I am trying to write a script that will look for a file and the script is running fine but is running as if it could never be found? However I know this file is there. It will run and also send multiple emails when I just want it to send one email instead of multiple. (I've removed my email and password for obvious reasons but the blank strings are my Email address/Password and I am aware of this.
This is my code:
for path, dirs, files in os.walk(bureau):
for filename in files:
filename_no_ext, ext = os.path.splitext(filename)
if ext.lower() == '.xls':
num = filename.rsplit(" ")
jnum = num[0]
if num[0] in jobnums:
master = ' '.join([jnum, "Master Box File List.xls"])
for jobfolder in os.listdir(bureau):
if jobfolder.startswith(jnum):
if os.path.exists(master):
print master
else:
fromaddr = ""
toaddr = ""
max_attempts = 5
login_success = False
for i in range(max_attempts):
try:
msg = MIMEMultipart()
msg['From'] = fromaddr
msg['To'] = toaddr
msg['Subject'] = "Scripting Email"
body = "This email is an automatic email part of a Python training excersise"
msg.attach(MIMEText(body, 'plain'))
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(fromaddr, "")
text = msg.as_string()
print "Signed In To Mailbox."
login_success = True
break
except:
print "Can't Sign In To Mailbox. Trying Again...."
time.sleep(0.5)
continue
if login_success:
server.sendmail(fromaddr, toaddr, text)
server.quit()
print "Email Sent."
else:
print "Can't Sign In To Mailbox."
Im not expecting this to be a huge error just something small that I can't see, cheers guys.
I'm going to take a wild guess that you don't actually mean to do
for jobfolder in os.listdir(bureau):
It looks like bureau is your top level directory. It never changes in the code. So for every file in your walk, you are running this for loop on the top level directory. What are you actually trying to loop over? If you're just checking for each file in the tree, you don't need another nested loop here, os.walk will already descend the full tree.
Related
I am pretty new to coding and i don't know much, i wanted to make a script that sends 1 email to a person with 1 attachment taken from my directory. Let's say i have 100 files, and i want to send 1 file per email, then after email has been sent, then that file i sent is being deleted so that script doesn't send same attachment twice, lastly whole code is put on random delay between 10 and 20 seconds only to repeat whole process. Problem is that script is put on sleep and then is being executed, and sends lots of emails to one person without attachment, also files aren't being deleted. Please help.
import smtplib, time, random, glob, os
while True:
time.sleep(random.randint(10,20))
#checking files
os.chdir("path")
for file in glob.glob('*.txt'):
#sending
gmail_user = 'my#gmail.com'
gmail_password = 'password'
sent_from = gmail_user
to = "someones#gmail.com"
subject = 'X'
body = 'Y'
email_text = """\
From: %s
To: %s
Subject: %s
%s
""" % (sent_from, ", ".join(to), subject, body)
try:
server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
server.ehlo()
server.login(gmail_user, gmail_password)
server.sendmail(sent_from, to, email_text)
server.close()
print ("Sent")
except:
print ("Error")
else:
print('No files with extensions .txt')
#removing
os.remove(os.path.join("path", file))
Your while loop is unnecessary. You can remove it.
Then, move time.sleep(random.randint(10,20)) to the for-loop where the emails are actually sent.
Also your variables (like gmail_user, gmail_password) don't change, so you can declare them outside of the for-loop.
So the corrected code looks like:
# first declare constants
gmail_user = "whatever"
for file in glob.glob('*.txt'):
time.sleep(random.randint(10,20))
try:
# sending the mail
import smtplib
import os
import time
def send_email(contacts):
try:
user= passw=""
with open("credentials.txt", "r") as f:
file = f.readlines()
user = file[0].strip()
passw = file[1].strip()
server = smtplib.SMTP('smtp.gmail.com:587')
server.ehlo()
server.starttls() # it is necessary to start this before login
server.login(user, passw) # login credentials
subject = "Assignment Task for Working student job"
msg = "This is a msg body of assignment. "
message = 'Subject: {}\n\n{}'.format(subject, msg)
for i in contacts:
server.sendmail(user, contacts, message)
print(f"successfully sent email to {i} and wait for 10 seconds" )
time.sleep(10)
server.quit()
print("Success: Email sent!")
except:
print("Email failed to send.")
if __name__ == "__main__":
#sender, password = read_creds()
contacts = ['editorawais#gmail.com', 'editorawais#yahoo.com', 'editorawais#live.com','techwpblog#gmail.com']
send_email(contacts)
I created this email script. But now i am getting error on login. My credentials.txt is just of two lines.
"Email address"
"Password"
Please can anybody help me where i am missing something. And the correct way possibly. Thanks
Lose the quotation marks if you indeed have those in the txt file. Python will try to plug in everything on the first and second line including the "" try just doing this in your .txt file.
email
password
I am trying to send a 2 step verification code for an assignment and everything works but when i recieve the email there is no number. For Loop creates random 6 digit code. It says: Please confirm your login by entering this 2-step verification code. None'
I have looked on stack over flow for solutions and google etc
def TwoStep():
for x in range(1):
RandomNumber = print(random.randint(100000,1000000))
time.sleep(5)
email_send = 'recieving email'
email_user = 'myemail'
email_password = 'password'
subject = '2-Step Verification'
msg = MIMEMultipart()
msg['From'] = email_user
msg['To'] = email_send
msg['Subject'] = subject
body = ('Please confirm your login by entering this 2-step verification code. ' + str(RandomNumber))
msg.attach(MIMEText(body,'plain'))
text = msg.as_string()
server = smtplib.SMTP('smtp.gmail.com',587)
server.starttls()
server.login(email_user,email_password)
server.sendmail(email_user,email_send,text)
server.quit()
TwoStep()
Be able to send the 6 digit code through email.
A few things to comment:
1) print(random.randint(100000,1000000)) prints the number in the console but doesn't returns anything, that's why you are getting a None value.
2) DON'T use capital case variables, by convention these names are reserved for naming Classes and it's confusing to see this names as a variable. Note that even the SO highlighting marks it in another color. Use some camel-case or snake-case naming such as randomNumber or random_number (these one more common in Python).
3) Is the for loop even necessary? I think you only need to generate a random number, so you can remove the loop around it, and just assign it once.
your code is not returning a random number instead printing it and why is loop added ?
for x in range(1):
RandomNumber = print(random.randint(100000,1000000))
I'm trying to send email to multiple people using Python.
def getRecipients(fileWithRecipients):
recipients = []
f = open(fileWithRecipients, 'r')
for line in f:
recipients.append(line)
return recipients
def test_email():
gmail_user = "csarankings#gmail.com"
gmail_pass = getPassword("pass.txt")
FROM = "csarankings#gmail.com"
TO = getRecipients("recipients.txt")
date = getCurrentDate()
SUBJECT = "Current CSA Rankings: " + date
TEXT = createEmailMessageFromFile("rankings.txt")
message = """\From: %s\nTo: %s\nSubject: %s\n\n%s """ % (FROM, ", ".join(TO), SUBJECT, TEXT)
try:
server = smtplib.SMTP("smtp.gmail.com", 587)
server.ehlo()
server.starttls()
server.login(gmail_user, gmail_pass)
server.sendmail(FROM, TO, message)
server.close()
print("it worked")
except:
print("it failed :(")
For whatever reason, my emails only go to the first recipient in my list of recipients (the TO variable within my test_email() function.
My recipients file just consists of an email address per line (only has two in there at the moment). I thought there might be something wrong with my getRecipients() function, so I just hardcoded two emails into the TO variable and it works for the first email address and not the second.
Any idea why this might be happening? I suspect it has something to do with:
", ".join(TO)
where I set my message variable.
NB: My test_email() is largely based on the most upvoted answer here:
How to send an email with Gmail as provider using Python?
EDIT: For what it's worth, when I hardcode a list of a single email address into the TO variable, the subject displays properly in the email. When I use the getRecipients() function (even with only one email address in the recipients.txt file), it displays this in the body of the email:
Subject: Current CSA Rankings 6/13/15
Not sure if relevant but thought it might be related to the issue.
EDIT_2: I don't think my question is a duplicate of:
How to send email to multiple recipients using python smtplib?
because, while I use the smtplib.sendmail() function, I don't use the email module at all, so our code is very different...
I was able to do this by iterating over the list of recipients after logging on to the server.
Something like this
try:
server = smtplib.SMTP("smtp.gmail.com", 587)
server.ehlo()
server.starttls()
server.login(gmail_user, gmail_pass)
print('Login successful')
except:
print('Login unsuccessful')
And then iterating over list
for item in List:
TO = item
FROM = gmail_user
#message as defined above
try:
server.sendmail(FROM, TO, message)
except:
print('not sent for' + item)
server.close()
I am trying to use a Python script I found on Github to send email with attachments. I have a list of 5 attachments and want to send one email per attachment. When I run the script it sends the first email with one attachment and the next email with 2 attachments and so on. The 5th email has all 5 attachments instead of the 5th attachment in the list. I believe that I need to iterate through the list of attachments but cannot figure out where to do so. Any help would be greatly appreciated. Script is below.
attachments = ['file1.zip', 'file2.zip', 'file3.zip', 'file4.zip', 'file5.zip']
host = 'mailer' # specify port, if required, using this notations
fromaddr = 'test#localhost' # must be a vaild 'from' address in your GApps account
toaddr = 'target#remotehost'
replyto = fromaddr # unless you want a different reply-to
msgsubject = 'Test ZIP'
htmlmsgtext = """<h2>TEST</h2>"""
######### In normal use nothing changes below this line ###############
import smtplib, os, sys
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email import Encoders
from HTMLParser import HTMLParser
# A snippet - class to strip HTML tags for the text version of the email
class MLStripper(HTMLParser):
def __init__(self):
self.reset()
self.fed = []
def handle_data(self, d):
self.fed.append(d)
def get_data(self):
return ''.join(self.fed)
def strip_tags(html):
s = MLStripper()
s.feed(html)
return s.get_data()
########################################################################
try:
# Make text version from HTML - First convert tags that produce a line break to carriage returns
msgtext = htmlmsgtext.replace('</br>',"\r").replace('<br />',"\r").replace('</p>',"\r")
# Then strip all the other tags out
msgtext = strip_tags(msgtext)
# necessary mimey stuff
msg = MIMEMultipart()
msg.preamble = 'This is a multi-part message in MIME format.\n'
msg.epilogue = ''
body = MIMEMultipart('alternative')
body.attach(MIMEText(msgtext))
body.attach(MIMEText(htmlmsgtext, 'html'))
msg.attach(body)
if 'attachments' in globals() and len('attachments') > 0:
for filename in attachments:
f=filename
part = MIMEBase('application', "octet-stream")
part.set_payload( open(f,"rb").read() )
Encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename="%s"' % f)
msg.attach(part)
msg.add_header('From', fromaddr)
msg.add_header('To', toaddr)
msg.add_header('Subject', msgsubject)
msg.add_header('Reply-To', replyto)
server = smtplib.SMTP(host)
server.set_debuglevel(False) # set to True for verbose output
server.sendmail(msg['From'], [msg['To']], msg.as_string())
print 'Email sent with filename: "%s"' % f
server.quit()
except:
print ('Email NOT sent to %s successfully. %s ERR: %s %s %s ', str(toaddr), str(sys.exc_info()[0]), str(sys.exc_info()[1]), str (sys.exc_info()[2]) )
Each time through the loop, you add an attachment to the existing message, then send the message. So, you're going to keep accumulating a bigger and bigger message and sending each intermediate step.
It's not clear what you actually want to do, but obviously not this…
If you want to send one message with all five attachments, just move the sending code (everything from server = smtplib.SMTP(host) to server.quit() outside the loop by unindenting it.
If you want to send five messages, each with one attachment, most the message-creating code (everything from msg = MIMEMultipart() to msg.attach(body)) into the loop by indenting it and moving it down a couple lines.
If you want something else, the answer will almost surely be similarly trivial, but nobody can tell you how to do it until you explain what it is you want.