""" Converter Deskbar A plugin for the Gnome deskbar applet that converts from one thing to another. Stuart Langridge, http://www.kryogenix.org/ Licenced under the GNU GPL, version 2.0 """ from gettext import gettext as _ import urllib, os, re, subprocess import gtk import deskbar.Handler, deskbar CONVERTER_ICON = [ "16 16 8 1", " c None", ". c #000000", "+ c #0000B0", "@ c #00B000", "# c #B00000", "$ c #B0FFB0", "% c #FFB0B0", "& c #FFFFFF", " ", " . ", " .%. +++ ", " .%%#. &&+ ", " .%%%##. +& ", " .%%#.& +++ ", " .%.& +&& ", " .& & ", " . ", " .$. ", " .$$@. ", " .$$$@@. ", " .$$@.& ", " .$.& ", " .& ", " " ] HELP_TEXT = _("""Converter requires the GNU units program. Download from http://www.gnu.org/software/units/units.html or install your distribution's package ('units' in Ubuntu).""") r_normal = re.compile(""" ^ # start string \s* # optional whitespace (?P[0-9.]+) # a number \s* # optional whitespace (?P[^\s]+) # unit1 \s+ in \s+ # " in " (with compulsory whitespace) (?P[^\s]+) # unit2 \s* # optional whitespace $ # end""", re.VERBOSE | re.IGNORECASE) r_currency = re.compile(""" ^ # start string \s* # optional whitespace (?P[£\$]+) # unit1, a $ or a £ \s* # optional whitespace (?P[0-9.]+) # a number \s+ in \s+ # " in " (with compulsory whitespace) (?P[^\s]+) # unit2 \s* # optional whitespace $ # end""", re.VERBOSE | re.IGNORECASE) CURRENCIES = { "GBP": ["pound", "pounds", "£"], "USD": ["dollar", "dollars", "$"], } def _on_more_information(x): deskbar.Utils.more_information_dialog(None,_("Getting GNU units"),HELP_TEXT) def _check_requirements(*args): if not True in [os.path.isfile(os.path.join(x,'units')) for x in os.environ["PATH"].split(":")]: return (deskbar.Handler.HANDLER_HAS_REQUIREMENTS, "Converter requires the GNU units program", _on_more_information) return (deskbar.Handler.HANDLER_IS_HAPPY, None, None) HANDLERS = { "ConverterHandler" : { "name": _("Converter"), "description": _("Convert one quantity to another"), "requirements" : _check_requirements } } class ConverterMatch(deskbar.Match.Match): def get_verb(self): return "%(name)s" def get_category(self): return "actions" def get_hash(self, text=None): return self.name def action(self, x): pass class ConverterHandler(deskbar.Handler.AsyncHandler): def __init__(self): deskbar.Handler.AsyncHandler.__init__(self, None) self._icon = gtk.gdk.pixbuf_new_from_xpm_data(CONVERTER_ICON) def parse_query(self,q): # check if query has one of the following formats: # "2 in " # "2 in " # "2 in " # where special_unit1 is a $ or a £, to handle currency conversions normal = r_normal.match(q) if normal: d = normal.groupdict() return d else: currency = r_currency.match(q) if currency: d = currency.groupdict() return d def run_query(self,q): items = self.parse_query(q) if items: # First, try shelling out to the units program to do the conversion try: r = subprocess.Popen("units -t '%(number)s %(unit1)s' '%(unit2)s'" % items, shell=True, stdout=subprocess.PIPE) oline = r.stdout.readlines()[0].strip() if oline.startswith('Unknown unit'): raise "Unknown unit" if oline.startswith('conformability error'): raise "Conformability" return "%s %s = %s %s" % (items['number'],items['unit1'], oline, items['unit2']) except: # It failed. Fix up currencies for curcode, curnames in CURRENCIES.items(): for curname in curnames: if items['unit1'] == curname: items['unit1'] = curcode if items['unit2'] == curname: items['unit2'] = curcode try: r = subprocess.Popen("units -t '%(number)s %(unit1)s' '%(unit2)s'" % items, shell=True, stdout=subprocess.PIPE) oline = r.stdout.readlines()[0].strip() if oline.startswith('Unknown unit'): raise "Unknown unit" if oline.startswith('conformability error'): raise "Conformability" return "%s %s = %.2f %s" % (items['number'],items['unit1'], float(oline), items['unit2']) except: return None def query(self, qstring, defres): ret = self.run_query(qstring) if ret: return [ConverterMatch(self, name=ret)] else: return []