I'm trying to send a text message over Tkinter. So you input sms:hello. That sends a text message that says hello. To do this it emails the word using the AT&T email server and GMail. So the program reads INFO.txt which contains all the email authentications g_user g_pass and m_num. Then it uses those to send an email which sends the text message.
Now my problem is that UnboundLocalError: local variable 'g_user' referenced before assignment. Which I know is caused by something not being a global variable. Can anyone help me out? I'm stumped...
root = Tk()
#open file
file=open('INFO.txt')
line=file.readline()
if 'Mobile_number:::' in line:
m_num=line[16:]
if 'GMail_name:::' in line:
g_user=line[13:]
if 'GMail_pass:::' in line:
g_pass=line[13:]
def callback(event):
text = inputfield.get()
if 'sms:' in text:
textmessage()
def textmessage():#sms:
import smtplib
#open file
file=open('INFO.txt')
line=file.readline()
if 'Mobile_number:::' in line:
m_num=line[16:]
if 'GMail_name:::' in line:
g_user=line[13:]
if 'GMail_pass:::' in line:
g_pass=line[13:]
SMTP_SERVER = 'smtp.gmail.com'
SMTP_PORT = 587
sender = '{}#gmail.com'.format(g_user)
password='{}'.format(g_pass)
recipient = '{}#txt.att.net'.format(m_num)
subject = 'Gmail SMTP Test'
body = text[4:]
"Sends an e-mail to the specified recipient."
body = "" + body + ""
headers = ["From: " + sender,
"Subject: " + subject,
"To: " + recipient,
"MIME-Version: 1.0",
"Content-Type: text/html"]
headers = "\r\n".join(headers)
session = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
session.ehlo()
session.starttls()
session.ehlo
session.login(sender, password)
session.sendmail(sender, recipient, headers + "\r\n\r\n" + body)
session.quit()
text2=text[4:]
confirmation="SMS containing '{}' sent".format(text2)
tex.insert(END,confirmation)
tex=Text(root)
tex.pack(side='right')
inputfield = Entry(root)
inputfield.pack(side='bottom')
inputfield.bind('<Return>', callback)
root.mainloop()
The problem is most likely with this line:
sender = '{}#gmail.com'.format(g_user)
because the if statement condition (if 'GMail_name:::' in line) is evaluating to False and then your g_user variable is never defined in the local scope of that function.
Take a close look at the error message:
UnboundLocalError: local variable 'g_user' referenced before assignment
A pretty good rule of thumb is to assume that the error message is telling the truth. In this case it is telling you two very important details:
It thinks g_user is a local variable
It thinks g_user was used before it was set
To solve this, you need to answer why to one or both of those questions. Why does it think it is local, and/or why does it think it wasn't set? If you mentally step through the code, you'll probably answer one or both of those questions.
For example, ask youself the question "how does g_user" get set if 'GMail_name:::' in line returns false? Have you verified that the if statement is true? Is your code prepared to handle the case where it's false? Have you literally proven to yourself that the if statement is true, or are you just assuming it's true?
Also, answer this question: are you reading every line from INFO.txt, or are you reading a single line? If you're only reading a single line, is that intentional? It looks like you are expecting both the username and password to be at position [13:] in the line, which will be impossible if both values are different and both values are on the same line.
Since you are just now learning to program, don't just throw lines of code into a file and hope they work, and don't get others to solve your problems. think about what the computer is doing. Step through the code logically and the problems will become self-evident.
Related
def mail():
server = smtplib.SMTP('smtp-mail.outlook.com',587)
server.starttls()
server.login(env, password)
server.sendmail(env,rec,msg =str(list))
print("Login no servidor efetuado com Sucesso")
print("Email enviado para " + rec)
server.close()
I use this code to send an email but the email comes empty i tryed to swap msg = str(list) to just list tried remove message and type in the third argument just a string and emails always come empty
server.sendmail(env,rec,msg =str(list))
You see what your message contains?
str(list)
Try typing this same thing in a scope in which list is not overwritten (because list is not reassigned in your mail function).
>>> str(list)
"<class 'list'>"
For sure that's not the right way of doing this.
What's more, in the same line of code above I don't see the assignation of env and rec, so I guess there must be some error there.
I have a script that emails me links to me.
The problem is the links arent included, instead I get:
<function <lambda> at 0x7f75b5fb4a60>
My script looks like:
from bs4 import BeautifulSoup
import re
import requests
ex_webdev_js_by_city = [
'http://boston.website.org/search/web',
]
ex_web_j_keywords = [['one'],['coool', 'person']]
ex_web_j_keywords = sum(ex_web_j_keywords, [])
ex_js = []
for webdev_j_for_a_city in ex_webdev_js_by_city:
webdev_j = requests.get(webdev_j_for_a_city)
soup = BeautifulSoup(webdev_j.text, "lxml")
for j_keyword in ex_web_j_keywords:
for a in soup.find_all('a', class_="result-title hdrlnk", text=re.compile(j_keyword,re.IGNORECASE)):
#print(a.get('href'))
ex_js.append(a.get('href'))
if ex_js:
#email them to myself!
import smtplib, socket
TO = 'myemail#gmail.com'
try:
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
TEXT = lambda: print(('Latest js from site:\n\n{}'*len(ex_js)).format(*ex_js))
#Gmail Sign In
gmail_sender = 'myemail'
gmail_passwd = 'mypass'
server.login(gmail_sender, gmail_passwd)
msg = str(TEXT)
server.sendmail(gmail_sender, gmail_sender, msg)
print('Sent you some links!')
server.quit()
except socket.error as e:
print ('error sending mail, error was {}'.format(e))
The error is occuring on this line (I believe):
lambda: print(('Latest js from site:\n\n{}'*len(ex_js)).format(*ex_js))
It appears its printing out the object details in the email to me, and not the value.
Thus, what am i possibly doing wrong here?
I don't know why you use print or lambda anyway. If you simply wrote:
msg = ('Latest js from site:\n\n{}'*len(ex_js)).format(*ex_js)
and drop the:
msg = str(TEXT)
it should probably work.
So the try block should read:
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
msg = ('Latest js from site:\n\n{}'*len(ex_js)).format(*ex_js)
#Gmail Sign In
gmail_sender = 'myemail'
gmail_passwd = 'mypass'
server.login(gmail_sender, gmail_passwd)
# msg = str(TEXT) !!commented out!! (only to make it explicit)
server.sendmail(gmail_sender, gmail_sender, msg)
print('Sent you some links!')
server.quit()
I think however that you do not really understand what lambda and print are supposed to do. print is used to write data to the standard output channel, but you want to write it into an email, so you do not need to print it locally, you need somehow to store your message in memory.
Finally lambda:... is used to create an anonymous function, if you do not feed it any arguments, its usage is usually to postpone execution (for instance to achieve laziness). But here you actually need the message, so again no need to use this construct.
When you say
TEXT = lambda: print(('Latest js from site:\n\n{}'*len(ex_js)).format(*ex_js))
Yo are simply creating lambda function , it is not executed yet . In order to execute you need to specifically invoke it by calling TEXT()
In order to fix your problem change to
TEXT = lambda: ('Latest js from site:\n\n{}'*len(ex_js)).format(*ex_js)
And msg = str(TEXT())
I am doing text processing using Python in which I am looking for a specific text in a console log and printing every matched line. This is accomplished by a function called:
get_matched_log_lines(url, search_pattern, print_pattern) where url = from which I get my log, search_pattern = my target search pattern, print_pattern = the way I want to print my output(its, %s.%s)
How do I send this entire output of function get_matched_log_lines() via email? Emailing function code is already written by me in Python.
Here is what I think/attempted so far:
email_content = get_matched_log_lines(url, search_pattern, print_pattern)
TO = 'recipient email address'
FROM ='sender email address'
#emailing function - py_mail
py_mail("Test email subject", email_content, TO, FROM)
This provides me an empty email.
Here is my answer based on the suggestions by PyNEwbie:
def get_matched_log_lines(url, search_pattern, print_pattern):
out = open("output_file.txt", "w")
for something in somthings:
test = print_pattern % matched_line
print >>out, test
out.close()
^^ just a general example (syntax maybe incorrect). The idea is to open the file in write mode and then dumping the output in it.
fp = open("output_file.txt", 'r')
# Create a text/plain message
msg = fp.read()
fp.close()
email_content = msg
Then open the same file in read mode and store its output to some var (in my case email_content)
Finally send an email with that email_content,
email_content = get_matched_log_lines(url, search_pattern, print_pattern)
TO = 'recipient email address'
FROM ='sender email address'
#emailing function - py_mail
py_mail("Test email subject", email_content, TO, FROM)
I am trying to write a python script to send an email that uses html formatting and involves a lot of non-breaking spaces. However, when I run it, some of the   strings are interrupted by spaces that occur every 171 characters, as can be seen by this example:
#!/usr/bin/env python
import smtplib
import socket
from email.mime.text import MIMEText
emails = ["my#email.com"]
sender = "test#{0}".format(socket.gethostname())
message = "<html><head></head><body>"
for i in range(20):
message += " " * 50
message += "<br/>"
message += "</body>"
message = MIMEText(message, "html")
message["Subject"] = "Test"
message["From"] = sender
message["To"] = ", ".join(emails)
mailer = smtplib.SMTP("localhost")
mailer.sendmail(sender, emails, message.as_string())
mailer.quit()
The example should produce a blank email that consists of only spaces, but it ends up looking something like this:
  ;
&nb sp;
& nbsp;
&nbs p;
&n bsp;
Edit: In case it is important, I am running Ubuntu 15.04 with Postfix for the smtp client, and using python2.6.
I can replicate this in a way but my line breaks come every 999 characters. RFC 821 says maximum length of a line is 1000 characters including the line break so that's probably why.
This post gives a different way to send a html email in python, and i believe the mime type "multipart/alternative" is the correct way.
Sending HTML email using Python
I'm the developer of yagmail, a package that tries to make it easy to send emails.
You can use the following code:
import yagmail
yag = yagmail.SMTP('me#gmail.com', 'mypassword')
for i in range(20):
message += " " * 50
message += "<br/>"
yag.send(contents = message)
Note that by default it will send a HTML message, and that it also adds automatically the alternative part for non HTML browsers.
Also, note that omitting the subject will leave an empty subject, and without a to argument it will send it to self.
Furthermore, note that if you set yagmail up correctly, you can just login using yag.SMTP(), without having to have username & password in the script (while still being secure). Omitting the password will prompt a getpass.
Adding an attachment is as simple as pointing to a local file, e.g.:
yag.send(contents = [message, 'previously a lot of whitespace', '/local/path/file.zip']
Awesome isn't it? Thanks for the allowing me to show a nice use case for yagmail :)
If you have any feature requests, issues or ideas please let me know at github.
I can't figure out the problem and want some input as to whether my Python code is incorrect, or if this is an issue or design limitation of Python XMPP library. I'm new to Python by the way.
Here's snippets of code in question below. What I'd like to do is read in a text file of IM recipients, one recipient per line, in XMPP/Jabber ID format. This is read into a Python list variable.
I then instantiate an XMPP client session and loop through the list of recipients and send a message to each recipient. Then sleep some time and repeat test. This is for load testing the IM client of recipients as well as IM server. There is code to alternately handle case of taking only one recipient from command line input instead of from file.
What ends up happening is that Python does iterate/loop through the list but only last recipient in list receives message. Switch order of recipients to verify. Kind of looks like Python XMPP library is not sending it out right, or I'm missing a step with the library calls, because the debug print statements during runtime indicate the looping works correctly.
recipient = ""
delay = 60
useFile = False
recList = []
...
elif (sys.argv[i] == '-t'):
recipient = sys.argv[i+1]
useFile = False
elif (sys.argv[i] == '-tf'):
fil = open(sys.argv[i+1], 'r')
recList = fil.readlines()
fil.close()
useFile = True
...
# disable debug msgs
cnx = xmpp.Client(svr,debug=[])
cnx.connect(server=(svr,5223))
cnx.auth(user,pwd,'imbot')
cnx.sendInitPresence()
while (True):
if useFile:
for listUser in recList:
cnx.send(xmpp.Message(listUser,msg+str(msgCounter)))
print "sending to "+listUser+" msg = "+msg+str(msgCounter)
else:
cnx.send(xmpp.Message(recipient,msg+str(msgCounter)))
msgCounter += 1
time.sleep(delay)
Never mind, found the problem. One has to watch out for the newline characters at the end of a line for the elements in a list returned by file.readlines(), so I had to strip it out with .rstrip('\n') on the element when sending out message.