TheAxeR
January 18th, 2009, 05:35 AM
I have a script which I use with conky to tell me the unread count and the title of unread emails. I did not write the original script; but, I made a few changes and everything worked fine. I then decided I would give a try at changing it to work with python 3. I have run into an error which I do not understand.
Here is the code:
import sys
import urllib.request
from xml.dom.minidom import parse
gmail = 'https://mail.google.com/gmail/feed/atom'
uname = sys.argv[1]
password = sys.argv[2]
maxlen = sys.argv[3]
def get_feed():
'''The method to do HTTPBasicAuthentication'''
# Create an OpenerDirector with support for Basic HTTP Authentication...
auth_handler = urllib.request.HTTPBasicAuthHandler()
auth_handler.add_password(realm='New mail feed',
uri='https://mail.google.com/',
user= uname,
passwd= password)
opener = urllib.request.build_opener(auth_handler)
# ...and install it globally so it can be used with urlopen.
urllib.request.install_opener(opener)
response = urllib.request.urlopen(gmail)
feed = response.read()
return feed
def read_mail(feed, maxlen):
'''Parse the Atom feed and print a summary'''
atom = parse(feed)
num_email = atom.getElementsByTagName(fullcount)
# Output the total number of new emails.
if num_email > 1:
print ('${color1} {0} new emails\n').format(num_email)
elif num_email == 1:
print ('${color1} {0} new emails\n').format(num_email)
else:
print ('${color1} No new emails\n')
if __name__ == "__main__":
mailfeed = get_feed() # Do auth and then get the feed
read_mail(mailfeed, int(maxlen)) # Let the feed be chewed by feedparser
Here is the error:
Traceback (most recent call last):
File "conkyGmail2.py", line 96, in <module>
read_mail(mailfeed, int(maxlen)) # Let the feed be chewed by feedparser
File "conkyGmail2.py", line 64, in read_mail
atom = parse(feed)
File "/usr/lib/python3.0/xml/dom/minidom.py", line 1917, in parse
return expatbuilder.parse(file)
File "/usr/lib/python3.0/xml/dom/expatbuilder.py", line 928, in parse
result = builder.parseFile(file)
File "/usr/lib/python3.0/xml/dom/expatbuilder.py", line 204, in parseFile
buffer = file.read(16*1024)
AttributeError: 'bytes' object has no attribute 'read'
It seems that there is an issue when it tries to read the atom file which Google supplies.
I have based this on this code for python 2.5, which I know works:
import sys
import urllib # For BasicHTTPAuthentication
import feedparser # For parsing the feed
GMAIL = "https://mail.google.com/gmail/feed/atom"
uname = sys.argv[1]
password = sys.argv[2]
maxlen = sys.argv[3]
urllib.FancyURLopener.prompt_user_passwd = lambda self, host, realm: (uname, password)
def get_feed():
'''The method to do HTTPBasicAuthentication'''
opener = urllib.FancyURLopener()
f = opener.open(GMAIL)
feed = f.read()
return feed
def read_mail(feed, maxlen):
'''Parse the Atom feed and print a summary'''
atom = feedparser.parse(feed)
num_email = len(atom.entries)
# Output the total number of new emails.
if num_email > 1:
print '${color1} %s new emails\n' % (len(atom.entries))
elif num_email == 1:
print '${color1} %s new emails\n' % (len(atom.entries))
else:
print '${color1} No new emails\n'
for i in range(min(len(atom.entries), maxlen)):
mail = atom.entries[i]
title_len = len(mail.title)
# Test that the email has a subject line. If it does not have a subject
# line then use the author.
if title_len == 0:
title = mail.author
else:
title = mail.title
# Truncate if the email subject line is longer then 20 characters.
# This includes spaces. If it is longer add ellipse.
if len(title) < 21:
print ' ${color2}%s' % title
else:
print ' ${color2}%s...' % title[:20]
#uncomment the following line if you want to show the name of the sender
# print ' ${color2}%s' % atom.entries[i].author
if len(atom.entries) > maxlen:
print ' ${color}more...'
if __name__ == "__main__":
f = get_feed() # Do auth and then get the feed
read_mail(f, int(maxlen)) # Let the feed be chewed by feedparser
Any help would be appreciated. Thank you.
Here is the code:
import sys
import urllib.request
from xml.dom.minidom import parse
gmail = 'https://mail.google.com/gmail/feed/atom'
uname = sys.argv[1]
password = sys.argv[2]
maxlen = sys.argv[3]
def get_feed():
'''The method to do HTTPBasicAuthentication'''
# Create an OpenerDirector with support for Basic HTTP Authentication...
auth_handler = urllib.request.HTTPBasicAuthHandler()
auth_handler.add_password(realm='New mail feed',
uri='https://mail.google.com/',
user= uname,
passwd= password)
opener = urllib.request.build_opener(auth_handler)
# ...and install it globally so it can be used with urlopen.
urllib.request.install_opener(opener)
response = urllib.request.urlopen(gmail)
feed = response.read()
return feed
def read_mail(feed, maxlen):
'''Parse the Atom feed and print a summary'''
atom = parse(feed)
num_email = atom.getElementsByTagName(fullcount)
# Output the total number of new emails.
if num_email > 1:
print ('${color1} {0} new emails\n').format(num_email)
elif num_email == 1:
print ('${color1} {0} new emails\n').format(num_email)
else:
print ('${color1} No new emails\n')
if __name__ == "__main__":
mailfeed = get_feed() # Do auth and then get the feed
read_mail(mailfeed, int(maxlen)) # Let the feed be chewed by feedparser
Here is the error:
Traceback (most recent call last):
File "conkyGmail2.py", line 96, in <module>
read_mail(mailfeed, int(maxlen)) # Let the feed be chewed by feedparser
File "conkyGmail2.py", line 64, in read_mail
atom = parse(feed)
File "/usr/lib/python3.0/xml/dom/minidom.py", line 1917, in parse
return expatbuilder.parse(file)
File "/usr/lib/python3.0/xml/dom/expatbuilder.py", line 928, in parse
result = builder.parseFile(file)
File "/usr/lib/python3.0/xml/dom/expatbuilder.py", line 204, in parseFile
buffer = file.read(16*1024)
AttributeError: 'bytes' object has no attribute 'read'
It seems that there is an issue when it tries to read the atom file which Google supplies.
I have based this on this code for python 2.5, which I know works:
import sys
import urllib # For BasicHTTPAuthentication
import feedparser # For parsing the feed
GMAIL = "https://mail.google.com/gmail/feed/atom"
uname = sys.argv[1]
password = sys.argv[2]
maxlen = sys.argv[3]
urllib.FancyURLopener.prompt_user_passwd = lambda self, host, realm: (uname, password)
def get_feed():
'''The method to do HTTPBasicAuthentication'''
opener = urllib.FancyURLopener()
f = opener.open(GMAIL)
feed = f.read()
return feed
def read_mail(feed, maxlen):
'''Parse the Atom feed and print a summary'''
atom = feedparser.parse(feed)
num_email = len(atom.entries)
# Output the total number of new emails.
if num_email > 1:
print '${color1} %s new emails\n' % (len(atom.entries))
elif num_email == 1:
print '${color1} %s new emails\n' % (len(atom.entries))
else:
print '${color1} No new emails\n'
for i in range(min(len(atom.entries), maxlen)):
mail = atom.entries[i]
title_len = len(mail.title)
# Test that the email has a subject line. If it does not have a subject
# line then use the author.
if title_len == 0:
title = mail.author
else:
title = mail.title
# Truncate if the email subject line is longer then 20 characters.
# This includes spaces. If it is longer add ellipse.
if len(title) < 21:
print ' ${color2}%s' % title
else:
print ' ${color2}%s...' % title[:20]
#uncomment the following line if you want to show the name of the sender
# print ' ${color2}%s' % atom.entries[i].author
if len(atom.entries) > maxlen:
print ' ${color}more...'
if __name__ == "__main__":
f = get_feed() # Do auth and then get the feed
read_mail(f, int(maxlen)) # Let the feed be chewed by feedparser
Any help would be appreciated. Thank you.