0

I am trying to send a bunch of photos to my email address using the email module. But when I run my program nothing is happening. I am not able to figure out what's wrong in my program. How can I solve this problem?

Python code:

import os
import smtplib
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart

fromadd = '[email protected]'
toadd = '[email protected]'

def send():
    msg = MIMEMultipart()

    msg['From'] = fromadd
    msg['To'] = toadd
    msg['Subject'] = 'Photos'

    text = MIMEText('Pics')
    msg.attach(text)

    screenshot_data = open(files, 'rb').read()
    webcam_data = open(files, 'rb').read()

    send_image = MIMEImage(screenshot_data, name=os.path.basename(files))
    send_images = MIMEImage(webcam_data, name=os.path.basename(files))

    msg.attach(send_image)
    msg.attach(send_images)

    sessions = smtplib.SMTP('smtp.gmail.com', '587')
    sessions.ehlo()
    sessions.starttls()
    sessions.ehlo()
    sessions.login(fromadd, 'Password')
    sessions.sendmail(fromadd, toadd, msg.as_string())
    sessions.quit()


def main():

    global files

    for files in os.listdir(r'C:\NONE'):

        if os.path.isfile(files) and files.endswith(".jpg"):
            send()
            print('File Sent: ' + files) 
            os.remove(files)

    else:
        pass

 if __name__ == '__main__':
     main()
5
  • As a side note: Why have you made files a global instead of just passing it as an argument to send? Also, why is a variable representing a single filename called files instead of, say, file or filename? Commented Jul 17, 2018 at 3:46
  • This is not the way you pass parameters to functions. Remove global files and pass the files variable (consider renaming this to a singular noun by the way) to your send() function. Commented Jul 17, 2018 at 3:47
  • Anyway, are you sure you actually have files that end in .jpg directly in the C:\NONE directory? Because if so, the print should be printing something out. If nothing is printing out, either you don't have any files there, or there's a problem with the logic in main; since send is never being called, the bug you're asking about can't be in send. (You may, of course, have bugs there as well, but if you can't even get that far, they don't matter yet.) Commented Jul 17, 2018 at 3:48
  • I thought files will only be accessible in main function so I declared global variable for files. I just called ** files** variable to make easy in my program Commented Jul 17, 2018 at 3:53
  • Yeah I have files which ends with .jpg in C:\NONE directory. I have called send in main function. Still I am not able to send mail. -- abarnert Commented Jul 17, 2018 at 3:58

1 Answer 1

1

os.listdir() returns just the file names, not the full paths. So unless you run this program in c:\NONE or just happen to have a file with the same name in your current working directory, os.path.isfile(files) will return False, and so send() will never be called.

Even though it's not specific to Python - so many of the concrete tips in it do not apply - you might want to give Eric Lippert's How To Debug Small Programs a read. Also remember Brian Kernighan's advice:

The most effective debugging tool is still careful thought, coupled with judiciously placed print statements.

-- "Unix for Beginners" (1979)

The immediate fix is to os.path.join() the directory name back in front; but you also really need to get rid of the global variable.

import os
import smtplib
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart

fromadd = '[email protected]'
toadd = '[email protected]'

def send(pathname, froma, toa):
    msg = MIMEMultipart()

    msg['From'] = froma
    msg['To'] = toa
    msg['Subject'] = 'Photos'

    text = MIMEText('Pics')
    msg.attach(text)

    # Should really close() when done!
    screenshot_data = open(pathname, 'rb').read()
    webcam_data = open(pathname, 'rb').read()

    screenshot_image = MIMEImage(screenshot_data, name=os.path.basename(pathname))
    webcam_image = MIMEImage(webcam_data, name=os.path.basename(pathname))

    msg.attach(screenshot_image)
    msg.attach(webcam_image)

    session = smtplib.SMTP('smtp.gmail.com', '587')
    session.ehlo()
    session.starttls()
    session.ehlo()
    session.login(froma, 'Password')
    session.sendmail(froma, toa, msg.as_string())
    session.quit()

def main():
    for basename in os.listdir(r'C:\NONE'):
        filename = os.path.join([r'C:\NONE', basename])
        # switch order of conditions for minor efficiency hack
        if filename.endswith(".jpg") and os.path.isfile(filename):
            send(filename, fromadd, toadd)
            print('File Sent: ' + filename) 
            os.remove(filename)
        # empty else not required

 if __name__ == '__main__':
     main()

Notice also how I renamed several of the variables to avoid plurals on singular instances and hopefully better connect related variables by using a common prefix.

It's still not clear why you send two copies of each image, or why you create a text part when you don't have anything useful to put in it. You might also want to avoid the legacy sendmail method in accordance with the recommendation in its documentation. And why do you create a separate message for each photo? Attaching all the photos to a single email message will surely be more practical (unless the pics are absolutely huge and the message becomes too big for your mail server; but surely then email is the wrong tool for this anyway).

More fundamentally, you should not be writing new code in Python 2 in 2018; and incidentally, some of this would be somewhat more straightforward with the overhauled email library in 3.6+ (though it's still low-level and quirky).

Sign up to request clarification or add additional context in comments.

2 Comments

what do you mean by then email is the wrong tool for this anyway? Is there another way of sending large number of images at once?
Upload them to a file sharing site and send links.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.