class ZeitgeistPlugin(PluginClass): plugin_info = { 'name': _('Log events with Zeitgeist'), # T: plugin name 'description': _('Pushes events to the Zeitgeist daemon.'), # T: plugin description 'author': 'Marcel Stimberg', 'help': 'Plugins:Log events with Zeitgeist', } @classmethod def check_dependencies(klass): has_zeitgeist = not ZeitgeistClient is None return has_zeitgeist, [('libzeitgeist', has_zeitgeist, False)] def __init__(self, config=None): PluginClass.__init__(self, config) try: self.zeitgeist_client = ZeitgeistClient() self.zeitgeist_client.register_data_source( 'application://zim.desktop', 'Zim', _('Zim Desktop Wiki'), []) # T: short description of zim except RuntimeError as e: logger.exception( 'Loading zeitgeist client failed, will not log events') self.zeitgeist_client = None def create_and_send_event(self, page, event_type): if not self.zeitgeist_client: return if not hasattr(page, 'source') \ or not isinstance(page.source, File): return uri = page.source.uri origin = Gio.File(uri).get_parent().get_uri() text = _('Wiki page: %s') % page.name # T: label for how zim pages show up in the recent files menu, %s is the page name subject = Subject.new_for_values( mimetype='text/x-zim-wiki', uri=uri, origin=origin, interpretation=Interpretation.TEXT_DOCUMENT, manifestation=Manifestation.FILE_DATA_OBJECT, text=text) event = Event.new_for_values(actor='application://zim.desktop', interpretation=event_type, manifestation=Manifestation.USER_ACTIVITY, subjects=[ subject, ]) self.zeitgeist_client.insert_event(event)
class Zeitgeist(EventPlugin): PLUGIN_ID = "zeitgeist" PLUGIN_NAME = _("Event Logging") PLUGIN_DESC = _("Sends song events to the Zeitgeist event logging " "service.") PLUGIN_ICON = Icons.NETWORK_WORKGROUP def enabled(self): self.client = ZeitgeistClient() self.__stopped_by_user = False def disabled(self): del self.client del self.__stopped_by_user def plugin_on_song_started(self, song): if self.__stopped_by_user: manifestation = Manifestation.USER_ACTIVITY else: manifestation = Manifestation.SCHEDULED_ACTIVITY self.__send_event(song, Interpretation.ACCESS_EVENT, manifestation) def plugin_on_song_ended(self, song, stopped): self.__stopped_by_user = stopped if stopped: manifestation = Manifestation.USER_ACTIVITY else: manifestation = Manifestation.SCHEDULED_ACTIVITY self.__send_event(song, Interpretation.LEAVE_EVENT, manifestation) def __send_event(self, song, interpretation, manifestation): if not song: return print_d("event: interpretation=%s, manifestation=%s" % (interpretation.__name__, manifestation.__name__)) subject = Subject.new_for_values( uri=song("~uri"), interpretation=Interpretation.AUDIO, manifestation=Manifestation.FILE_DATA_OBJECT, ) event = Event.new_for_values( timestamp=int(time.time() * 1000), interpretation=interpretation, manifestation=manifestation, actor="application://quodlibet.desktop", subjects=[subject] ) self.client.insert_event(event)
class ZeitgeistLogger(object): """A class that logs zeitgeist events.""" client = None def __init__(self): """Initialize this instance.""" try: from zeitgeist.client import ZeitgeistClient self.client = ZeitgeistClient() logger.info("Zeitgeist support initialized.") except Exception: logger.exception("Zeitgeist support not started:") def log(self, event): """Log a zeitgeist event.""" d = Deferred() if self.client: logger.info("Logging Zeitgeist event: %r", event) self.client.insert_event(event, d.callback, d.errback) else: d.callback([]) return d
class Zeitgeist(modules.ThreadedModule): def __init__(self): """ Constructor """ handlers = { consts.MSG_EVT_APP_QUIT: self.onModUnloaded, consts.MSG_EVT_NEW_TRACK: self.onNewTrack, consts.MSG_EVT_MOD_LOADED: self.onModLoaded, consts.MSG_EVT_APP_STARTED: self.onModLoaded, consts.MSG_EVT_MOD_UNLOADED: self.onModUnloaded, } modules.ThreadedModule.__init__(self, handlers) # --== Message handlers ==-- def onModLoaded(self): """ The module has been loaded """ self.client = None try: from zeitgeist.client import ZeitgeistClient self.client = ZeitgeistClient() except: logger.info('[%s] Could not create Zeitgeist client\n\n%s' % (MOD_INFO[modules.MODINFO_NAME], traceback.format_exc())) def onModUnloaded(self): """ The module has been unloaded """ self.client = None def onNewTrack(self, track): """ Send track information to Zeitgeist """ import mimetypes, os.path from zeitgeist.datamodel import Event, Subject, Interpretation, Manifestation mime, encoding = mimetypes.guess_type(track.getFilePath(), strict=False) subject = Subject.new_for_values( uri = os.path.dirname(track.getURI()), text = track.getTitle() + ' - ' + track.getArtist() + ' - ' + track.getExtendedAlbum(), mimetype = mime, manifestation = unicode(Manifestation.FILE), interpretation = unicode(Interpretation.AUDIO), ) if hasattr(Interpretation, 'ACCESS_EVENT'): eventType = Interpretation.ACCESS_EVENT else: eventType = Interpretation.OPEN_EVENT event = Event.new_for_values( actor = "application://decibel-audio-player.desktop", subjects = [subject,], interpretation = eventType, ) self.client.insert_event(event)
class Zeitgeist(modules.ThreadedModule): def __init__(self): """ Constructor """ handlers = { consts.MSG_EVT_APP_QUIT: self.onModUnloaded, consts.MSG_EVT_NEW_TRACK: self.onNewTrack, consts.MSG_EVT_MOD_LOADED: self.onModLoaded, consts.MSG_EVT_APP_STARTED: self.onModLoaded, consts.MSG_EVT_MOD_UNLOADED: self.onModUnloaded, } modules.ThreadedModule.__init__(self, handlers) # --== Message handlers ==-- def onModLoaded(self): """ The module has been loaded """ self.client = None try: from zeitgeist.client import ZeitgeistClient from zeitgeist.datamodel import Event self.client = ZeitgeistClient() if self.client.get_version() >= [0, 3, 2, 999]: self.client.register_data_source("Pogo", "Pogo", "Play your music", [Event.new_for_values(actor="application://pogo.desktop")]) except: logger.info('[%s] Could not create Zeitgeist client\n\n%s' % (MOD_INFO[modules.MODINFO_NAME], traceback.format_exc())) def onModUnloaded(self): """ The module has been unloaded """ self.client = None def onNewTrack(self, track): """ Send track information to Zeitgeist """ if self.client is None: return from zeitgeist.datamodel import Interpretation if hasattr(Interpretation, 'ACCESS_EVENT'): event_type = Interpretation.ACCESS_EVENT else: event_type = Interpretation.OPEN_EVENT self.send_to_zeitgeist(track, event_type) def send_to_zeitgeist(self, track, event_type): """ Other players (e.g. Rhythmbox) log the playing of individual files, but we want to log albums. Maybe it would be better to log individual files, but then we would have to distinguish between Manifestation.USER_ACTIVITY and Manifestation.SCHEDULED_ACTIVITY. Another possible addition would be logging Interpretation.LEAVE_EVENT. """ import mimetypes, os.path from zeitgeist.datamodel import Event, Subject, Interpretation, Manifestation mime, encoding = mimetypes.guess_type(track.getFilePath(), strict=False) title = track.getTitle() album = track.getAlbum() artist = track.getArtist() uri = track.getURI() origin = os.path.dirname(uri) # Handle "unknown" tags if 'unknown' in title.lower(): title = track.getBasename() if 'unknown' in album.lower(): album = '' if 'unknown' in artist.lower(): artist = '' subject = Subject.new_for_values( uri = origin, text = ' - '.join([part for part in [artist, album] if part]), mimetype = mime, manifestation = unicode(Manifestation.FILE_DATA_OBJECT), interpretation = unicode(Interpretation.AUDIO), origin = origin, ) event = Event.new_for_values( actor = "application://pogo.desktop", subjects = [subject,], interpretation = unicode(event_type), timestamp = int(time.time() * 1000), ) self.client.insert_event(event)
event_manifestation = { 'user' : Manifestation.USER_ACTIVITY, 'heuristic' : Manifestation.HEURISTIC_ACTIVITY, 'scheduled' : Manifestation.SCHEDULED_ACTIVITY, 'world' : Manifestation.WORLD_ACTIVITY, 'system' : Manifestation.SYSTEM_NOTIFICATION }[event_manif] subject = Subject.new_for_values( uri=unicode(uri), text=unicode(uri.rpartition('/')[2]), interpretation=unicode(subject_interpretation), manifestation=unicode(subject_manifestation), origin=unicode(uri.rpartition('/')[0]), mimetype=unicode(mimetype) ) # print "subject: %r" % subject event = Event.new_for_values( timestamp=int(time.time()*1000), interpretation=unicode(event_interpretation), manifestation=unicode(event_manifestation), actor=unicode(event_actor), subjects=[subject,] ) # print "event: %r" % event zeitgeistclient.insert_event(event) # print "insert done"