0

I need to send a lot of emails to many different recipients with many attachments. I'd like to be able to review the emails and add any additional attachments that may need to be added prior to sending. Currently this code will only open one window (email), requiring that one to be sent or closed before showing another. How can I get all of the emails open and visible at the same time?

def mailer(text, subject, recipient, attachments):
    import win32com.client as win32

    list(attachments)
    outlook = win32.Dispatch('outlook.application')
    mail = outlook.CreateItem(0)
    mail.To = recipient
    mail.Subject = subject
    mail.HtmlBody = text
    for each in attachments:
        mail.Attachments.Add(Source=each)
    mail.Display(True)

mailer("", " TEST 1", test_address, "")
mailer("", " TEST 2", test_address, "")
mailer("", " TEST 3", test_address, "")
mailer("", " TEST 4", test_address, "")

2 Answers 2

3

Call mail.display(false) - that will display the window modelessly.

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

1 Comment

Yup! Thanks, that does it perfectly.
0

In general, statements in python are run sequentially.

If you have a script like:

print "a"
print "b"
print "c"
print "d"

then your expected output would be:

$ play.py
a
b
c
d

This is what is happening as you run:

mailer("", " TEST 1", test_address, "")
mailer("", " TEST 2", test_address, "")
mailer("", " TEST 3", test_address, "")
mailer("", " TEST 4", test_address, "")

Python is running these statements in the order in which you give them. So mailer("", " TEST 2", test_address, "") will only be run once mailer("", " TEST 1", test_address, "") has completed and so on, in order, until the last statement has been run.

How can you fix this?

My first instinct would be to check out python's multiprocessing package: http://docs.python.org/library/multiprocessing.html

You could change your code to something like:

from multiprocessing import Process

def mailer(text, subject, recipient, attachments):
    import win32com.client as win32

    list(attachments)
    outlook = win32.Dispatch('outlook.application')
    mail = outlook.CreateItem(0)
    mail.To = recipient
    mail.Subject = subject
    mail.HtmlBody = text
    for each in attachments:
        mail.Attachments.Add(Source=each)
    mail.Display(True)

if __name__ == '__main__':
    Process(mailer("", " TEST 1", test_address, ""))
    Process(mailer("", " TEST 2", test_address, "")
    Process(mailer("", " TEST 3", test_address, "")
    Process(mailer("", " TEST 4", test_address, "")

Whether this or another package(like threading here: https://docs.python.org/2/library/threading.html) or even a third party library would be best really depends on the number of message you would like to have open at once and the CPU/RAM requirements of each.

1 Comment

Turns out it was that pesky "True." But thanks for the information, I'm now reading all about multiprocessing and threading.

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.