Gmail Notifier using SchedulGhost, OSM and plain python

Do you have questions about writing plugins or scripts in Python? Meet the coders here.
Post Reply
tom.luft
Posts: 4
Joined: Mon Sep 30, 2013 10:05 am

Gmail Notifier using SchedulGhost, OSM and plain python

Post by tom.luft » Mon Sep 30, 2013 10:32 am

I spent the last few hours on my computer coding my very own gmail notifier. As I didn't find any similar project on the web I thought I'd share my findings.
So my little script
  • logs in gmail via basic http authentication
  • fetches the gmail atom feed
  • parses it in a quite 'dirty' way and finally
  • passes the unread mail counter, the unread mail subjects and their direct http links to the osm plugin, which displays those informations.
When you click on those subjects you directly get to the associated emails.

The SchedulGhost plugin triggers events periodically. Those events trigger my python script. If there are unread emails, this python script triggers the osm plugin. If you click on a subject this triggers firefox (or any convenient browser) with the passed html links. This should work with any website, as long as it understands basic http authentication and can be parsed as easily as an atom feed.

That's the python script.

Code: Select all

import urllib2 as req
import HTMLParser
h = HTMLParser.HTMLParser()

# ----------------- USER SECTION -----------------
# login data
realm = 'New mail feed'
url = 'https://mail.google.com' 
user = 'your_username@gmail.com'
passwd = 'your_password'

# feed url
feed_url = 'https://mail.google.com/mail/feed/atom'

# texts
none_unread = 'Keine neuen Emails'
one_unread = 'x ungelesenes Email' # x = 1
more_unread = 'x ungelesene Emails' # x = unread email count
stop_notifications = 'Benachrichtigungen stoppen'
close_menu = 'Schliessen'

# codec for subjects
# for available codecs visit http://docs.python.org/2/library/codecs.html#standard-encodings
codec = 'latin_1'
# -------------- END OF USER SECTION --------------

# authentication
auth_handler = req.HTTPBasicAuthHandler()
auth_handler.add_password(
        realm,
        url,
        user,
        passwd
)
opener = req.build_opener(auth_handler)
req.install_opener(opener)
request=opener.open(feed_url)
response=str(request.read())

# find beginning and end of unread mail count 
# by finding the two instances of the word 'fullcount'

fc_start = response.find('fullcount')+10
fc_end = response.find('fullcount',fc_start+1)-2
unread_count = response[fc_start:fc_end]

if unread_count != '0':
    if unread_count == '1':
        text = one_unread.replace('x', '1')
    else:
        text = more_unread.replace('x', unread_count)
    print(text)
    
    # add unread mail count to osm entries
    eg.gmail_osm_entries=[(text,'gmail_read.0')]  
    
    titles = []; links=['gmail.com']; ti_start=0; ti_end=0; en_start=0; en_end=0;
    # same approach for subjects
    # here the word is 'title' but not before the word 'entry'
    # links for the entries are found in a similar way
    
    # in the OSM the subjects are shown but event names with the link number as suffix are created
    # they are passed further on as payloads via the OSM plugin
    # the links can then be accessed via {eg.gmail_links[int(eg.event.payload)]}
    # link 0 is defined as 'gmail.com'
    
    eg.gmail_osm_entries.append(['----------------------------------------------------','dummy'])
    
    for i in range (1,int(unread_count)+1):
        # find positions of keywords
        en_start = response.find('entry',en_end)+6
        ti_start = response.find('title',en_start)+6
        ti_end = response.find('title',ti_start+1)-2
        li_start = response.find('link rel=',ti_end)+27
        li_end = response.find('type=',li_start)-2
        en_end = response.find('entry',en_start+1)+6
        # extract subject
        utf8_subject = response[ti_start:ti_end]
        # decode subject
        decoded_subject = utf8_subject.decode('utf_8','ignore')
        # encode subject
        subject = decoded_subject.encode(codec,'ignore')
        subject = h.unescape(subject)
        # add event name to subject
        subject_event = (subject,'gmail_read.'+str(i))
        # add subject and event name to list
        eg.gmail_osm_entries.append(subject_event)
        # extract link, unescape it and add it to the link list
        # the links will be accessed via priorily assigned numbers
        # the event gmail_read.3 will show the 4th link 
        # (numbering of lists always starts with 0)
        links.append(h.unescape(response[li_start:li_end]))
        
    # add entry for stopping the notifications and closing the menu (for using with mice)
    eg.gmail_osm_entries.append(['----------------------------------------------------','dummy'])
    eg.gmail_osm_entries.append([stop_notifications,'gmail_stop'])
    eg.gmail_osm_entries.append([close_menu,'dummy'])
    
    # save links in eg workspace
    eg.gmail_links=links
    
    # trigger event for unread emails
    eg.TriggerEvent('gmail_unread')
else:
    print(none_unread)
If there are unread emails it triggers the event Main.gmail_unread.
So let a macro listen to this event and start osm (show menu, created from expression) when it appears. Settings in osm are as follows:
List of menu items: eg.gmail_osm_entries
The third part applied as: event payload

If you click on an item it creates an event called OSM.gmail_read x where x is the number of the entry you clicked.
Next thing to do: let a macro listen to the event OSM.gmail_read and let it start a browser with this parameter: {eg.gmail_links[int(eg.event.payload)]}.
If you click on the close button, it creates a dummy event and just closes the menu.
If you click on the notificatiom stop button, it creates an event OSM.gmail_stop. So let a macro listen to it and when triggered disable the python script.

Well this sounds confusing and complicated, but it really is quite straight forward. In the user section you can define your credentials, your preferred messages, codec etc.
Post here if you got any problems!
Attachments
30-09-2013 12-27-46.png
Screenshot of the osm
30-09-2013 12-27-46.png (5.41 KiB) Viewed 1857 times

Post Reply