~woutc/specto/specto-dbus-client

« back to all changes in this revision

Viewing changes to spectlib/gmailatom.py

  • Committer: Jean-François Fortin Tam
  • Author(s): Wout Clymans
  • Date: 2008-07-22 23:22:49 UTC
  • Revision ID: jeff@kiki-20080722232249-l64srclhp6u6qyrw
WARNING: this commit contains all the significant changes that happened in a specto-woutc branch over the past year. Large change log follows. Some commit log lines were intentionally left out.

- A dialog with debug information is shown when specto has a system/programming error.
- Disable renaming watches in the listview, make it a Jump To action instead
- All mandatory fields have to be filled in now (add and edit watch)
- The error log now shows the lines in color according to the severity
- Better file size cache name
- Added more error-handling
- The filesize is now saved in a different cache file (not in watches.list), may fix issue 37?
- Icons are now shown in the combobox when you add a new watch (buggy, patches welcome)
- Improved the pop3, imap and gmail watches
- The gmail watch now saves what unread mails there already were last time
- Convert HTML entities for the web diff
- Moved some code so the file dialog will show faster
- A watch will be marked updated when you didn't clear it on quit.
- Removed double call to refresh the watch info
- Made a general gtkutil file where you can define widgets used in the edit and add watch windows
- Removed the class name from the logger
- Clear the watch when you open it using the balloon
- Make some watch names clearer
- Error log tab in notifier window
- Added "clear" button in the edit menu
- Show simple diff from webpage difference
- Console mode (specto --console or specto --console --help)
- Watch menu when you right-click a watch entry in the notifier window
- Ability to run a command when a watch is updated
- Ability to run a command when a watch is cleared
- Fields in the add and edit windows are now dynamic; when creating a new watch plugin, you don't have to write all the gui code anymore
- More space for the extra information in the info panel
- code cleanup
- use plugin-system

- Fix issue 150: Gmail.com - that address is disabled in Germany - hence you can't go to messages directly
- Fix issue 93: Gmail library can support no more than 19 new mails
- Fix issue 131: bombs on special characters
- Fix issue 134: harmonized colors
- Fix issue 119: don't let the log file get huge
- Fix issue 143: Site adress in "About" box is not clickable
- Fix issue 146: Per-watch option to prevent URL redirects; To use this option add "redirect = True" to the watch that is allowed to redirect
- Fix issue 145: abnormal behavior with ampersands in a web watch
- Fix issue 51: Specto stores passwords in plaintext (started keyring support)
- Fix issue 135: Proxy support (already proxy support for web watch)
- Fix issue 128: allow specifying a port for mail watches (add 'port = 323' to your watch config)
- Fix issue 132: removing a watch should remove its cache files
- Fix issue 136: Support specific folder monitor over IMAP (add 'folder = work' to your imap watch config)
- Fix issue 63: Google Reader Watch does not support more than 20 items
- Fix issue 39: POP3 & IMAP watches not on par with gmail watch's message counting logic
- Fix issue 100: gmail with google apps should point to the right domain when clicking Jump to
- Fix issue 95: statusbar should show something else when updates are done
- Fix issue 112: hide error log tabs when debug mode is deactivated
- Fix issue 101: show the import dialog after the file chooser
- Fix issue 114: removing a watch should show a confirmation dialog
- Fix issue 73: brackets in watch name lead to startup crash (brackets can now be used in the name!)
- Fix issue 69: startup fails due to wrong glade file path  
- Fix issue 12: provide more information
- Fix issue 13: watch list importing and exporting
- Fix issue 20: Organise specto source into modules
- Fix issue 33: ability to run a command instead of notifying
- Fix issue 54: freedesktop-compliant user directories
- Fix issue 72: "show in window list" preference is not saved
- Fix issue 77: don't mess up if ekiga's sound files are not present
- Fix issue 118: add http:// automatically for web watches (also @gmail.com added for gmail accounts)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# -*- coding: utf-8 -*-
2
 
 
3
 
# gmailatom 0.0.1
4
 
#
5
 
# HOW TO USE:
6
 
# 1) Create an instance of 'GmailAtom' class. The two arguments
7
 
#    its constructor take are the username (including '@gmail.com')
8
 
#    and the password.
9
 
# 2) To retrieve the account status call 'refreshInfo()'.
10
 
# 3) To get the unread messages count call 'getUnreadMsgCount()'.
11
 
#    You MUST call 'refreshInfo()' at least one time before using
12
 
#    this method or it will return zero.
13
 
# 4) To get specific information about an unread email you must
14
 
#    call the corresponding getter method passing to it the number
15
 
#    of the message. The number zero represents the newest one.
16
 
#    You MUST call 'refreshInfo()' at least one time before using any
17
 
#    getter method or they will return an empty string.
18
 
#    The getter methods are:
19
 
#       getMsgTitle(index)
20
 
#       getMsgSummary(index)
21
 
#       getMsgAuthorName(index)
22
 
#       getMsgAuthorEmail(index)
23
 
#
24
 
# by Juan Grande
25
 
# juan.grande@gmail.com
26
 
 
27
 
from xml.sax.handler import ContentHandler
28
 
from xml import sax
29
 
import urllib2
30
 
 
31
 
# Auxiliar structure
32
 
class Mail:
33
 
        title=""
34
 
        summary=""
35
 
        author_name=""
36
 
        author_addr=""
37
 
 
38
 
# Sax XML Handler
39
 
class MailHandler(ContentHandler):
40
 
        
41
 
        # Tags
42
 
        TAG_FEED = "feed"
43
 
        TAG_FULLCOUNT = "fullcount"
44
 
        TAG_ENTRY = "entry"
45
 
        TAG_TITLE = "title"
46
 
        TAG_SUMMARY = "summary"
47
 
        TAG_AUTHOR = "author"
48
 
        TAG_NAME = "name"
49
 
        TAG_EMAIL = "email"
50
 
        
51
 
        # Path the information
52
 
        PATH_FULLCOUNT = [ TAG_FEED, TAG_FULLCOUNT ]
53
 
        PATH_TITLE = [ TAG_FEED, TAG_ENTRY, TAG_TITLE ]
54
 
        PATH_SUMMARY = [ TAG_FEED, TAG_ENTRY, TAG_SUMMARY ]
55
 
        PATH_AUTHOR_NAME = [ TAG_FEED, TAG_ENTRY, TAG_AUTHOR, TAG_NAME ]
56
 
        PATH_AUTHOR_EMAIL = [ TAG_FEED, TAG_ENTRY, TAG_AUTHOR, TAG_EMAIL ]
57
 
 
58
 
        def __init__(self):
59
 
                self.startDocument()
60
 
 
61
 
        def startDocument(self):
62
 
                self.entries=list()
63
 
                self.actual=list()
64
 
                self.mail_count="0"
65
 
 
66
 
        def startElement( self, name, attrs):
67
 
                # update actual path
68
 
                self.actual.append(name)
69
 
 
70
 
                # add a new email to the list
71
 
                if name=="entry":
72
 
                        m = Mail()
73
 
                        self.entries.append(m)
74
 
 
75
 
        def endElement( self, name):
76
 
                # update actual path
77
 
                self.actual.pop()
78
 
 
79
 
        def characters( self, content):
80
 
                # New messages count
81
 
                if (self.actual==self.PATH_FULLCOUNT):
82
 
                        self.mail_count = self.mail_count+content
83
 
 
84
 
                # Message title
85
 
                if (self.actual==self.PATH_TITLE):
86
 
                        temp_mail=self.entries.pop()
87
 
                        temp_mail.title=temp_mail.title+content
88
 
                        self.entries.append(temp_mail)
89
 
 
90
 
                # Message summary
91
 
                if (self.actual==self.PATH_SUMMARY):
92
 
                        temp_mail=self.entries.pop()
93
 
                        temp_mail.summary=temp_mail.summary+content
94
 
                        self.entries.append(temp_mail)
95
 
 
96
 
                # Message author name
97
 
                if (self.actual==self.PATH_AUTHOR_NAME):
98
 
                        temp_mail=self.entries.pop()
99
 
                        temp_mail.author_name=temp_mail.author_name+content
100
 
                        self.entries.append(temp_mail)
101
 
 
102
 
                # Message author email
103
 
                if (self.actual==self.PATH_AUTHOR_EMAIL):
104
 
                        temp_mail=self.entries.pop()
105
 
                        temp_mail.author_addr=temp_mail.author_addr+content
106
 
                        self.entries.append(temp_mail)
107
 
 
108
 
        def getUnreadMsgCount(self):
109
 
                return int(self.mail_count)
110
 
 
111
 
# The mail class
112
 
class GmailAtom:
113
 
 
114
 
        realm = "New mail feed"
115
 
        host = "https://mail.google.com"
116
 
        url = host + "/mail/feed/atom"
117
 
 
118
 
        def __init__(self, user, pswd):
119
 
                self.m = MailHandler()
120
 
                # initialize authorization handler
121
 
                auth_handler = urllib2.HTTPBasicAuthHandler()
122
 
                auth_handler.add_password( self.realm, self.host, user, pswd)
123
 
                opener = urllib2.build_opener(auth_handler)
124
 
                urllib2.install_opener(opener)
125
 
 
126
 
        def sendRequest(self):
127
 
                return urllib2.urlopen(self.url)
128
 
 
129
 
        def refreshInfo(self):
130
 
                # get the page and parse it
131
 
                p = sax.parseString( self.sendRequest().read(), self.m)
132
 
 
133
 
        def getUnreadMsgCount(self):
134
 
                return self.m.getUnreadMsgCount()
135
 
 
136
 
        def getMsgTitle(self, index):
137
 
                return self.m.entries[index].title
138
 
 
139
 
        def getMsgSummary(self, index):
140
 
                return self.m.entries[index].summary
141
 
 
142
 
        def getMsgAuthorName(self, index):
143
 
                return self.m.entries[index].author_name
144
 
 
145
 
        def getMsgAuthorEmail(self, index):
146
 
                return self.m.entries[index].author_email