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())
Related
I am experimenting with smtplib in Python3.
I want to send the content of a variable to an email address. If there is an smtplib.SMTPAuthenticationError, I want to send that variable to an alternative email address. This works (see code below). But what if I want to add a third email address (if the first two fail for some reason)?
I don't think try and except allow me to add another block of the same code (with different email login details).
I know with subprocess, it's possible to acquire the returncode of a variable and then use if.
For example:
result = subprocess.run(["ls", "-al"], capture_output = True)
if result !=0:
do_something_to_list_the_directory
I don't know how this can be done without using subprocess. Can anyone please advise?
Code below:
try:
mail_sending_attempt = smtplib.SMTP("smtp_provider", 587)
mail_sending_attempt.starttls()
mail_sending_attempt.login(send, passinfo) ### this will not work
mail_sending_attempt.sendmail(send, receive, message)
mail_sending_attempt.quit()
except Exception:
mail_sending_attempt = smtplib.SMTP("smtp_provider", 587)
mail_sending_attempt.starttls()
mail_sending_attempt.login(send2, passinfo2) ### this will not work
mail_sending_attempt.sendmail(send2, receive2, message)
mail_sending_attempt.quit()
In case there are more email, you can use following snippet
from dataclasses import dataclass
#dataclass
class EmailData:
send: str
passinfo: str
receive: str
main = EmailData("send1", "passinfo1", "receive1")
backup_1 = EmailData("send2", "passinfo2", "receive2")
...
for data in [main, backup_1, ...]:
try:
mail_sending_attempt = smtplib.SMTP("smtp_provider", 587)
mail_sending_attempt.starttls()
mail_sending_attempt.login(data.send, data.passinfo)
mail_sending_attempt.sendmail(data.send, data.receive, message)
mail_sending_attempt.quit()
break
except Exception:
continue
else:
# the case when we won't encounter break, so every login failed.
raise Exception
I have a list of emails(mine) that I want to test against a list of passwords(All valid and some none valid of course) using imaplib library. Whenever I test the program ordinarily like in the code below, it works perfectly no errors.
import sys
import imaplib
# connect to host using SSL
imap_host = 'imap.server.com'
imap_port = '993'
imap_user = 'username#email'
imap_pass = 'RightPassword'
imap = imaplib.IMAP4_SSL(imap_host, imap_port)
## login to server
try:
login = imap.login(imap_user, imap_pass)
if login:
print login
except imaplib.IMAP4.error as error:
print error
#
But whenever I run the code such as to parsing credentials through a function to handle the authentication protocols such as the following code below, I get an error saying
"LOGIN command error: BAD ['Missing \'"\'']".
I have tried all sort of things I could find using google and non seem to handle it properly.
"""
E-mail Tester
NB: This is for educational purpose only.
"""
import sys
import imaplib
EMAILS_FILE = open('email_list.txt', 'r')
PASSWORD_FILE = open('pass_list.txt', 'r')
SUCCESS_FILE = open('success.txt', 'a')
EMAILS_FILE_LIST = []
def set_check(_emails):
email = str(_emails)
PASSWORD_FILE.seek(0)
for passwords in PASSWORD_FILE:
password = str(passwords)
# connect to host using SSL
imap_host = 'imap.server.com'
imap_port = '993'
imap = imaplib.IMAP4_SSL(imap_host, imap_port)
## login to server
try:
# print "%s%s" % (email,password)
# print "I got here so far"
# sys.exit()
print "Testing <--> E-mail: %s - Password: %s" % (email, password)
login = imap.login("%s","%s" % (email, password))
if login:
print login
print "OK <---> E-mail: %s\nPassword: %s" % (email, password)
except imaplib.IMAP4.error as error:
print error
for emails in EMAILS_FILE:
EMAILS_FILE_LIST.append(emails)
for email_count in range(0, len(EMAILS_FILE_LIST)):
set_check(EMAILS_FILE_LIST[email_count])
I have tried all kind of suggestions I could find on the internet but non has worked thus far.
I expect imap.login to handle the authentication without the mysterious error output
"LOGIN command error: BAD ['Missing \'"\'']"
login = imap.login("%s","%s" % (email, password))
does not work. It throws an error in Python: TypeError: not all arguments converted during string formatting, because you're providing two strings to one %s.
Why don't you just use imap.login(email, password)? It has the same effect as what you're trying to do.
And what does your password file look like? What is it actually sending? Please provide the log line before it crashes. (anonymizing if necessary, but leaving any punctuation in for help diagnosing)
Okay, so I actually got this fixed by removing trail lines from my strings.
email = str(_emails).rstrip()
PASSWORD_FILE.seek(0)
for passwords in PASSWORD_FILE:
password = str(passwords).rstrip()
the error is caused by trail lines in the strings.
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'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.
I'd like to be able to retrieve a users Google Talk Status Message with Python, it's really hard to find documentation on how to use some of the libraries out there.
I don't have anything to hand with xmpp installed, but here's some old code I had lying around that might help you. You'll want to update the USERNAME/PASSWORD to your own values for test purposes.
Things to note: users logged in to Google Talk get a random presence string on their userid: that doesn't matter if you are trying to get the status of some other user, but if you want to write some code so want to communicate with yourself you need to distinguish the user logged in from GMail or a GTalk client from the test program. Hence the code searches through the userids.
Also, if you read the status immediately after logging in you probably won't get anything. There's a delay in the code because it takes a little while for the status to become available.
"""Send a single GTalk message to myself"""
import xmpp
import time
_SERVER = 'talk.google.com', 5223
USERNAME = 'someuser#gmail.com'
PASSWORD = 'whatever'
def sendMessage(tojid, text, username=USERNAME, password=PASSWORD):
jid = xmpp.protocol.JID(username)
client = xmpp.Client(jid.getDomain(), debug=[])
#self.client.RegisterHandler('message', self.message_cb)
if not client:
print 'Connection failed!'
return
con = client.connect(server=_SERVER)
print 'connected with', con
auth = client.auth(jid.getNode(), password, 'botty')
if not auth:
print 'Authentication failed!'
return
client.RegisterHandler('message', message_cb)
roster = client.getRoster()
client.sendInitPresence()
if '/' in tojid:
tail = tojid.split('/')[-1]
t = time.time() + 1
while time.time() < t:
client.Process(1)
time.sleep(0.1)
if [ res for res in roster.getResources(tojid) if res.startswith(tail) ]:
break
for res in roster.getResources(tojid):
if res.startswith(tail):
tojid = tojid.split('/', 1)[0] + '/' + res
print "sending to", tojid
id = client.send(xmpp.protocol.Message(tojid, text))
t = time.time() + 1
while time.time() < t:
client.Process(1)
time.sleep(0.1)
print "status", roster.getStatus(tojid)
print "show", roster.getShow(tojid)
print "resources", roster.getResources(tojid)
client.disconnect()
def message_cb(session, message):
print ">", message
sendMessage(USERNAME + '/Talk', "This is an automatically generated gtalk message: did you get it?")