Author: duncan
Date: Wed Jul 25 16:02:40 2007
New Revision: 9764
Log:
[ 1760242 ] audio scrobbler for last.fm
Patch from Wout Clymans applied
Added:
branches/rel-1/freevo/src/audio/plugins/freevo_scrobbler.py (contents,
props changed)
Modified:
branches/rel-1/freevo/ChangeLog
branches/rel-1/freevo/src/audio/audioitem.py
Modified: branches/rel-1/freevo/ChangeLog
==============================================================================
--- branches/rel-1/freevo/ChangeLog (original)
+++ branches/rel-1/freevo/ChangeLog Wed Jul 25 16:02:40 2007
@@ -18,6 +18,7 @@
* New Chinese Translation (F#1752417)
* Added personal web pages to the webserver, using PERSONAL_WWW_PAGE
(F#1729595)
+ * Added audio scrobbler plug-in for last fm (F#1760242)
* Added sounds to menu selection, enabled with OSD_SOUNDS_ENABLED (F#1732380)
* Added translation for Greek (F#)
* Added XINE_BOOKMARK for when xine has support for get_time, default is off
(B#1745076)
@@ -26,6 +27,7 @@
* Updated headlines to allow the window to be scrolled (F#1752971)
* Updated local_conf.py.example with MPLAYER_HAS_FIELD_DOMINANCE (F#1729404)
* Updated record_client to allow favourites to be added from the command line
(F#1734781)
+ * Updated recordings manager to show full scrollable description (F#1759171)
* Updated skins to adjust the window heights when the button bar is active
(F#1733061)
* Updated system sensors for a configurable path (B#1731892)
* Updated tv program menu to show full description (F#1752973)
Modified: branches/rel-1/freevo/src/audio/audioitem.py
==============================================================================
--- branches/rel-1/freevo/src/audio/audioitem.py (original)
+++ branches/rel-1/freevo/src/audio/audioitem.py Wed Jul 25 16:02:40 2007
@@ -41,6 +41,14 @@
from player import PlayerGUI
from item import Item
+try:
+ if config.LASTFM_SCROBBLE:
+ from plugins.freevo_scrobbler import Scrobbler
+ SCROBBLE = True
+ else:
+ SCROBBLE = False
+except:
+ SCROBBLE = False
class AudioItem(Item):
"""
@@ -169,6 +177,12 @@
self.player = PlayerGUI(self, menuw)
error = self.player.play()
+ #last.fm scrobbler
+ if SCROBBLE:
+ scrobbler = Scrobbler()
+ if scrobbler.send_handshake():
+ scrobbler.submit_song(self.info)
+
if error and menuw:
AlertBox(text=error).show()
rc.post_event(rc.PLAY_END)
Added: branches/rel-1/freevo/src/audio/plugins/freevo_scrobbler.py
==============================================================================
--- (empty file)
+++ branches/rel-1/freevo/src/audio/plugins/freevo_scrobbler.py Wed Jul 25
16:02:40 2007
@@ -0,0 +1,144 @@
+# -*- coding: iso-8859-1 -*-
+# -----------------------------------------------------------------------
+# freevo_scrobbler - Upload the music you play to your last.fm profile
+# -----------------------------------------------------------------------
+#
+# Notes:
+# Todo:
+#
+# -----------------------------------------------------------------------
+# Freevo - A Home Theater PC framework
+# Copyright (C) 2002 Krister Lagerstrom, et al.
+# Please see the file freevo/Docs/CREDITS for a complete list of authors.
+#
+# 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 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MER-
+# CHANTABILITY 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.,
+# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# -----------------------------------------------------------------------
+
+import urllib2, urllib
+import md5 , time
+import config
+
+URL = "http://post.audioscrobbler.com/?hs=true&p=1.1&c=xms&v=0.7"
+
+
+class Scrobbler:
+ def __init__(self):
+ self.username = config.LASTFM_USER
+ self.md5_pass = config.LASTFM_PASS
+ hasher = md5.new()
+ hasher.update(self.md5_pass);
+ self.password = hasher.hexdigest()
+
+ def config(self):
+ '''config is called automatically,
+ freevo plugins -i video.bilingual returns the info
+ '''
+ return [
+ ('LASTFM_USER', 'None', 'User id for last fm'),
+ ('LASTFM_PASS', 'None', 'Password for last fm'),
+ ]
+
+ def send_handshake(self):
+ url = URL + "&u=%s" % self.username
+ resp = None
+
+ try:
+ resp = urllib2.urlopen(url);
+ except Exception,e:
+ print "Server not responding, handshake failed.",e
+ return False
+
+ # check response
+ lines = resp.read().rstrip().split("\n")
+ status = lines.pop(0)
+
+ if status.startswith("UPDATE"): print "Please update: %s" % status
+
+ if status == "UPTODATE" or status.startswith("UPDATE"):
+ challenge = lines.pop(0)
+
+ hasher = md5.new()
+ hasher.update(self.password)
+ hasher.update(challenge)
+ self.password_hash = hasher.hexdigest()
+
+ self.submit_url = lines.pop(0)
+ print "Handshake SUCCESS"
+
+ try: self.interval_time = int(lines.pop(0).split()[1])
+ except: pass
+
+ if status == "UPTODATE" or status.startswith("UPDATE"): return True
+ elif status == "BADUSER": print "Handshake failed: bad user"
+ else: print "Handshake failed: %s" % status; return False
+
+ def submit_song(self, info):
+ data = {
+ 'u': self.username,
+ 's': self.password_hash
+ }
+ if not info['length']<=30*1000 or not info['title']=="" or not
info['artist']=="":
+ print ("Sending song: " + info['artist'] + " - " + info['title'])
+ i = 0
+ stamp = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())
+ data["a[%d]" % i] = info['artist'].encode('utf-8')
+ data["t[%d]" % i] = info['title'].encode('utf-8')
+ data["l[%d]" % i] = str(info['length']).encode('utf-8')
+ data["b[%d]" % i] = info['album'].encode('utf-8')
+ data["m[%d]" % i] = ""
+ data["i[%d]" % i] = stamp
+
+ (host, file) = self.submit_url[7:].split("/")
+ url = "http://" + host + "/" + file
+ resp = None
+ try:
+ data_str = urllib.urlencode(data)
+ resp = urllib2.urlopen(url, data_str)
+ resp_save = resp.read()
+ except Exception,e:
+ print "Audioscrobbler server not responding, will try later.",e
+
+ lines = resp_save.rstrip().split("\n")
+
+ try: (status, interval) = lines
+ except:
+ try: status = lines[0]
+ except:
+ print "Status incorrect"
+ return False
+ else: self.interval_time = int(interval.split()[1])
+
+ if status == "BADAUTH":
+ print "Authentication failed: invalid username or bad
password."
+ print url
+ print data
+
+ elif status == "OK":
+ print "Submit succesfull"
+ return True
+
+ elif status.startswith("FAILED"):
+ print "FAILED response from server: %s" % status
+ print "Dumping full response:"
+ print resp_save
+ else:
+ print "Unknown response from server: %s" % status
+ print "Dumping full response:"
+ print resp_save
+ else:
+ print "Song not accepted!"
+
+ return False
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog