[Deskbar] GMail account search



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



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]