[rhythmbox] add zeitgeist plugin, developed by Markus Korn, Laszlo Pandy and Michal Hruby



commit 061932fd629ae85ea457372dc93e35d3bcbb0313
Author: Jonathan Matthew <jonathan d14n org>
Date:   Tue Oct 19 14:39:07 2010 +1000

    add zeitgeist plugin, developed by Markus Korn, Laszlo Pandy and Michal Hruby

 configure.ac                                 |    1 +
 data/rhythmbox.schemas                       |   22 ++++
 plugins/Makefile.am                          |    1 +
 plugins/rbzeitgeist/Makefile.am              |   14 +++
 plugins/rbzeitgeist/rbzeitgeist.rb-plugin.in |    9 ++
 plugins/rbzeitgeist/rbzeitgeist/__init__.py  |  149 ++++++++++++++++++++++++++
 6 files changed, 196 insertions(+), 0 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index c4fc709..5d16bb1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -925,6 +925,7 @@ plugins/replaygain/Makefile
 plugins/replaygain/replaygain/Makefile
 plugins/mpris/Makefile
 plugins/dbus-media-server/Makefile
+plugins/rbzeitgeist/Makefile
 bindings/Makefile
 bindings/python/Makefile
 bindings/vala/Makefile
diff --git a/data/rhythmbox.schemas b/data/rhythmbox.schemas
index 802f612..f66f864 100644
--- a/data/rhythmbox.schemas
+++ b/data/rhythmbox.schemas
@@ -1682,5 +1682,27 @@
 	<long>True if the MediaServer2 plugin is hidden.</long>
 	</locale>
       </schema>
+      <schema>
+        <key>/schemas/apps/rhythmbox/plugins/rbzeitgeist/active</key>
+        <applyto>/apps/rhythmbox/plugins/rbzeitgeist/active</applyto>
+        <owner>rhythmbox</owner>
+        <type>bool</type>
+        <default>FALSE</default>
+        <locale name="C">
+        <short>True if the Zeitgeist plugin is enabled.</short>
+	<long>True if the Zeitgeist plugin is enabled.</long>
+	</locale>
+      </schema>
+      <schema>
+        <key>/schemas/apps/rhythmbox/plugins/rbzeitgeist/hidden</key>
+        <applyto>/apps/rhythmbox/plugins/rbzeitgeist/hidden</applyto>
+        <owner>rhythmbox</owner>
+        <type>bool</type>
+        <default>FALSE</default>
+        <locale name="C">
+        <short>True if the Zeitgeist plugin is hidden.</short>
+	<long>True if the Zeitgeist plugin is hidden.</long>
+	</locale>
+      </schema>
     </schemalist>
 </gconfschemafile>
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 3d92e45..20a2e48 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -25,6 +25,7 @@ SUBDIRS += 						\
 	context						\
 	sendto						\
 	replaygain					\
+	rbzeitgeist					\
 	rb
 endif
 
diff --git a/plugins/rbzeitgeist/Makefile.am b/plugins/rbzeitgeist/Makefile.am
new file mode 100644
index 0000000..eb8fa0d
--- /dev/null
+++ b/plugins/rbzeitgeist/Makefile.am
@@ -0,0 +1,14 @@
+# Zeitgeist Python Plugin
+
+plugin_in_files = rbzeitgeist.rb-plugin.in
+%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+
+plugin_DATA = $(plugin_in_files:.rb-plugin.in=.rb-plugin)
+
+plugindir = $(PLUGINDIR)/rbzeitgeist
+plugin_PYTHON = rbzeitgeist/__init__.py
+
+EXTRA_DIST = $(plugin_in_files) $(plugin_PYTHON)
+
+CLEANFILES = $(plugin_DATA)
+DISTCLEANFILES = $(plugin_DATA)
diff --git a/plugins/rbzeitgeist/rbzeitgeist.rb-plugin.in b/plugins/rbzeitgeist/rbzeitgeist.rb-plugin.in
new file mode 100644
index 0000000..8a36dda
--- /dev/null
+++ b/plugins/rbzeitgeist/rbzeitgeist.rb-plugin.in
@@ -0,0 +1,9 @@
+[RB Plugin]
+Loader=python
+Module=rbzeitgeist
+IAge=1
+_Name=Zeitgeist
+_Description=Inform Zeitgeist about your activity
+Authors=Markus Korn <thekorn gmx de>
+Copyright=Copyright © 2009 Markus Korn
+Website=http://www.zeitgeist-project.com
diff --git a/plugins/rbzeitgeist/rbzeitgeist/__init__.py b/plugins/rbzeitgeist/rbzeitgeist/__init__.py
new file mode 100644
index 0000000..5698641
--- /dev/null
+++ b/plugins/rbzeitgeist/rbzeitgeist/__init__.py
@@ -0,0 +1,149 @@
+# -.- coding: utf-8 -.-
+
+# Copyright © 2009 Markus Korn <thekorn gmx de>
+# Copyright © 2010 Laszlo Pandy <laszlok2 gmail com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# The Rhythmbox authors hereby grant permission for non-GPL compatible
+# GStreamer plugins to be used and distributed together with GStreamer
+# and Rhythmbox. This permission is above and beyond the permissions granted
+# by the GPL license by which Rhythmbox is covered. If you modify this code
+# you may extend this exception to your version of the code, but you are not
+# obligated to do so. If you do not wish to do so, delete this exception
+# statement from your version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# 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 rb
+import rhythmdb
+import gobject
+import time
+
+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(rb.Plugin):
+
+    def __init__(self):
+        rb.Plugin.__init__(self)
+
+    def activate(self, shell):
+        print "LOADING Zeitgeist plugin ......"
+        if IFACE is not None:
+            shell_player = shell.get_player()
+            self.__psc_id = shell_player.connect("playing-song-changed", self.playing_song_changed)
+
+            backend_player = shell_player.get_property("player")
+            self.__eos_id = backend_player.connect("eos", self.on_backend_eos)
+
+            self.__manual_switch = True
+            self.__current_song = None
+            self._shell = shell
+
+            if IFACE.get_version() >= [0, 3, 2, 999]:
+                IFACE.register_data_source("5463", "Rhythmbox", "Play and organize your music collection",
+                                            [Event.new_for_values(actor="application://rhythmbox.desktop")]
+                                            )
+
+    @staticmethod
+    def get_song_info(db, entry):
+        song = {
+            "album": db.entry_get(entry, rhythmdb.PROP_ALBUM),
+            "artist": db.entry_get(entry, rhythmdb.PROP_ARTIST),
+            "title":  db.entry_get(entry, rhythmdb.PROP_TITLE),
+            "location": db.entry_get(entry, rhythmdb.PROP_LOCATION),
+            "mimetype": db.entry_get(entry, rhythmdb.PROP_MIMETYPE),
+        }
+        return song
+
+
+    def on_backend_eos(self, backend_player, stream_data, eos_early):
+        # EOS signal means that the song changed because the song is over.
+        # ie. the user did not explicitly change the song.
+        self.__manual_switch = False
+
+    def playing_song_changed(self, shell, entry):
+        if self.__current_song is not None:
+            self.send_to_zeitgeist_async(self.__current_song, Interpretation.LEAVE_EVENT)
+
+        if entry is not None:
+            self.send_to_zeitgeist_async(entry, Interpretation.ACCESS_EVENT)
+
+        self.__current_song = entry
+        gobject.idle_add(self.reset_manual_switch)
+
+    def reset_manual_switch(self):
+        """
+        After the eos signal has fired, and after the zeitgeist events have
+        been sent asynchronously, reset the manual_switch variable.
+        """
+        self.__manual_switch = True
+
+    def send_to_zeitgeist_async(self, entry, event_type):
+        """
+        We do async here because the "eos" signal is fired
+        *after* the "playing-song-changed" signal.
+        We don't know if the song change was manual or automatic
+        until we get get the eos signal. If the mainloop goes to
+        idle, it means there are no more signals scheduled, so we
+        will have already received the eos if it was coming.
+        """
+        db = self._shell.get_property("db")
+        gobject.idle_add(self.send_to_zeitgeist, db, entry, event_type)
+
+    def send_to_zeitgeist(self, db, entry, event_type):
+        song = self.get_song_info(db, entry)
+
+        if self.__manual_switch:
+            manifest = Manifestation.USER_ACTIVITY
+        else:
+            manifest = Manifestation.SCHEDULED_ACTIVITY
+
+        subject = Subject.new_for_values(
+            uri=song["location"],
+            interpretation=unicode(Interpretation.AUDIO),
+            manifestation=unicode(Manifestation.FILE_DATA_OBJECT),
+            #~ origin="", #TBD
+            mimetype=song["mimetype"],
+            text=" - ".join([song["title"], song["artist"], song["album"]])
+        )
+        event = Event.new_for_values(
+            timestamp=int(time.time()*1000),
+            interpretation=unicode(event_type),
+            manifestation=unicode(manifest),
+            actor="application://rhythmbox.desktop",
+            subjects=[subject,]
+        )
+        #print event
+        IFACE.insert_event(event)
+
+    def deactivate(self, shell):
+        print "UNLOADING Zeitgeist plugin ......."
+        if IFACE is not None:
+            shell_player = shell.get_player()
+            shell_player.disconnect(self.__psc_id)
+            self.__psc_id = None
+
+            backend_player = shell_player.get_property("player")
+            backend_player.disconnect(self.__eos_id)
+            self.__eos_id = None
+
+            self._shell = None
+            self.__current_song = None



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