Hi ! I recently seen the Stuart Langridge's plugins for deskbar. I took his gmail search plugin (using libgmail) and prettified it a bit. I attach it to the mail. It uses gconf to store username and password. Please tell me what you think about it, if it should go in core release for 2.15 or not.. If we manage to get web-plugins done, then it can be moved afterwards.. Raf
""" Gmail Deskbar A plugin for the Gnome deskbar applet that searches your Gmail account. Stuart Langridge, http://www.kryogenix.org/ Licenced under the GNU GPL, version 2.0 """ from gettext import gettext as _ import urllib, os, cgi, re import gnomevfs, gtk, gconf import deskbar.Handler, deskbar, deskbar.Match from deskbar.Utils import strip_html, htmldecode import xml.dom.minidom try: import libgmail except: pass # alert in requirements GCONF_GMAIL_USER = deskbar.GCONF_DIR+"/gmail/user" GCONF_GMAIL_PASSWORD = deskbar.GCONF_DIR+"/gmail/password" GMAIL_MESSAGE_URL = 'https://mail.google.com/mail/h/?q=%(search)s&s=q&th=%(thread)s&v=c' QUERY_DELAY = 1 GMAIL_ICON = [ "16 16 8 1", " c None", ". c #DA3838", "+ c #F28181", "@ c #F9A7A7", "# c #FFB6B6", "$ c #FFFFFF", "% c #E95A5A", "& c #FFE2E2", " ", " ", " ", "...+@@@@@@@@+...", "....#$$$$$$#....", "..+%.#$$$$#.%+..", "..$+%.#$$#.%+$..", "..$$+%.##.%+$$..", "..$$#+%..%+#$$..", "..$&@#+%%+#@&$..", "..&@&$$++$$&@&..", "..@&$$$$$$$$&@..", "..&$$$$$$$$$$&..", "..@@@@@@@@@@@@..", " ", " " ] def monkeypatch_libgmail_login(self): "New login method for GmailAccount in old libgmails: monkeypatch" import urllib,urllib2,re data = urllib.urlencode({ 'continue': "https://mail.google.com/mail/", # hardcode new URL_GMAIL 'Email': self.name, 'Passwd': self._pw, }) headers = { 'Host': 'www.google.com', 'User-Agent': 'User-Agent: Mozilla/5.0 (compatible;)', } req = urllib2.Request(libgmail.URL_LOGIN, data=data, headers=headers) pageData = self._retrievePage(req) RE_PAGE_REDIRECT = 'CheckCookie\?continue=([^"]+)' try: redirectURL = urllib.unquote( re.search(RE_PAGE_REDIRECT, pageData).group(1)) except AttributeError: raise GmailLoginFailure pageData = self._retrievePage(redirectURL) def _on_more_information(dialog): deskbar.Utils.more_information_dialog(dialog, _("Getting libgmail"), _( """Gmail Search requires libgmail. Download from http://libgmail.sf.net/ or install your distribution's package (for example python-libgmail in Ubuntu).""")) def _on_config_account(dialog): dialog = gtk.Dialog(_("Gmail Account"), dialog, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) table = gtk.Table(rows=2, columns=2) table.attach(gtk.Label(_("Enter your Gmail username and password below")), 0, 2, 0, 1) user_entry = gtk.Entry() t = deskbar.GCONF_CLIENT.get_string(GCONF_GMAIL_USER) if t != None: user_entry.set_text(t) table.attach(gtk.Label(_("Username: ")), 0, 1, 1, 2) table.attach(user_entry, 1, 2, 1, 2) pass_entry = gtk.Entry() t = deskbar.GCONF_CLIENT.get_string(GCONF_GMAIL_PASSWORD) if t != None: pass_entry.set_text(t) #pass_entry.set_visibility(False) table.attach(gtk.Label(_("Password: ")), 0, 1, 2, 3) table.attach(pass_entry, 1, 2, 2, 3) table.show_all() dialog.vbox.add(table) response = dialog.run() dialog.destroy() if response == gtk.RESPONSE_ACCEPT and user_entry.get_text() != "" and pass_entry.get_text() != "": deskbar.GCONF_CLIENT.set_string(GCONF_GMAIL_USER, user_entry.get_text()) deskbar.GCONF_CLIENT.set_string(GCONF_GMAIL_PASSWORD, pass_entry.get_text()) def _check_requirements(*args): try: import libgmail if not deskbar.GCONF_CLIENT.get_string(GCONF_GMAIL_USER) or not deskbar.GCONF_CLIENT.get_string(GCONF_GMAIL_PASSWORD): return (deskbar.Handler.HANDLER_HAS_REQUIREMENTS, _("You need to configure your Gmail account."), _on_config_account) else: return (deskbar.Handler.HANDLER_IS_CONFIGURABLE, _("You can modify your Gmail account."), _on_config_account) except Exception, e: return (deskbar.Handler.HANDLER_HAS_REQUIREMENTS, "Gmail Search requires libgmail (libgmail.sf.net)", _on_more_information) HANDLERS = { "GmailHandler" : { "name": _("Gmail Search"), "description": _("Search your emails and conversations from Gmail"), "requirements" : _check_requirements } } class GmailMatch(deskbar.Match.Match): def __init__(self, handler, url=None, authors=None, snippet=None, **args): deskbar.Match.Match.__init__ (self, handler, **args) self.url = url self.snippet = snippet def get_name(self, text=None): return { "name": cgi.escape(self.name), "snippet": self.snippet, } def get_verb(self): return "<b>%(name)s</b>" + "\n<span foreground='grey' size='small'>%(snippet)s</span>" def action(self, text=None): gnomevfs.url_show(self.url) def get_category(self): return "emails" def get_hash(self, text=None): return self.url class GmailHandler(deskbar.Handler.AsyncHandler): def __init__(self): deskbar.Handler.AsyncHandler.__init__(self, None) self._icon = gtk.gdk.pixbuf_new_from_xpm_data(GMAIL_ICON) self._account = None self._user = deskbar.GCONF_CLIENT.get_string(GCONF_GMAIL_USER) self._password = deskbar.GCONF_CLIENT.get_string(GCONF_GMAIL_PASSWORD) deskbar.GCONF_CLIENT.notify_add(GCONF_GMAIL_USER, lambda x, y, z, a: self.on_username_change(z.value)) deskbar.GCONF_CLIENT.notify_add(GCONF_GMAIL_PASSWORD, lambda x, y, z, a: self.on_password_change(z.value)) def on_username_change(self, value): if value != None and value.type == gconf.VALUE_STRING: self._user = value.get_string() self._account = None def on_password_change(self, value): if value != None and value.type == gconf.VALUE_STRING: self._password = value.get_string() self._account = None def login(self): if self._account != None: return self._account ga = libgmail.GmailAccount(self._user, self._password) try: v = libgmail.Version except: # libgmail had a broken login() in older versions, including # that packaged with Ubuntu Dapper and previous. If it doesn't # have a version number then it's an old version, so monkeypatch # the login function to work. libgmail.GmailAccount.login = monkeypatch_libgmail_login try: ga.login() self._account = ga return self._account except Exception, msg: print 'Error:GMail handler:login():', msg def query(self, qstring, defres): # Delay before we query so we *don't* make four queries # "s", "sp", "spa", "spam". self.check_query_changed (timeout=QUERY_DELAY) print 'Query Gmail for:', qstring # for x in self.login().getMessagesByQuery(qstring): # for prop in ('unread', 'star', 'date','authors','flags','subject', # 'snippet','categories','attach','matching_msgid','extra_snippet'): # try: # print prop, ':', getattr(x, prop) # except: # print 'no prop', prop # The gmail search might have taken a long time # better check if we're still valid account = self.login() if account == None: return [] for x in account.getMessagesByQuery(qstring): match = GmailMatch(self, name=cgi.escape(x.subject), snippet=cgi.escape( strip_html(htmldecode(x.snippet))), url=GMAIL_MESSAGE_URL % { "search": urllib.quote_plus(qstring), "thread": x.info[0] }) self.emit_query_ready(qstring, [match])
Attachment:
signature.asc
Description: This is a digitally signed message part