home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / lib / deskbar-applet / handlers / beagle-live.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2006-08-31  |  11.0 KB  |  371 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. import os
  5. import sys
  6. import cgi
  7. import re
  8. import gobject
  9. import gtk
  10. import gnome
  11. import gnome.ui as gnome
  12. import gnomevfs
  13. import deskbar
  14. import deskbar.Handler as deskbar
  15. import deskbar.Utils as deskbar
  16. import deskbar.Match as deskbar
  17. from gettext import gettext as _
  18. from os.path import exists
  19. from deskbar.defs import VERSION
  20. MAX_RESULTS = 20
  21.  
  22. try:
  23.     import beagle
  24. except:
  25.     pass
  26.  
  27.  
  28. def _show_start_beagle_dialog(dialog):
  29.     dialog = gtk.Dialog(_('Start Beagle Daemon?'), dialog, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
  30.     dialog.set_default_size(350, 150)
  31.     dialog.add_button(_('Start Beagle Daemon'), gtk.RESPONSE_ACCEPT)
  32.     dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT)
  33.     label = gtk.Label(_('The Beagle daemon does not appear to be running.\n You need to start it to use the Beagle Live handler.'))
  34.     dialog.vbox.add(label)
  35.     label.show()
  36.     response = dialog.run()
  37.     dialog.destroy()
  38.     if response == gtk.RESPONSE_ACCEPT:
  39.         print 'Starting Beagle Daemon.'
  40.         gobject.spawn_async([
  41.             'beagled'], flags = gobject.SPAWN_SEARCH_PATH)
  42.     
  43.  
  44.  
  45. def _check_requirements():
  46.     
  47.     try:
  48.         import deskbar
  49.         import beagle
  50.     except Exception:
  51.         e = None
  52.         return (deskbar.Handler.HANDLER_IS_NOT_APPLICABLE, 'Could not load beagle, libbeagle has been compiled without python bindings:' + str(e), None)
  53.  
  54.     if not beagle.beagle_util_daemon_is_running():
  55.         return (deskbar.Handler.HANDLER_HAS_REQUIREMENTS, 'Beagle daemon is not running.', _show_start_beagle_dialog)
  56.     else:
  57.         return (deskbar.Handler.HANDLER_IS_HAPPY, None, None)
  58.  
  59. HANDLERS = {
  60.     'BeagleLiveHandler': {
  61.         'name': _('Beagle Live'),
  62.         'description': _('Search all of your documents (using Beagle), as you type'),
  63.         'requirements': _check_requirements,
  64.         'version': VERSION } }
  65. TYPES = {
  66.     'Contact': {
  67.         'name': ('fixme:FileAs',),
  68.         'action': 'evolution %(uri)s',
  69.         'icon': 'stock_contact',
  70.         'description': _('Edit contact %s') % '<b>%(name)s</b>',
  71.         'category': 'people' },
  72.     'MailMessage': {
  73.         'name': ('dc:title', 'parent:dc:title'),
  74.         'action': 'evolution %(uri)s',
  75.         'icon': 'stock_mail',
  76.         'extra': {
  77.             'sender': ('fixme:from_name', 'parent:fixme:from_name') },
  78.         'description': _('From %s') % '<i>%(sender)s</i>' + '\n<b>%(name)s</b>',
  79.         'category': 'emails' },
  80.     'File': {
  81.         'name': ('beagle:ExactFilename',),
  82.         'action': (lambda d: gnome.url_show(d['uri'])),
  83.         'icon': 'stock_new',
  84.         'description': _('Open %s') % '<b>%(name)s</b>',
  85.         'snippet': True,
  86.         'category': 'files' },
  87.     'FeedItem': {
  88.         'name': ('dc:title',),
  89.         'action': (lambda d: gnome.url_show(d['identifier'])),
  90.         'icon': 'stock_news',
  91.         'description': _('News from %s') % '<i>%(publisher)s</i>' + '\n<b>%(name)s</b>',
  92.         'snippet': True,
  93.         'category': 'news',
  94.         'extra': {
  95.             'publisher': ('dc:publisher',),
  96.             'identifier': ('dc:identifier',) } },
  97.     'Note': {
  98.         'name': ('dc:title',),
  99.         'action': 'tomboy --open-note %(uri)s',
  100.         'icon': 'stock_notes',
  101.         'description': _('Note: %s') % '<b>%(name)s</b>',
  102.         'snippet': True,
  103.         'category': 'notes' },
  104.     'IMLog': {
  105.         'name': ('fixme:speakingto',),
  106.         'extra': {
  107.             'client': ('fixme:client',) },
  108.         'action': "beagle-imlogviewer --client %(client)s --highlight-search '%(text)s' %(uri)s",
  109.         'icon': 'im',
  110.         'description': _('With %s') % '<b>%(name)s</b>',
  111.         'snippet': True,
  112.         'category': 'conversations' },
  113.     'Calendar': {
  114.         'name': ('fixme:summary',),
  115.         'action': 'evolution %(uri)s',
  116.         'icon': 'stock_calendar',
  117.         'description': _('Calendar: %s') % '<b>%(name)s</b>',
  118.         'category': 'documents' },
  119.     'WebHistory': {
  120.         'name': ('dc:title',),
  121.         'action': (lambda d: gnome.url_show(d['uri'])),
  122.         'icon': 'stock_bookmark',
  123.         'description': _('Open History Item %s') % '<i>%(name)s</i>' + '\n%(escaped_uri)s',
  124.         'category': 'web' } }
  125. for key, val in TYPES.items():
  126.     if 'snippet' in val and val['snippet']:
  127.         val['description'] += '%(snippet)s'
  128.     
  129.  
  130.  
  131. class BeagleLiveMatch(deskbar.Match.Match):
  132.     
  133.     def __init__(self, handler, result = None, **args):
  134.         '''
  135. \t\tresult: a dict containing:
  136. \t\t\t"name" : a name sensible to display for this match
  137. \t\t\t"uri": the uri of the match as provided by the beagled \'Uri: \'-field
  138. \t\t\t"type": One of the types listed in the TYPES dict
  139.  
  140. \t\t-- and optionally extra fields as provided by the corresponding entry in TYPES.
  141. \t\tFx. "MailMessage". has an extra "sender" entry.
  142. \t\t'''
  143.         deskbar.Match.Match.__init__(self, handler, name = result['name'], **args)
  144.         self.result = result
  145.         action = TYPES[self.result['type']]['action']
  146.         if not callable(action) and action.startswith('beagle-imlogviewer'):
  147.             self.result['uri'] = gnomevfs.get_local_path_from_uri(self.result['uri'])
  148.         
  149.         self._icon = None
  150.         if result['type'] == 'File':
  151.             
  152.             try:
  153.                 self._icon = deskbar.Utils.load_icon_for_file(result['uri'])
  154.             except Exception:
  155.                 pass
  156.             except:
  157.                 None<EXCEPTION MATCH>Exception
  158.             
  159.  
  160.         None<EXCEPTION MATCH>Exception
  161.         if self._icon == None:
  162.             self._icon = handler.ICONS[result['type']]
  163.         
  164.  
  165.     
  166.     def get_category(self):
  167.         
  168.         try:
  169.             return TYPES[self.result['type']]['category']
  170.         except:
  171.             return 'default'
  172.  
  173.  
  174.     
  175.     def get_name(self, text = None):
  176.         if text:
  177.             self.result['text'] = text
  178.             self.result['text'] = self.result['text'].replace("'", "\\'")
  179.         
  180.         return self.result
  181.  
  182.     
  183.     def get_verb(self):
  184.         return TYPES[self.result['type']]['description']
  185.  
  186.     
  187.     def action(self, text = None):
  188.         self.get_name(text)
  189.         action = TYPES[self.result['type']]['action']
  190.         if callable(action):
  191.             print 'BeagleLive url_show()', self.result
  192.             action(self.result)
  193.         else:
  194.             action = action % self.result
  195.             args = action.split(' ')
  196.             print 'BeagleLive spawning:', action, args
  197.             gobject.spawn_async(args, flags = gobject.SPAWN_SEARCH_PATH)
  198.  
  199.     
  200.     def get_hash(self, text = None):
  201.         if 'uri' in self.result:
  202.             return self.result['uri']
  203.         
  204.  
  205.  
  206.  
  207. class SnippetContainer:
  208.     
  209.     def __init__(self, hit):
  210.         self.hit = hit
  211.         self.snippet = None
  212.  
  213.  
  214.  
  215. class BeagleLiveHandler(deskbar.Handler.SignallingHandler):
  216.     
  217.     def __init__(self):
  218.         deskbar.Handler.SignallingHandler.__init__(self, ('system-search', 'best'))
  219.         self.counter = { }
  220.         self.snippets = { }
  221.         self.set_delay(500)
  222.  
  223.     
  224.     def initialize(self):
  225.         self.beagle = beagle.Client()
  226.         self.ICONS = self._BeagleLiveHandler__load_icons()
  227.  
  228.     
  229.     def __load_icons(self):
  230.         res = { }
  231.         for t in TYPES.iterkeys():
  232.             icon_file = TYPES[t]['icon']
  233.             if not icon_file:
  234.                 continue
  235.             
  236.             res[t] = deskbar.Utils.load_icon(icon_file)
  237.         
  238.         return res
  239.  
  240.     
  241.     def query(self, qstring):
  242.         beagle_query = beagle.Query()
  243.         beagle_query.add_text(qstring)
  244.         beagle_query.connect('hits-added', self.hits_added, qstring, MAX_RESULTS)
  245.         
  246.         try:
  247.             self.beagle.send_request_async(beagle_query)
  248.         except:
  249.             return None
  250.  
  251.         self.counter[qstring] = { }
  252.  
  253.     
  254.     def _on_snippet_received(self, request, response, query, container, qstring, qmax):
  255.         container.snippet = response.get_snippet()
  256.         self._on_hit_added(query, container, qstring, qmax)
  257.  
  258.     
  259.     def _on_snippet_closed(self, request, query, container, qstring, qmax):
  260.         if container.snippet == None:
  261.             self._on_hit_added(query, container, qstring, qmax)
  262.         
  263.         container.hit.unref()
  264.  
  265.     
  266.     def _on_hit_added(self, query, hit, qstring, qmax):
  267.         fire_signal = False
  268.         snippet = None
  269.         if hit.__class__ == SnippetContainer:
  270.             hit = hit.hit
  271.             snippet = hit.snippet
  272.             fire_signal = True
  273.         
  274.         if hit.get_type() not in self.counter[qstring]:
  275.             self.counter[qstring][hit.get_type()] = 0
  276.         
  277.         if self.counter[qstring][hit.get_type()] >= qmax:
  278.             return None
  279.         
  280.         hit_type = TYPES[hit.get_type()]
  281.         result = {
  282.             'uri': hit.get_uri(),
  283.             'type': hit.get_type() }
  284.         if snippet != None:
  285.             tmp = re.sub('<.*?>', '', snippet)
  286.             tmp = re.sub('</.*?>', '', tmp)
  287.             result['snippet'] = "\n<span foreground='grey' size='small'>%s</span>" % cgi.escape(tmp)
  288.         else:
  289.             result['snippet'] = ''
  290.         name = None
  291.         for prop in hit_type['name']:
  292.             
  293.             try:
  294.                 name = hit.get_properties(prop)[0]
  295.             except:
  296.                 
  297.                 try:
  298.                     name = hit.get_property(prop)
  299.  
  300.  
  301.             if name != None:
  302.                 result['name'] = cgi.escape(name)
  303.                 break
  304.                 continue
  305.         
  306.         if name == None:
  307.             result['name'] = _('?')
  308.         
  309.         if 'extra' in hit_type:
  310.             for prop, keys in hit_type['extra'].items():
  311.                 val = None
  312.                 for key in keys:
  313.                     
  314.                     try:
  315.                         val = hit.get_properties(key)[0]
  316.                     except:
  317.                         
  318.                         try:
  319.                             val = hit.get_property(key)
  320.  
  321.  
  322.                     if val != None:
  323.                         if prop == 'uri' or prop == 'identifier':
  324.                             result[prop] = val
  325.                             result['escaped_' + prop] = cgi.escape(val)
  326.                         else:
  327.                             result[prop] = cgi.escape(val)
  328.                         break
  329.                         continue
  330.                 
  331.                 if val == None:
  332.                     result[prop] = _('?')
  333.                     continue
  334.             
  335.         
  336.         self.counter[qstring][hit.get_type()] = self.counter[qstring][hit.get_type()] + 1
  337.         match = BeagleLiveMatch(self, result)
  338.         if fire_signal:
  339.             self.emit_query_ready(qstring, [
  340.                 match])
  341.         else:
  342.             return match
  343.  
  344.     
  345.     def hits_added(self, query, response, qstring, qmax):
  346.         hit_matches = []
  347.         for hit in response.get_hits():
  348.             if hit.get_type() not in TYPES:
  349.                 print 'WARNING: Beagle live seen an unknown type:', hit.get_type()
  350.                 continue
  351.             
  352.             if 'snippet' in TYPES[hit.get_type()] and TYPES[hit.get_type()]['snippet']:
  353.                 req = beagle.SnippetRequest()
  354.                 req.set_query(query)
  355.                 req.set_hit(hit)
  356.                 container = SnippetContainer(hit)
  357.                 hit.ref()
  358.                 req.connect('response', self._on_snippet_received, query, container, qstring, qmax)
  359.                 req.connect('closed', self._on_snippet_closed, query, container, qstring, qmax)
  360.                 self.beagle.send_request_async(req)
  361.                 continue
  362.             
  363.             match = self._on_hit_added(query, hit, qstring, qmax)
  364.             if match != None:
  365.                 hit_matches.append(match)
  366.                 continue
  367.         
  368.         self.emit_query_ready(qstring, hit_matches)
  369.  
  370.  
  371.