python-3.xoverwrite

Python won't overwrite files / directory if already exists


I'm using Python to download image attachments from gmail using the following script:

#!/usr/bin/env python3
# read emails and detach attachment in attachments directory
 
import email
import getpass, imaplib
import os
import sys
import time
 
detach_dir = '.'
if 'attachments' not in os.listdir(detach_dir):
    os.mkdir('/var/www/html/attachments')
 
userName = 'enter-your-gmail-account-name-here'
passwd = 'enter-your-password-here'
 
try:
    imapSession = imaplib.IMAP4_SSL('imap.gmail.com',993)
    typ, accountDetails = imapSession.login(userName, passwd)
    if typ != 'OK':
        print ('Not able to sign in!')
        raise Exception
 
    imapSession.select('Inbox')
    typ, data = imapSession.search(None, 'SUBJECT', '"DASHBOARD"')
    if typ != 'OK':
        print ('Error searching Inbox.')
        raise Exception
 
    # Iterating over all emails
    for msgId in data[0].split():
        typ, messageParts = imapSession.fetch(msgId, '(RFC822)')
 
        if typ != 'OK':
            print ('Error fetching mail.')
            raise Exception
 
        emailBody = messageParts[0][1] 
        mail = email.message_from_bytes(emailBody) 
 
        for part in mail.walk():
 
            if part.get_content_maintype() == 'multipart':
 
                continue
            if part.get('Content-Disposition') is None:
 
                continue
 
            fileName = part.get_filename()
 
            if bool(fileName): 
                filePath = os.path.join(detach_dir, '/var/www/html/attachments', fileName)
                if not os.path.isfile(filePath) : 
                    print (fileName)
                    print (filePath)
                    fp = open(filePath, 'wb')
                    fp.write(part.get_payload(decode=True))
                    fp.close()
 
    #MOVING EMAILS TO PROCESSED PART BEGINS HERE
    imapSession.select(mailbox='inbox', readonly=False)
    resp, items = imapSession.search(None, 'All')
    email_ids = items[0].split()
    for email in email_ids:
        latest_email_id = email
 
        #move to processed
        result = imapSession.store(latest_email_id, '+X-GM-LABELS', 'Processed')
 
        if result[0] == 'OK':
            #delete from inbox
            imapSession.store(latest_email_id, '+FLAGS', '\\Deleted')
 
    #END OF MOVING EMAILS TO PROCESSED
 
    imapSession.close()
    imapSession.logout()
 
except :
    print ('No attachments were downloaded')

I'm getting the following error:

Traceback (most recent call last):
  File "/home/jenns/get_images_from_emails.py", line 12, in <module>
    os.mkdir('/var/www/html/attachments')
FileExistsError: [Errno 17] File exists: '/var/www/html/attachments'

I've noticed that python3 is not in #!/usr/bin/env python3 and changed it to #!/usr/bin python3 which didn't produce different results.

I know the gmail side is working because the attachment is moving to the Processed Folder and the email is deleted from my inbox.

I've also used sudo chmod 775 '/var/www/html/attachments' and that didn't resolve the problem. Any ideas as to why the files aren't downloading using the script, get_images_from_emails.py ?


Solution

  • The error message tells you, that the folder you're trying to create already exists, not a file. A file would be overwritten.

    This likely happens due to not providing the full path for your "detach_dir" when checking for its existence, but then providing a full path for creating it.

    Something like this should work:

    attach_dir =  '/var/www/html/attachments'
    if not os.path.exists(attach_dir):
        os.makedirs(attach_dir)
    

    Edit:

    And I'm not sure about your directory structure, but this looks like it could be an error ...

    filePath = os.path.join(detach_dir, '/var/www/html/attachments', fileName)
    

    ... as the above suggests that your "detach_dir" would be /var/www/html, thus the filepath would be: /var/www/html/var/www/html/attachments/filename (a directory that likely doesn't exist)