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, ui):
        PluginClass.__init__(self, ui)
        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, e:
            logger.exception(
                'Loading zeitgeist client failed, will not log events')
            self.zeitgeist_client = None
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)
Example #3
0
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)
 def __init__(self, ui):
     PluginClass.__init__(self, ui)
     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, e:
         logger.exception(
             'Loading zeitgeist client failed, will not log events')
         self.zeitgeist_client = None
Example #5
0
    def initialize(self):
        '''
        Inicializes the Zeitgeist client and registers itself as a Zeitgeist
        data source.
        '''
        self.logger.info('Initialiazing zeitgeist plugin')
        editor = self.locator.get_service('editor')
        editor.fileOpened.connect(self._zeitgeist_log_file_open)
        editor.fileSaved.connect(self._zeitgeist_log_file_modified)

        #initialize zeitgeist client
        self.zeitgeist = ZeitgeistClient()
        self._register_data_source()
Example #6
0
def push_to_zeitgeist(commits):
    ZG = ZeitgeistClient()
    commits = commits
    def error_handler(error):
        print "===> ERROR:", error
    def ids_reply_handler(ids):
        global commits
        print len(commits)
        if len(commits) > 0:
            events = format_events(commits[0:100])
            commits = commits[100:]
            time.sleep(0.5)
            ZG.insert_events(events, ids_reply_handler, error_handler)
    events = format_events(commits[0:100])
    commits = commits[100:]
    ZG.insert_events(events, ids_reply_handler, error_handler)
Example #7
0
 def _get_client(self, bus_name, app_uri, app_name, app_description,
                 event_template):
     client = None
     try:
         client = ZeitgeistClient()
         if hasattr(self.client, "register_data_source"):
             client.register_data_source(
                 bus_name,
                 app_name or bus_name,
                 app_description or bus_name,
                 event_template or \
                 [Event.new_for_values(actor=app_uri)])
         self.log(logging.DEBUG, 'your client was set')
     except Exception as e:
         self.log(logging.ERROR, 'S.O.S: %s', e)
         raise
     return client
Example #8
0
 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:")
Example #9
0
    def __init__(self, log=log):
        self.log = log
        self._zclient = ZeitgeistClient()
        self._zdclient = ZeitgeistDBusInterface()
        self._database = DesktopDatabase(DATABASE_NAME, create=True)

        self._user = os.environ.get('USERNAME')
        self._machine = os.uname()
Example #10
0
 def __init__(self, ui):
     PluginClass.__init__(self, ui)
     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, e:
         logger.exception('Loading zeitgeist client failed, will not log events')
         self.zeitgeist_client = None
 def _get_client(self, bus_name, app_uri,
                 app_name, app_description,
                 event_template):
     client = None
     try:
         client = ZeitgeistClient()
         if hasattr(self.client, "register_data_source"):
             client.register_data_source(
                 bus_name,
                 app_name or bus_name,
                 app_description or bus_name,
                 event_template or \
                 [Event.new_for_values(actor=app_uri)])
         self.log(logging.DEBUG, 'your client was set')
     except Exception as e:
         self.log(logging.ERROR, 'S.O.S: %s', e)
         raise
     return client
    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()))
Example #13
0
class CardapioPlugin(CardapioPluginInterface):

	author             = _('Cardapio Team')
	name               = _('Recent documents (simple)')
	description        = _('Search for your most recently used files.')
	icon               = 'document-open-recent'

	url                = ''
	help_text          = ''
	version            = '0.996'

	plugin_api_version = 1.40

	search_delay_type  = 'local'

	default_keyword    = 'zgeist'

	category_count     = 1
	category_name      = _('Recent Documents')
	category_icon      = 'document-open-recent'
	category_tooltip   = _('Files that you have used recently')
	hide_from_sidebar  = False


	def __init__(self, cardapio_proxy, category): 

		self.c = cardapio_proxy

		self.loaded = False

		try:
			import urllib2, os
			from zeitgeist.client import ZeitgeistClient
			from zeitgeist import datamodel

		except Exception, exception:
			self.c.write_to_log(self, 'Could not import certain modules', is_error = True)
			self.c.write_to_log(self, exception, is_error = True)
			return
		
		self.urllib2   = urllib2
		self.os        = os
		self.datamodel = datamodel

		if 'ZeitgeistClient' not in locals():
			self.c.write_to_log(self, 'Could not import Zeitgeist', is_error = True)
			return

		try:
			self.zg = ZeitgeistClient()
		except Exception, exception:
			self.c.write_to_log(self, 'Could not start Zeitgeist', is_error = True)
			self.c.write_to_log(self, exception, is_error = True)
			return 
Example #14
0
    def setUp(self, database_path=None):
        assert self.daemon is None
        assert self.client is None
        self.env = os.environ.copy()
        self.datapath = tempfile.mkdtemp(prefix="zeitgeist.datapath.")
        self.env.update({
            "ZEITGEIST_DATABASE_PATH": database_path or ":memory:",
            "ZEITGEIST_DATA_PATH": self.datapath,
            "XDG_CACHE_HOME": os.path.join(self.datapath, "cache"),
        })
        self.spawn_daemon()

        # hack to clear the state of the interface
        ZeitgeistDBusInterface._ZeitgeistDBusInterface__shared_state = {}

        # Replace the bus connection with a private one for each test case,
        # so that they don't share signals or other state
        _set_bus(dbus.SessionBus(private=True))
        get_bus().set_exit_on_disconnect(False)

        self.client = ZeitgeistClient()
Example #15
0
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
Example #16
0
    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()))
Example #17
0
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, ui):
        PluginClass.__init__(self, ui)
        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, e:
            logger.exception('Loading zeitgeist client failed, will not log events')
            self.zeitgeist_client = None
Example #18
0
    def log_install_event(self, desktop_file):
        """Logs an install event on Zeitgeist"""
        if not HAVE_MODULE:
            LOG.warn("No zeitgeist support, impossible to log event")
            return False

        if not desktop_file or not len(desktop_file):
            LOG.warn("Invalid desktop file provided, impossible to log event")
            return False

        subject = self.__create_app_subject(desktop_file)

        subject.text = "Installed with " + self.distro.get_app_name()
        event = self.__create_user_event()
        event.interpretation = ZeitgeistDataModel.Interpretation.EVENT_INTERPRETATION.CREATE_EVENT
        event.append_subject(subject)
        ZeitgeistClient().insert_event(event)

        subject.text = "Accessed by " + self.distro.get_app_name()
        event = self.__create_user_event()
        event.interpretation = ZeitgeistDataModel.Interpretation.EVENT_INTERPRETATION.ACCESS_EVENT
        event.append_subject(subject)
        ZeitgeistClient().insert_event(event)
        return True
	def setUp(self, database_path=None):
		assert self.daemon is None
		assert self.client is None
		self.env = os.environ.copy()
		self.datapath = tempfile.mkdtemp(prefix="zeitgeist.datapath.")
		self.env.update({
			"ZEITGEIST_DATABASE_PATH": database_path or ":memory:",
			"ZEITGEIST_DATA_PATH": self.datapath,
			"XDG_CACHE_HOME": os.path.join(self.datapath, "cache"),
		})
		self.spawn_daemon()
		
		# hack to clear the state of the interface
		ZeitgeistDBusInterface._ZeitgeistDBusInterface__shared_state = {}
		
		# Replace the bus connection with a private one for each test case,
		# so that they don't share signals or other state
		_set_bus(dbus.SessionBus(private=True))
		get_bus().set_exit_on_disconnect(False)
		
		self.client = ZeitgeistClient()
    def zclient(
            self,
            bus_name='im.pidgin.purple.PurpleInterface',
            app_uri='application://pidgin.desktop',
            app_name='Pidgin',
            app_description="Pidgin is an easy to use and free chat client used by millions. Connect to AIM, MSN, Yahoo, and more chat networks all at once.",
            event_template=None):

        if self._client:
            return self._client

        try:
            self._client = ZeitgeistClient()
            if hasattr(self._client, "register_data_source"):
                self.client.register_data_source(
                    bus_name,
                    app_name or bus_name,
                    app_description or bus_name,
                    event_template or \
                    [Event.new_for_values(actor=app_uri)])
        except:
            pass

        return self._client
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)
Example #22
0
class CardapioPlugin(CardapioPluginInterface):

    author = _('Cardapio Team')
    name = _('Recent documents (categorized)')
    description = _(
        'Search for your most recently used files, divided into categories depending on <i>when</i> they were last accessed.'
    )
    icon = 'document-open-recent'

    url = ''
    help_text = ''
    version = '0.996'

    plugin_api_version = 1.40

    search_delay_type = 'local'

    default_keyword = 'zgeist'

    category_count = 4
    category_name = [
        _('Today'), _('This week'),
        _('This month'),
        _('All time')
    ]
    category_icon = ['document-open-recent'] * 4
    category_tooltip = [
        _('Files you used today'),
        _('Files you used this week'),
        _('Files you used this month'),
        _('All other files')
    ]
    hide_from_sidebar = [False] * 4

    def __init__(self, cardapio_proxy, category):

        # NOTE: Right now Cardapio creates a separate instance for each
        # category. This is very wasteful! We should instead create a single
        # instance and pass the category to the search() method instead.

        self.c = cardapio_proxy

        self.loaded = False

        try:
            import urllib2, os
            from zeitgeist.client import ZeitgeistClient
            from zeitgeist import datamodel
            import time

        except Exception, exception:
            self.c.write_to_log(self,
                                'Could not import certain modules',
                                is_error=True)
            self.c.write_to_log(self, exception, is_error=True)
            return

        self.urllib2 = urllib2
        self.os = os
        self.datamodel = datamodel

        if 'ZeitgeistClient' not in locals():
            self.c.write_to_log(self,
                                'Could not import Zeitgeist',
                                is_error=True)
            return

        try:
            self.zg = ZeitgeistClient()
        except Exception, exception:
            self.c.write_to_log(self,
                                'Could not start Zeitgeist',
                                is_error=True)
            self.c.write_to_log(self, exception, is_error=True)
            return
def get_interface():
	global _zg
	if _zg is None:
		_zg = ZeitgeistClient()
        _zg.register_event_subclass(CustomEvent)
	return _zg
class SoftwareCenterZeitgeist():
    """ simple wrapper around zeitgeist """

    def __init__(self):
        try:
            self.zg_client = ZeitgeistClient()
        except Exception as e:
            logging.warn("can not get zeitgeist client: '%s'" % e)
            self.zg_client = None
        
    def get_usage_counter(self, application, callback, timerange=None):
        """Request the usage count as integer for the given application.
           When the request is there, "callback" is called. A optional
           timerange like [time.time(), time.time() - 30*24*60*60] can
           also be specified
        """
        # helper
        def _callback(event_ids):
            callback(len(event_ids))
        # no client or empty query -> empty result
        if not self.zg_client or not application:
            callback(0)
            return
        # the app we are looking for
        application = "application://"+application.split("/")[-1]
        # the event_templates
        e1 = Event.new_for_values(
            actor=application, interpretation=Interpretation.MODIFY_EVENT.uri)
        e2 = Event.new_for_values(
            actor=application, interpretation=Interpretation.CREATE_EVENT.uri)
        # run it
        self.zg_client.find_event_ids_for_templates(
            [e1, e2], _callback, timerange=timerange, num_events=0)
       
    def get_popular_mimetypes(self, callback, num=3):
        """ get the "num" (default to 3) most popular mimetypes based
            on the last 1000 events that zeitgeist recorded and
            call "callback" with [(count1, "mime1"), (count2, "mime2"), ...] 
            as arguement
        """
        def _callback(events):
            # gather
            mimetypes = {}
            for event in events:
                if event.subjects is None:
                    continue
                mimetype = event.subjects[0].mimetype
                if not mimetype in mimetypes:
                    mimetypes[mimetype] = 0
                mimetypes[mimetype] += 1
            # return early if empty
            results = []
            if not mimetypes:
                callback([])
            # convert to result and sort
            for k, v in mimetypes.items():
                results.append([v, k])
            results.sort(reverse = True)
            # tell the client about it
            callback(results[:num])
        # no zeitgeist
        if not self.zg_client:
            return
        # trigger event (actual processing is done in _callback)
        # FIXME: investigate how result_type MostRecentEvents or
        #        MostRecentSubjects would affect the results
        self.zg_client.find_events_for_templates(
            [], _callback, num_events=1000, 
            result_type=ResultType.MostRecentEvents)
Example #25
0
 def enabled(self):
     self.client = ZeitgeistClient()
     self.__stopped_by_user = False
Example #26
0
def get_interface():
    global _zg
    if _zg is None:
        _zg = ZeitgeistClient()
    _zg.register_event_subclass(CustomEvent)
    return _zg
 def __init__(self):
     try:
         self.zg_client = ZeitgeistClient()
     except Exception as e:
         logging.warn("can not get zeitgeist client: '%s'" % e)
         self.zg_client = None
Example #28
0
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.

import time
import rb

from gi.repository import GObject, Gio, GLib, Peas
from gi.repository import RB

from zeitgeist.client import ZeitgeistClient
from zeitgeist.datamodel import Event, Subject, Interpretation, Manifestation

try:
    IFACE = ZeitgeistClient()
except RuntimeError, e:
    print "Unable to connect to Zeitgeist, won't send events. Reason: '%s'" % e
    IFACE = None


class ZeitgeistPlugin(GObject.Object, Peas.Activatable):
    __gtype_name__ = 'ZeitgeistPlugin'
    object = GObject.property(type=GObject.Object)

    def __init__(self):
        GObject.Object.__init__(self)

    def do_activate(self):
        print "Loading Zeitgeist plugin..."
        if IFACE is not None:
Example #29
0
class RemoteTestCase(unittest.TestCase):
    """
	Helper class to implement unit tests against a
	remote Zeitgeist process
	"""
    @staticmethod
    def _get_pid(matching_string):
        p1 = Popen(["pgrep", "-x", "zeitgeist-daemo"],
                   stdout=PIPE,
                   stderr=PIPE)
        out = p1.communicate()[0]
        pid = out.decode().split('\n')[0]

        p2 = Popen(["ps", "--no-headers", "-fp", pid],
                   stderr=PIPE,
                   stdout=PIPE)
        pid_line = p2.communicate()[0].decode()

        return pid_line

    @staticmethod
    def _safe_start_subprocess(cmd, env, timeout=1, error_callback=None):
        """ starts `cmd` in a subprocess and check after `timeout`
		if everything goes well"""
        args = {'env': env}
        if not '--verbose-subprocess' in sys.argv:
            args['stderr'] = PIPE
            args['stdout'] = PIPE
        process = Popen(cmd, **args)
        # give the process some time to wake up
        time.sleep(timeout)
        error = process.poll()
        if error:
            cmd = " ".join(cmd)
            error = "'%s' exits with error %i." % (cmd, error)
            if error_callback:
                error += " *** %s" % error_callback(*process.communicate())
            raise RuntimeError(error)
        return process

    @staticmethod
    def _safe_start_daemon(env=None, timeout=1):
        if env is None:
            env = os.environ.copy()

        def error_callback(stdout, stderr):
            stderr = stderr.decode()
            if "--replace" in stderr:
                return "%r | %s" % (
                    stderr,
                    RemoteTestCase._get_pid("./src/zeitgeist-daemon").replace(
                        "\n", "|"))
            else:
                return stderr

        return RemoteTestCase._safe_start_subprocess(
            ("./src/zeitgeist-daemon", "--no-datahub", "--log-level=DEBUG"),
            env, timeout, error_callback)

    def __init__(self, methodName):
        super(RemoteTestCase, self).__init__(methodName)
        self.daemon = None
        self.client = None

    def spawn_daemon(self):
        self.daemon = self._safe_start_daemon(env=self.env)

    def kill_daemon(self, kill_signal=signal.SIGKILL):
        os.kill(self.daemon.pid, kill_signal)
        return self.daemon.wait()

    def setUp(self, database_path=None):
        assert self.daemon is None
        assert self.client is None
        self.env = os.environ.copy()
        self.datapath = tempfile.mkdtemp(prefix="zeitgeist.datapath.")
        self.env.update({
            "ZEITGEIST_DATABASE_PATH": database_path or ":memory:",
            "ZEITGEIST_DATA_PATH": self.datapath,
            "XDG_CACHE_HOME": os.path.join(self.datapath, "cache"),
        })
        self.spawn_daemon()

        # hack to clear the state of the interface
        ZeitgeistDBusInterface._ZeitgeistDBusInterface__shared_state = {}

        # Replace the bus connection with a private one for each test case,
        # so that they don't share signals or other state
        _set_bus(dbus.SessionBus(private=True))
        get_bus().set_exit_on_disconnect(False)

        self.client = ZeitgeistClient()

    def tearDown(self):
        assert self.daemon is not None
        assert self.client is not None
        get_bus().close()
        self.kill_daemon()
        if 'ZEITGEIST_TESTS_KEEP_TMP' in os.environ:
            print('\n\nAll temporary files have been preserved in %s\n' \
             % self.datapath)
        else:
            shutil.rmtree(self.datapath)

    def insertEventsAndWait(self, events):
        """
		Insert a set of events and spin a mainloop until the async reply
		is back and return the result - which should be a list of ids.
		
		This method is basically just a hack to invoke an async method
		in a blocking manner.
		"""
        mainloop = self.create_mainloop()
        result = []

        def collect_ids_and_quit(ids):
            result.extend(ids)
            mainloop.quit()

        self.client.insert_events(events,
                                  ids_reply_handler=collect_ids_and_quit)
        mainloop.run()
        return result

    def findEventIdsAndWait(self, event_templates, **kwargs):
        """
		Do search based on event_templates and spin a mainloop until
		the async reply is back and return the result - which should be
		a list of ids.
		
		This method is basically just a hack to invoke an async method
		in a blocking manner.
		"""
        mainloop = self.create_mainloop()
        result = []

        def collect_ids_and_quit(ids):
            result.extend(ids)
            mainloop.quit()

        self.client.find_event_ids_for_templates(event_templates,
                                                 collect_ids_and_quit,
                                                 **kwargs)
        mainloop.run()
        return result

    def getEventsAndWait(self, event_ids):
        """
		Request a set of full events and spin a mainloop until the
		async reply is back and return the result - which should be a
		list of Events.
		
		This method is basically just a hack to invoke an async method
		in a blocking manner.
		"""
        mainloop = self.create_mainloop()
        result = []

        def collect_events_and_quit(events):
            for event in events:
                if event:
                    event[0][0] = int(event.id)
            result.extend(events)
            mainloop.quit()

        self.client.get_events(event_ids, collect_events_and_quit)
        mainloop.run()
        return result

    def findEventsForTemplatesAndWait(self, event_templates, **kwargs):
        """
		Execute ZeitgeistClient.find_events_for_templates in a blocking manner.
		"""
        mainloop = self.create_mainloop()
        result = []

        def collect_events_and_quit(events):
            result.extend(events)
            mainloop.quit()

        self.client.find_events_for_templates(event_templates,
                                              collect_events_and_quit,
                                              **kwargs)
        mainloop.run()
        return result

    def findEventsForValuesAndWait(self, *args, **kwargs):
        """
		Execute ZeitgeistClient.find_events_for_value in a blocking manner.
		"""
        mainloop = self.create_mainloop()
        result = []

        def collect_events_and_quit(events):
            result.extend(events)
            mainloop.quit()

        self.client.find_events_for_values(collect_events_and_quit, *args,
                                           **kwargs)
        mainloop.run()
        return result

    def deleteEventsAndWait(self, event_ids):
        """
		Delete events given by their id and run a loop until the result 
		containing a timetuple describing the interval of changes is
		returned.
		
		This method is basically just a hack to invoke an async method
		in a blocking manner.
		"""
        mainloop = self.create_mainloop()
        result = []

        def collect_timestamp_and_quit(timestamps):
            result.append(timestamps)
            mainloop.quit()

        self.client.delete_events(event_ids, collect_timestamp_and_quit)
        mainloop.run()
        return result[0]

    def findRelatedAndWait(self, subject_uris, num_events, result_type):
        """
		Find related subject uris to given uris and return them.
		
		This method is basically just a hack to invoke an async method
		in a blocking manner.
		"""
        mainloop = self.create_mainloop()
        result = []

        def callback(uri_list):
            result.extend(uri_list)
            mainloop.quit()

        self.client.find_related_uris_for_uris(subject_uris,
                                               callback,
                                               num_events=num_events,
                                               result_type=result_type)
        mainloop.run()
        return result

    @staticmethod
    def create_mainloop(timeout=5):
        class MainLoopWithFailure(object):
            """
			Remember to wrap callbacks using the asyncTestMethod decorator.
			"""
            def __init__(self):
                self._mainloop = GLib.MainLoop()
                self.failed = False

            def __getattr__(self, name):
                return getattr(self._mainloop, name)

            def fail(self, message):
                self.failed = True
                self.failure_message = message
                mainloop.quit()

            def run(self):
                assert self.failed is False
                self._mainloop.run()
                if self.failed:
                    raise AssertionError(self.failure_message)

        mainloop = MainLoopWithFailure()
        if timeout is not None:

            def cb_timeout():
                mainloop.fail("Timed out -- "
                              "operations not completed in reasonable time.")
                return False  # stop timeout from being called again

            # Add an arbitrary timeout so this test won't block if it fails
            GLib.timeout_add_seconds(timeout, cb_timeout)

        return mainloop

    @staticmethod
    def get_plain_event(ev):
        """
		Ensure that an Event instance is a Plain Old Python Object (popo),
		without DBus wrappings, etc.
		"""
        if not ev:
            return NULL_EVENT
        for subject in ev.subjects:
            if not subject.current_uri:
                subject.current_uri = subject.uri
            if not subject.current_origin:
                subject.current_origin = subject.origin
        popo = []
        popo.append(list(map(str, ev[0])))
        popo.append([list(map(str, subj)) for subj in ev[1]])
        # We need the check here so that if D-Bus gives us an empty
        # byte array we don't serialize the text "dbus.Array(...)".
        popo.append(str(ev[2]) if ev[2] else '')
        return popo

    def assertEventsEqual(self, ev1, ev2):
        ev1 = self.get_plain_event(Event(ev1))
        ev2 = self.get_plain_event(Event(ev2))
        if ev1 is not NULL_EVENT and ev2 is not NULL_EVENT:
            if (ev1[0][0] and not ev2[0][0]) or (ev2[0][0] and not ev1[0][0]):
                ev1[0][0] = ev2[0][0] = ""  # delete IDs
        self.assertEqual(ev1, ev2)
class SoftwareCenterZeitgeist():
    """ simple wrapper around zeitgeist """
    def __init__(self):
        try:
            self.zg_client = ZeitgeistClient()
        except Exception as e:
            logging.warn("can not get zeitgeist client: '%s'" % e)
            self.zg_client = None

    def get_usage_counter(self, application, callback, timerange=None):
        """Request the usage count as integer for the given application.
           When the request is there, "callback" is called. A optional
           timerange like [time.time(), time.time() - 30*24*60*60] can
           also be specified
        """

        # helper
        def _callback(event_ids):
            callback(len(event_ids))

        # no client or empty query -> empty result
        if not self.zg_client or not application:
            callback(0)
            return
        # the app we are looking for
        application = "application://" + application.split("/")[-1]
        # the event_templates
        e1 = Event.new_for_values(
            actor=application, interpretation=Interpretation.MODIFY_EVENT.uri)
        e2 = Event.new_for_values(
            actor=application, interpretation=Interpretation.CREATE_EVENT.uri)
        # run it
        self.zg_client.find_event_ids_for_templates([e1, e2],
                                                    _callback,
                                                    timerange=timerange,
                                                    num_events=0)

    def get_popular_mimetypes(self, callback, num=3):
        """ get the "num" (default to 3) most popular mimetypes based
            on the last 1000 events that zeitgeist recorded and
            call "callback" with [(count1, "mime1"), (count2, "mime2"), ...] 
            as arguement
        """
        def _callback(events):
            # gather
            mimetypes = {}
            for event in events:
                if event.subjects is None:
                    continue
                mimetype = event.subjects[0].mimetype
                if not mimetype in mimetypes:
                    mimetypes[mimetype] = 0
                mimetypes[mimetype] += 1
            # return early if empty
            results = []
            if not mimetypes:
                callback([])
            # convert to result and sort
            for k, v in mimetypes.items():
                results.append([v, k])
            results.sort(reverse=True)
            # tell the client about it
            callback(results[:num])

        # no zeitgeist
        if not self.zg_client:
            return
        # trigger event (actual processing is done in _callback)
        # FIXME: investigate how result_type MostRecentEvents or
        #        MostRecentSubjects would affect the results
        self.zg_client.find_events_for_templates(
            [],
            _callback,
            num_events=1000,
            result_type=ResultType.MostRecentEvents)
Example #31
0
import os
import time
import datetime
import logging

gaj_path = '/home/jendrik/projects/RedNotebook/ref/gnome-activity-journal/'
sys.path.insert(0, gaj_path)
sys.path.insert(0, os.path.join(gaj_path, 'src'))

import gtk
import gobject

try:
	import zeitgeist
	from zeitgeist.client import ZeitgeistClient
	CLIENT = ZeitgeistClient()
	if CLIENT.get_version() < [0, 3, 1, 99]:
		logging.info('Zeitgeist version too old. You need at least 0.3.2')
		zeitgeist = None
	else:
		from zeitgeist.datamodel import Event, Subject, Interpretation, Manifestation, \
										ResultType, TimeRange
		from widgets import Item
		from common import shade_gdk_color, combine_gdk_color, get_gtk_rgba
		from daywidgets import DayPartWidget
except ImportError, e:
	logging.info('Zeitgeist not available')
	zeitgeist = None
except RuntimeError, e:
	logging.error("Unable to connect to Zeitgeist: %s" % e)
	zeitgeist = None
Example #32
0
import os
import gtk
import gnome.ui
import atexit

try:
	from dockmanager.dockmanager import DockManagerItem, DockManagerSink, DOCKITEM_IFACE
	from zeitgeist.client import ZeitgeistClient
	from zeitgeist.datamodel import Event, Subject, Interpretation, Manifestation, StorageState
	from signal import signal, SIGTERM
	from sys import exit
except ImportError, e:
	exit()

try:
	CLIENT = ZeitgeistClient()
	version = [int(x) for x in CLIENT.get_version()]
	MIN_VERSION = [0, 3, 1, 0]
	if version < MIN_VERSION:
		print "PLEASE USE ZEITGEIST 0.3.1 or above"
		exit()

except RuntimeError, e:
	print "Unable to connect to Zeitgeist, won't send events. Reason: '%s'" %e
	exit()

INTERPRETATION = {
		"http://zeitgeist-project.com/schema/1.0/core#VisitEvent":"OPENED",
		"http://zeitgeist-project.com/schema/1.0/core#ModifyEvent":"SAVED",
		"http://zeitgeist-project.com/schema/1.0/core#CreateEvent":"CREATED"
		}
 def enabled(self):
     self.client = ZeitgeistClient()
     self.__stopped_by_user = False
Example #34
0
import os
import time
import datetime
import logging

gaj_path = '/home/jendrik/projects/RedNotebook/ref/gnome-activity-journal/'
sys.path.insert(0, gaj_path)
sys.path.insert(0, os.path.join(gaj_path, 'src'))

import gtk
import gobject

try:
    import zeitgeist
    from zeitgeist.client import ZeitgeistClient
    CLIENT = ZeitgeistClient()
    if CLIENT.get_version() < [0, 3, 1, 99]:
        logging.info('Zeitgeist version too old. You need at least 0.3.2')
        zeitgeist = None
    else:
        from zeitgeist.datamodel import Event, Subject, Interpretation, Manifestation, \
                                        ResultType, TimeRange
        from widgets import Item
        from common import shade_gdk_color, combine_gdk_color, get_gtk_rgba
        from daywidgets import DayPartWidget
except ImportError, e:
    logging.info('Zeitgeist not available')
    zeitgeist = None
except RuntimeError, e:
    logging.error("Unable to connect to Zeitgeist: %s" % e)
    zeitgeist = None
class RemoteTestCase (unittest.TestCase):
	"""
	Helper class to implement unit tests against a
	remote Zeitgeist process
	"""
	
	@staticmethod
	def _get_pid(matching_string):
		p1 = Popen(["ps", "aux"], stdout=PIPE, stderr=PIPE)
		p2 = Popen(["grep", matching_string], stdin=p1.stdout, stderr=PIPE, stdout=PIPE)
		return p2.communicate()[0]
		
	@staticmethod
	def _safe_start_subprocess(cmd, env, timeout=1, error_callback=None):
		""" starts `cmd` in a subprocess and check after `timeout`
		if everything goes well"""
		args = { 'env': env }
		if not '--verbose-subprocess' in sys.argv:
			args['stderr'] = PIPE
			args['stdout'] = PIPE
		process = Popen(cmd, **args)
		# give the process some time to wake up
		time.sleep(timeout)
		error = process.poll()
		if error:
			cmd = " ".join(cmd)
			error = "'%s' exits with error %i." %(cmd, error)
			if error_callback:
				error += " *** %s" %error_callback(*process.communicate())
			raise RuntimeError(error)
		return process
		
	@staticmethod
	def _safe_start_daemon(env=None, timeout=1):
		if env is None:
			env = os.environ.copy()
			
		def error_callback(stdout, stderr):
			if "--replace" in stderr:
				return "%r | %s" %(stderr, RemoteTestCase._get_pid(
					"./src/zeitgeist-daemon").replace("\n", "|"))
			else:
				return stderr
			
		return RemoteTestCase._safe_start_subprocess(
			("./src/zeitgeist-daemon", "--no-datahub", "--log-level=DEBUG"),
			env, timeout, error_callback)
	
	def __init__(self, methodName):
		super(RemoteTestCase, self).__init__(methodName)
		self.daemon = None
		self.client = None
	
	def spawn_daemon(self):
		self.daemon = self._safe_start_daemon(env=self.env)
	
	def kill_daemon(self, kill_signal=signal.SIGKILL):
		os.kill(self.daemon.pid, kill_signal)
		return self.daemon.wait()

	def setUp(self, database_path=None):
		assert self.daemon is None
		assert self.client is None
		self.env = os.environ.copy()
		self.datapath = tempfile.mkdtemp(prefix="zeitgeist.datapath.")
		self.env.update({
			"ZEITGEIST_DATABASE_PATH": database_path or ":memory:",
			"ZEITGEIST_DATA_PATH": self.datapath,
			"XDG_CACHE_HOME": os.path.join(self.datapath, "cache"),
		})
		self.spawn_daemon()
		
		# hack to clear the state of the interface
		ZeitgeistDBusInterface._ZeitgeistDBusInterface__shared_state = {}
		
		# Replace the bus connection with a private one for each test case,
		# so that they don't share signals or other state
		_set_bus(dbus.SessionBus(private=True))
		get_bus().set_exit_on_disconnect(False)
		
		self.client = ZeitgeistClient()
	
	def tearDown(self):
		assert self.daemon is not None
		assert self.client is not None
		get_bus().close()
		self.kill_daemon()
		if 'ZEITGEIST_TESTS_KEEP_TMP' in os.environ:
			print '\n\nAll temporary files have been preserved in %s\n' \
				% self.datapath
		else:
			shutil.rmtree(self.datapath)
	
	def insertEventsAndWait(self, events):
		"""
		Insert a set of events and spin a mainloop until the async reply
		is back and return the result - which should be a list of ids.
		
		This method is basically just a hack to invoke an async method
		in a blocking manner.
		"""
		mainloop = self.create_mainloop()
		result = []
		
		def collect_ids_and_quit(ids):
			result.extend(ids)
			mainloop.quit()
			
		self.client.insert_events(events,
					ids_reply_handler=collect_ids_and_quit)
		mainloop.run()
		return result
	
	def findEventIdsAndWait(self, event_templates, **kwargs):
		"""
		Do search based on event_templates and spin a mainloop until
		the async reply is back and return the result - which should be
		a list of ids.
		
		This method is basically just a hack to invoke an async method
		in a blocking manner.
		"""
		mainloop = self.create_mainloop()
		result = []
		
		def collect_ids_and_quit(ids):
			result.extend(ids)
			mainloop.quit()
			
		self.client.find_event_ids_for_templates(event_templates,
							collect_ids_and_quit,
							**kwargs)
		mainloop.run()
		return result
	
	def getEventsAndWait(self, event_ids):
		"""
		Request a set of full events and spin a mainloop until the
		async reply is back and return the result - which should be a
		list of Events.
		
		This method is basically just a hack to invoke an async method
		in a blocking manner.
		"""
		mainloop = self.create_mainloop()
		result = []
		
		def collect_events_and_quit(events):
			for event in events:
				if event:
					event[0][0] = int(event.id)
			result.extend(events)
			mainloop.quit()
			
		self.client.get_events(event_ids, collect_events_and_quit)
		mainloop.run()
		return result
	
	def findEventsForTemplatesAndWait(self, event_templates, **kwargs):
		"""
		Execute ZeitgeistClient.find_events_for_templates in a blocking manner.
		"""
		mainloop = self.create_mainloop()
		result = []
		
		def collect_events_and_quit(events):
			result.extend(events)
			mainloop.quit()
		
		self.client.find_events_for_templates(
			event_templates, collect_events_and_quit, **kwargs)
		mainloop.run()
		return result

	def findEventsForValuesAndWait(self, *args, **kwargs):
		"""
		Execute ZeitgeistClient.find_events_for_value in a blocking manner.
		"""
		mainloop = self.create_mainloop()
		result = []
		
		def collect_events_and_quit(events):
			result.extend(events)
			mainloop.quit()
		
		self.client.find_events_for_values(
			collect_events_and_quit, *args, **kwargs)
		mainloop.run()
		return result
	
	def deleteEventsAndWait(self, event_ids):
		"""
		Delete events given by their id and run a loop until the result 
		containing a timetuple describing the interval of changes is
		returned.
		
		This method is basically just a hack to invoke an async method
		in a blocking manner.
		"""
		mainloop = self.create_mainloop()
		result = []
		
		def collect_timestamp_and_quit(timestamps):
			result.append(timestamps)
			mainloop.quit()
		
		self.client.delete_events(event_ids, collect_timestamp_and_quit)
		mainloop.run()
		return result[0]
		
	def findRelatedAndWait(self, subject_uris, num_events, result_type):
		"""
		Find related subject uris to given uris and return them.
		
		This method is basically just a hack to invoke an async method
		in a blocking manner.
		"""
		mainloop = self.create_mainloop()
		result = []
		
		def callback(uri_list):
			result.extend(uri_list)
			mainloop.quit()
		
		self.client.find_related_uris_for_uris(subject_uris, callback,
			num_events=num_events, result_type=result_type)
		mainloop.run()
		return result
	
	@staticmethod
	def create_mainloop(timeout=5):
		
		class MainLoopWithFailure(object):
			"""
			Remember to wrap callbacks using the asyncTestMethod decorator.
			"""
			
			def __init__(self):
				self._mainloop = gobject.MainLoop()
				self.failed = False
			
			def __getattr__(self, name):
				return getattr(self._mainloop, name)
			
			def fail(self, message):
				self.failed = True
				self.failure_message = message
				mainloop.quit()
			
			def run(self):
				assert self.failed is False
				self._mainloop.run()
				if self.failed:
					raise AssertionError, self.failure_message
		
		mainloop = MainLoopWithFailure()
		if timeout is not None:
			def cb_timeout():
				mainloop.fail("Timed out -- "
					"operations not completed in reasonable time.")
				return False # stop timeout from being called again
			
			# Add an arbitrary timeout so this test won't block if it fails
			gobject.timeout_add_seconds(timeout, cb_timeout)
		
		return mainloop
	
	@staticmethod
	def get_plain_event(ev):
		"""
		Ensure that an Event instance is a Plain Old Python Object (popo),
		without DBus wrappings, etc.
		"""
		if not ev:
			return NULL_EVENT
		for subject in ev.subjects:
			if not subject.current_uri:
				subject.current_uri = subject.uri
			if not subject.current_origin:
				subject.current_origin = subject.origin
		popo = []
		popo.append(map(unicode, ev[0]))
		popo.append([map(unicode, subj) for subj in ev[1]])
		# We need the check here so that if D-Bus gives us an empty
		# byte array we don't serialize the text "dbus.Array(...)".
		popo.append(str(ev[2]) if ev[2] else u'')
		return popo
	
	def assertEventsEqual(self, ev1, ev2):
		ev1 = self.get_plain_event(Event(ev1))
		ev2 = self.get_plain_event(Event(ev2))
		if ev1 is not NULL_EVENT and ev2 is not NULL_EVENT:
			if (ev1[0][0] and not ev2[0][0]) or (ev2[0][0] and not ev1[0][0]):
				ev1[0][0] = ev2[0][0] = "" # delete IDs
		self.assertEqual(ev1, ev2)
            return getattr(self._extension, name)
        except TypeError:
            print _("Could not find extension method \"%s\"") % name
            if self._restarted:
                print _("Aborting.")
                self._show_error()
                raise SystemExit
            else:
                print _("Attempting to restart Zeitgeist...")
                self._restarted = True
                CLIENT._iface.Quit()
                self._extension.reconnect()
                return self.__getattr__(name)

try:
    CLIENT = ZeitgeistClient()
except RuntimeError, e:
    print "%s: %s" % (_("ERROR"), _("Unable to connect to Zeitgeist:"))
    print "%s" % e
    CLIENT = CLIENT_VERSION = CLIENT_EXTENSION = None
else:
    CLIENT_VERSION = CLIENT.get_version()
    CLIENT_EXTENSION = ClientExtension()

STORE = None

try:
    BUS = dbus.SessionBus()
except Exception:
    BUS = None
Example #37
0
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)
Example #38
0
class ZeitgeistIntegration(plugin.Plugin):
    '''
    Plugin that enables integration with the Zeitgeist Framework.
    '''

    def initialize(self):
        '''
        Inicializes the Zeitgeist client and registers itself as a Zeitgeist
        data source.
        '''
        self.logger.info('Initialiazing zeitgeist plugin')
        editor = self.locator.get_service('editor')
        editor.fileOpened.connect(self._zeitgeist_log_file_open)
        editor.fileSaved.connect(self._zeitgeist_log_file_modified)

        #initialize zeitgeist client
        self.zeitgeist = ZeitgeistClient()
        self._register_data_source()

    def finish(self):
        '''
        Deletes the reference to the Zeitgeist client.
        '''
        # remove zeitgeist client
        del self.zeitgeist

        self.logger.info('Shutting down zeitgeist plugin')

    def _register_data_source(self):
        '''
        Registers the plugin as a Zeitgeist data source.
        '''
        unique_id = 'org.ninja.ide'
        name = 'Ninja IDE'
        description = 'Very versatile Python IDE'

        # Describe what sort of events will be inserted
        templates = []
        for interp in (Interpretation.EVENT_INTERPRETATION.ACCESS_EVENT,
            Interpretation.EVENT_INTERPRETATION.MODIFY_EVENT,
            Interpretation.EVENT_INTERPRETATION.LEAVE_EVENT,
            Interpretation.EVENT_INTERPRETATION.CREATE_EVENT):

            event_template = Event()
            event_template.interpretation = interp
            event_template.manifestation = Manifestation.USER_ACTIVITY

            for subj_interp in (Interpretation.DOCUMENT.TEXT_DOCUMENT.
                PLAIN_TEXT_DOCUMENT.SOURCE_CODE,
                Interpretation.DOCUMENT.TEXT_DOCUMENT.PLAIN_TEXT_DOCUMENT):

                subject_template = Subject()
                subject_template.interpretation = subj_interp
                subject_template.manifestation = Manifestation.FILE_DATA_OBJECT
                event_template.append_subject(subject_template)

            templates.append(event_template)

        self.zeitgeist.register_data_source(unique_id, name, description,
            templates)

    def _zeitgeist_log_event(self, fileName, interpretation):
        '''
        Registers an event over the file with a given interpretation.
        '''
        fileName = unicode(fileName)

        self.logger.info('Inserting event for %s' % fileName)

        subject = Subject.new_for_values(
            uri='file://%s' % fileName,
            origin='file://%s' % path.dirname(fileName),
            text=path.basename(fileName))
        event = Event.new_for_values(
            timestamp=int(time.time() * 1000),
            interpretation=interpretation,
            manifestation=Manifestation.USER_ACTIVITY,
            actor='application://ninja-ide.desktop',
            subjects=[subject])

        def on_id_received(event_ids):
            self.logger.info(
                'Logged %r with event id %d.' % (fileName, event_ids[0]))

        self.zeitgeist.insert_events([event], on_id_received)

    def _zeitgeist_log_file_open(self, fileName):
        '''
        Registers an event everytime Ninja IDE opens a file.
        '''
        self._zeitgeist_log_event(unicode(fileName),
            Interpretation.EVENT_INTERPRETATION.ACCESS_EVENT)

    def _zeitgeist_log_file_modified(self, fileName):
        '''
        Registers an event everytime Ninja IDE modifies a file.
        '''
        self._zeitgeist_log_event(unicode(fileName),
            Interpretation.EVENT_INTERPRETATION.MODIFY_EVENT)
Example #39
0
#                                                                         #
# http://www.apache.org/licenses/LICENSE-2.0                              #
#                                                                         #
# Unless required by applicable law or agreed to in writing, software     #
# distributed under the License is distributed on an "AS IS" BASIS,       #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.#
# See the License for the specific language governing permissions and     #
# limitations under the License.                                          #
###########################################################################

import datetime, psutil, csv

from zeitgeist.client import ZeitgeistClient
from zeitgeist.datamodel import *

zeitgeist = ZeitgeistClient()
b_time = psutil.boot_time()

# Only the first time to write the header.
#with open('test.csv', 'wb') as csvfile:
    #writer = csv.writer(csvfile)
    #writer.writerow(('Boot time', 'Software', 'Time', 'Other Processes'))

def intToDate(timestamp):
    return datetime.datetime.fromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S')

def listProcess():
    pList = []
    for proc in psutil.process_iter():
      try:
	  pinfo = proc.as_dict(attrs=['pid', 'name'])
 def __init__(self):
     try:
         self.zg_client = ZeitgeistClient()
     except Exception as e:
         logging.warn("can not get zeitgeist client: '%s'" % e)
         self.zg_client = None
Example #41
0
import os
import subprocess
import sys
import time

CLIENT = None

try:
    from zeitgeist.client import ZeitgeistClient
    from zeitgeist.datamodel import Event, Subject, Interpretation, Manifestation
except ImportError:
    pass
else:
    try:
        CLIENT = ZeitgeistClient()
    except RuntimeError as e:
        print("Unable to connect to Zeitgeist, won't send events. Reason: '%s'" % e)


def get_repo():
    """Get uri of remote repository and its name"""
    repo = None
    uri = subprocess.Popen(['git', 'config', '--get', 'remote.origin.url'],
                           stdout=subprocess.PIPE).communicate()[0]

    if uri:
        uri = uri.strip().decode(sys.getfilesystemencoding())
        if '/' in uri:
            sep = '/'
        else:
Example #42
0
  line = sys.argv[1].strip()
  prompt_index = line.find(MY_PROMPT)
  
  if ( prompt_index > -1 ):
    args_index = prompt_index + len(MY_PROMPT)
    prompt = line[:args_index]
    args = line[args_index:].strip().split(" ")
    cmd = args[0]
  
  # TODO add more commands. For now only command cd triggers event.  
  if(cmd == 'cd'):

    try:
      from zeitgeist.client import ZeitgeistClient
      from zeitgeist.datamodel import Subject, Event, Interpretation, Manifestation
      zeitgeistclient = ZeitgeistClient()
      got_zeitgeist = True
    except (RuntimeError, ImportError, dbus.exceptions.DBusException):
      got_zeitgeist = False
     
    precond = os.getuid() != 0 and os.getenv('DBUS_SESSION_BUS_ADDRESS') != None
     
    if got_zeitgeist and precond:
      
      uri            = 'file:///home/saasbook/typescript.txt' # must exist
      mimetype       = 'text/plain'
      event_actor    = 'app://somefakestring.desktop'
      event_interp   = 'new'
      event_manif    = 'user'
      subject_interp = 'document'
      subject_manif  = 'file_data_object'