Check unread count of Gmail messages with Python - python

How can I check the number of unread Gmail message in my inbox with a short Python script? Bonus points for retrieving the password from a file.

import imaplib
obj = imaplib.IMAP4_SSL('imap.gmail.com','993')
obj.login('username','password')
obj.select()
obj.search(None,'UnSeen')

Well, I'm going to go ahead and spell out an imaplib solution as Cletus suggested. I don't see why people feel the need to use gmail.py or Atom for this. This kind of thing is what IMAP was designed for. Gmail.py is particularly egregious as it actually parses Gmail's HTML. That may be necessary for some things, but not to get a message count!
import imaplib, re
conn = imaplib.IMAP4_SSL("imap.gmail.com", 993)
conn.login(username, password)
unreadCount = re.search("UNSEEN (\d+)", conn.status("INBOX", "(UNSEEN)")[1][0]).group(1)
Pre-compiling the regex may improve performance slightly.

I advise you to use Gmail atom feed
It is as simple as this:
import urllib
url = 'https://mail.google.com/mail/feed/atom/'
opener = urllib.FancyURLopener()
f = opener.open(url)
feed = f.read()
You can then use the feed parse function in this nice article: Check Gmail the pythonic way

For a complete implementation of reading the value from the atom feed:
import urllib2
import base64
from xml.dom.minidom import parse
def gmail_unread_count(user, password):
"""
Takes a Gmail user name and password and returns the unread
messages count as an integer.
"""
# Build the authentication string
b64auth = base64.encodestring("%s:%s" % (user, password))
auth = "Basic " + b64auth
# Build the request
req = urllib2.Request("https://mail.google.com/mail/feed/atom/")
req.add_header("Authorization", auth)
handle = urllib2.urlopen(req)
# Build an XML dom tree of the feed
dom = parse(handle)
handle.close()
# Get the "fullcount" xml object
count_obj = dom.getElementsByTagName("fullcount")[0]
# get its text and convert it to an integer
return int(count_obj.firstChild.wholeText)

Well it isn't a code snippet but I imagine using imaplib and the Gmail IMAP instructions get you most of the way there.

Once you are logged in (do this manually or with gmail.py) you should use the feed.
It is located here:
http://mail.google.com/mail/feed/atom
It is the way Google does it. Here is a link to their js chrome extension:
http://dev.chromium.org/developers/design-documents/extensions/samples/gmail.zip
You will then be able to parse xml that looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#">
<title>Gmail - Inbox for yourmail#gmail.com</title>
<tagline>New messages in your Gmail Inbox</tagline>
<fullcount>142</fullcount>

I didn't like the existing solutions so I decided to make a sister library for my email sender called Red Box.
It has a pre-configured gmail instance:
from redbox import gmail
# Configure Gmail
gmail.username = "example#gmail.com"
gmail.password = "<PASSWORD>"
# Select inbox folder
inbox = gmail.inbox
# Get unread emails
msgs_unread = inbox.search(seen=False)
# Print unread count
print(len(msgs_unread))
Red Box fetches the email contents only when needed. The above does not do that as we didn't access the contents of these messages. You can also easily access various parts of the messages if you need.
I also wrote how to configure Gmail's app password here:
To install:
pip install redbox
Links:
Source code
Documentation

Use Gmail.py
file = open("filename","r")
usr = file.readline()
pwd = file.readline()
gmail = GmailClient()
gmail.login(usr, pwd)
unreadMail = gmail.get_inbox_conversations(is_unread=True)
print unreadMail
Gets login information from a text file assuming the login name and password are on separate lines.

Related

Sending emails with outlook using Python and HTML

How do I successfully use a sender account with a password that is not already signed in to on the Outlook application on my laptop? I want to send a message from the example account, "from#outlook.com" but it has a password. I have this password. Am I able to enter this into the existing code?
import win32com.client as client
import datetime,time
outlook=client.Dispatch("Outlook.Application")
message=outlook.Createitem(0)
namespace=outlook.GetNameSpace('MAPI')
inbox=namespace.GetDefaultFolder(6)
message=inbox.items.add
message.To="to#outlook.com"
message.CC=""
message.BCC=""
From = "from#outlook.com"
#password = ""
message.Subject="Subject text here"
message.BodyFormat = 2
message.HTMLBody = "<html><h2><span style='color:red'>There is an error with the file </b></span></h2> <body>Please check your submission and try again </body></html>"
message.Save()
message.Display()
time.sleep(5)
message.Send()
Firstly, MailItem object does not expose the From property. It exposes read-only Sender / SenderEmailAddress / SenderName properties, but they obviously cannot be set. You can set the MailItem.Account property to an instance of the Account object retrieved from the Application.Session.Accounts collection, but that requires you to configure the relevant account in Outlook first.
As a general rule, Outlook wont' let you send from an arbitrary one-off account not previously configured in Outlook.

Cannot get the image position in the body from Outlook Python API

I need some help, I am currently trying to do some scripting to automatize some tasks. I would like to fetch the received mail and send the body somewhere.
For that I am using win32.com with the outlook API.
But the issue is that if there is image in the body of the mail. I can't fetch it with the initial body. I Thought about using attachment, which is working but in the end, I have images and the body. But in the body I don't have the image position information... So I can only send the images and cannot set them correctly. Which can be difficult to understand if there is a lot of images...
So far the code looks like something like this :
import os
import win32com.client
outlook = win32com.client.Dispatch('outlook.application')
mapi = outlook.GetNamespace("MAPI")
inbox = mapi.GetDefaultFolder(6)
messages = inbox.Items
message = messages[len(messages) - 1]
body = message.body
attachments = message.attachments
attachment = attachments[0]
file_name = attachment.filename
path = "D:\\Documents\\tmp"
attachment.SaveAsFile(path + os.sep + attachment.FileName)
Do you have any help on this ?
Thanks for your help :)
PS : Do you know where I can find the Python documentation for outlook API, I just find the Rest API one and there is some difference from both. Or if we can get the source code to check directly.
In the message body you may check for <img/> tags. If any of them contains this tag with a file name prefixed with cid: string, for example:
<img src=cid:Filename/>
Then you deal with an embedded image which can be found in attached files.
Also you may check the PR_ATTACH_CONTENT_ID property on the attached files in the following way:
Const PR_ATTACH_CONTENT_ID = "http://schemas.microsoft.com/mapi/proptag/0x3712001F"
Function IsEmbedded(Att As Attachment) As Boolean
Dim PropAccessor As PropertyAccessor
Set PropAccessor = Att.PropertyAccessor
IsEmbedded = (PropAccessor.GetProperty(PR_ATTACH_CONTENT_ID) <> "")
End Function
The PropertyAccessor can help you to deal with low-level MAPI properties in Outlook.

How to import an EODData download link to a python variable

I'm trying to import a text file of all of the NASDAQ symbols from EODData (http://eoddata.com/Data/symbollist.aspx?e=NASDAQ) into a python variable to save as a csv file. When I put the link into a Chrome browser the file downloads, but when I try to import it using urllib2 or pandas it looks like it is reading a website.
It seems to be similar to: EodData wsdl java connection but I'm trying to do it in python.
import urllib2
data = urllib2.urlopen("http://eoddata.com/Data/symbollist.aspx?e=NASDAQ")
for line in data:
print line
It seems that you must log in in order to download the data. You can download your data on chrome because you are automatically logged in. but through python, you have to register/log in. Try to check out the login API of the website and include your credentials in your code.
you have to look at the __init__ methods to fill it out with your credentials :
def __init__(self, username, password,
base_url='http://ws.eoddata.com/data.asmx/',
max_login_retries=3, logger=None):
"""
Args:
username (str): Account username.
password (str): Account password.
base_url (str): Base url of SOAP service
(defaults to `http://ws.eoddata.com/data.asmx/`).
max_login_retries (int): Maximum login retries, increase if there
are several clients working in parallel.
logger (logging.Logger): Client logger.
"""
self._token = ''
self._username = username
self._password = password
self._max_login_retries = max_login_retries
self._base_url = base_url
self.logger = logger or logging.getLogger('eoddata_client')
As per the documentation, you have to replace the username and password with your credentials. Also, you'll have to add the token which can be extracted from your account on the website.

What is the first step to getting in e-mail into my python / flask app code?

I am researching what it would take to make a web app that would interact with e-mails directly. Like you would send to something#myapp.com and the app would tear it apart and determine who it's from, if they are in the DB, what is the subject line, etc.
I am working with/most familiar with python and flask.
Could anyone get me started in the right direction of how to get an e-mail to interface with my flask app code?
There are several approach you can take:
write some code which uses IMAP or POP to retrieve emails and process them. Either run this from a crontab (or something similar) or add it to your flask app and trigger it in there, either through a crontab that requests a magic URL or setting up a custom timer thread.
configure your MTA to deliver email for something#myapp.com by feeding it to a program you write (for example in Exim you could use a pipe transport) . In that program you can either process it directly, or do something like POSTing it to your flask app.
I've done something along these lines recently, with a simple bookmarking web-app. I have the usual bookmarklet way of bookmarking something to it, but I also wanted to be able to e-mail links to it from apps like Reeder on my iPhone and whatever. You can see what I ended up with on GitHub: subMarks.
I use Google Apps for your Domain for my email, so I created a special address for my app to look at - I really didn't want to try building/configuring my own e-mail server.
the mail_daemon.py file from above is run as a cron job every 5 minutes. It connects to the email server using the poplib Python package, processes the emails that are there and then disconnects (one part I feel compelled to point out is that I check that the emails are from me before they are processed :) )
My Flask app then provides the front end to the bookmarks, displaying them from the database.
I decided not to put the email handling code into the actual flask app, because it can be rather slow and would only run when the page was visited, but you could do this if you wanted.
Here's some barebones code to get things going:
import poplib
from email import parser
from email.header import decode_header
import os
import sys
pop_conn = poplib.POP3_SSL('pop.example.com')
pop_conn.user('my-app#example.com')
pop_conn.pass_('password')
#Get messages from server:
messages = [pop_conn.retr(i) for i in range(1, len(pop_conn.list()[1]) + 1)]
# Concat message pieces:
messages = ["\n".join(mssg[1]) for mssg in messages]
#Parse message into an email object:
messages = [parser.Parser().parsestr(mssg) for mssg in messages]
for message in messages:
# check message is from a safe recipient
if 'me#example.com' in message['from']:
# Get the message body text
if message['Content-Type'][:4] == 'text':
text = message.get_payload() #plain text messages only have one payload
else:
text = message.get_payload()[0].get_payload() #HTML messages have more payloads
# decode the subject (odd symbols cause it to be encoded sometimes)
subject = decode_header(message['subject'])[0]
if subject[1]:
bookmark_title = subject[0].decode(subject[1]).encode('ascii', 'ignore') # icky
else:
bookmark_title = subject[0]
# in my system, you can use google's address+tag#gmail.com feature to specifiy
# where something goes, a useful feature.
project = message['to'].split('#')[0].split('+')
### Do something here with the message ###
pop_conn.quit()

Access Highrise's API with Python?

How can I access 37 signals Highrise's API with Python? Found wrappers for PHP/Ruby, but not Python. I'm writing my own now, anyone have advice on getting over the first hurdle of authentication with Python?
I wrote (am writing, really) a Highrise API wrapper for Python. It uses Python objects for each of the Highrise classes and work a lot like the Django ORM:
>>> from pyrise import *
>>> Highrise.server('my-server')
>>> Highrise.auth('api-key-goes-here')
>>> p = Person()
>>> p.first_name = 'Joe'
>>> p.last_name = 'Schmoe'
>>> p.save()
You can get the source from GitHub: https://github.com/feedmagnet/pyrise
Or install it from PyPI:
$ sudo pip install pyrise
I was just tackling this problem when I stumbled onto your question. Here is what I have hacked together so far. Its not pretty (yet) but it works. I don't know Pycurl and after looking at it for a while I went back to urllib2. Highrise uses Basic Authentication so you don't have to use CURL you can use urllib2. You just have to go through all the Pword Manager steps. The output is a long XML file of either all the companies or the people depending on which URL you insert. If you wanted just one person you could do something like 'http....../people/123.xml' or 'http....../people/123-fname-lname.xml' (like you see in the url when you actually go to a contact in highrise with the .xml added).
import ullib2
PEOPLEurl = 'http://yourcompany.highrisehq.com/people.xml' #get all the people
# or
COMPANYurl = 'http://yourcompany.highrisehq.com/company.xml' #get all companies
token = '12345abcd' #your token
password = 'X'
passmanager = urllib2.HTTPPasswordMgrWithDefaultRealm()
passmanager.add_password(None, PEOPLEurl, token, password)
authhandler = urllib2.HTTPBasicAuthHandler(passmanager)
opener = urllib2.build_opener(authhandler)
urllib2.install_opener(opener)
page = urllib2.urlopen(PEOPLEurl).read()
print page #this will dump out all the people contacts in highrise
Any feedback or suggestions on this code would be helpful!
See here on how to do basic authentication. Also IIRC urllib supports http://user:password#example.com URLs.
i was just looking to the php code of one of the php API wrappers and i see that they use curl ; so have you looked to pycurl ??
about the authentication here is an example that you can start with (it's not tested)...
import pycurl
def on_receive(data):
# process your data here
pass
def connetion(url, token)
conn = pycurl.Curl()
# Set Token.
conn.setopt(pycurl.USERPWD, "%s:x" % (token,))
# the format TOKEN:x i get it from the PHP wrapper because usually the
# format should be USER:PASSWD so here i think they just use a token as
# a USERname and they set the password to 'x'.
conn.setopt(pycurl.URL, url)
# Set the XML data to POST data.
conn.setopt(pycurl.POSTFIELDS, XML_DATA)
# Add SSL.
conn.setopt(pycurl.SSL_VERIFYPEER, 0)
conn.setopt(pycurl.SSL_VERIFYHOST, 0)
# Set function that will be called as soon as the data is received.
conn.setopt(pycurl.WRITEFUNCTION, on_receive)
# Perform the data transfer.
conn.perform()
if __name__ == '__main__':
connection("http://yourcompany.highrisehq.com", your_token)

Categories

Resources