finish removing lastFM support. done in #9644
This commit is contained in:
parent
bf169f302a
commit
47f34bcd56
|
@ -162,7 +162,6 @@ class Config:
|
||||||
'before_nickname': [ opt_str, '', _('Characters that are printed before the nickname in conversations') ],
|
'before_nickname': [ opt_str, '', _('Characters that are printed before the nickname in conversations') ],
|
||||||
'after_nickname': [ opt_str, ':', _('Characters that are printed after the nickname in conversations') ],
|
'after_nickname': [ opt_str, ':', _('Characters that are printed after the nickname in conversations') ],
|
||||||
'send_os_info': [ opt_bool, True ],
|
'send_os_info': [ opt_bool, True ],
|
||||||
'lastfm_username': [ opt_str, '', _('The username used to identify the Last.fm account.')],
|
|
||||||
'notify_on_new_gmail_email': [ opt_bool, True ],
|
'notify_on_new_gmail_email': [ opt_bool, True ],
|
||||||
'notify_on_new_gmail_email_extra': [ opt_bool, False ],
|
'notify_on_new_gmail_email_extra': [ opt_bool, False ],
|
||||||
'use_gpg_agent': [ opt_bool, False ],
|
'use_gpg_agent': [ opt_bool, False ],
|
||||||
|
|
219
src/lastfm.py
219
src/lastfm.py
|
@ -1,219 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding:utf-8 -*-
|
|
||||||
## src/lastfm.py
|
|
||||||
##
|
|
||||||
## Copyright (C) 2007 Olivier Mehani <shtrom AT ssji.net>
|
|
||||||
## Yann Leboulanger <asterix AT lagaule.org>
|
|
||||||
## Copyright (C) 2007-2008 Jean-Marie Traissard <jim AT lapin.org>
|
|
||||||
##
|
|
||||||
## This file is part of Gajim.
|
|
||||||
##
|
|
||||||
## Gajim 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; version 3 only.
|
|
||||||
##
|
|
||||||
## Gajim 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 Gajim. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
##
|
|
||||||
|
|
||||||
__version__ = '$Revision: 64 $'
|
|
||||||
|
|
||||||
from urllib import urlopen
|
|
||||||
from xml.dom import minidom
|
|
||||||
from time import time
|
|
||||||
|
|
||||||
class LastFM:
|
|
||||||
# Where to fetch the played song information
|
|
||||||
LASTFM_FORMAT_URL = \
|
|
||||||
'http://ws.audioscrobbler.com/1.0/user/%s/recenttracks.xml'
|
|
||||||
# Delay in seconds after which the last song entry is considered too old tox
|
|
||||||
# be displayed.
|
|
||||||
MAX_DELAY = 600
|
|
||||||
|
|
||||||
ARTIST = 0
|
|
||||||
NAME = 1
|
|
||||||
ALBUM = 2
|
|
||||||
TIME = 3
|
|
||||||
|
|
||||||
def __init__(self, username, proxies=None):
|
|
||||||
"""
|
|
||||||
Create a new LastFM object.
|
|
||||||
|
|
||||||
username, the Last.fm username
|
|
||||||
proxies, the list of proxies to use to connect to the Last.fm data, as
|
|
||||||
expected by urllib.urlopen()
|
|
||||||
"""
|
|
||||||
self.setUsername(username)
|
|
||||||
self._proxies = proxies
|
|
||||||
self.scrobbling = False
|
|
||||||
self.updateData()
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return 'Last.fm song tracker for user %s.%s' % (self._username,
|
|
||||||
self.formatSongTitle(
|
|
||||||
' Last song was \"%(n)s\" by \"%(a)s\" in album \"%(b)s\".'))
|
|
||||||
|
|
||||||
def getUsername(self):
|
|
||||||
return self._username
|
|
||||||
|
|
||||||
def setUsername(self, username):
|
|
||||||
self._username = username
|
|
||||||
self.lastSongs = []
|
|
||||||
|
|
||||||
def updateData(self):
|
|
||||||
"""
|
|
||||||
Fetch the last recent tracks list and update the object accordingly.
|
|
||||||
|
|
||||||
Return True if the last played time has changed, False otherwise.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
xmldocument = urlopen(self.LASTFM_FORMAT_URL % self._username,
|
|
||||||
self._proxies)
|
|
||||||
xmltree = minidom.parse(xmldocument)
|
|
||||||
except Exception:
|
|
||||||
print 'Error parsing XML from Last.fm...'
|
|
||||||
return False
|
|
||||||
|
|
||||||
if xmltree.childNodes.length != 1:
|
|
||||||
raise Exception('XML document not formed as expected')
|
|
||||||
|
|
||||||
recenttracks = xmltree.childNodes[0]
|
|
||||||
|
|
||||||
tracklist = recenttracks.getElementsByTagName('track')
|
|
||||||
|
|
||||||
# do not update if nothing more has been scrobbled since last time
|
|
||||||
if len(tracklist) > 0 and \
|
|
||||||
int(tracklist[0].getElementsByTagName('date')[0].
|
|
||||||
getAttribute('uts')) != self.getLastScrobbledTime():
|
|
||||||
self.lastSongs = []
|
|
||||||
for track in tracklist:
|
|
||||||
artistNode = track.getElementsByTagName('artist')[0]
|
|
||||||
if artistNode.firstChild:
|
|
||||||
artist = artistNode.firstChild.data
|
|
||||||
else:
|
|
||||||
artist = None
|
|
||||||
|
|
||||||
nameNode = track.getElementsByTagName('name')[0]
|
|
||||||
if nameNode.firstChild:
|
|
||||||
name = nameNode.firstChild.data
|
|
||||||
else:
|
|
||||||
name = None
|
|
||||||
|
|
||||||
albumNode = track.getElementsByTagName('album')[0]
|
|
||||||
if albumNode.firstChild:
|
|
||||||
album = albumNode.firstChild.data
|
|
||||||
else:
|
|
||||||
album = None
|
|
||||||
|
|
||||||
timeNode = track.getElementsByTagName('date')[0]
|
|
||||||
self.lastSongs.append((artist, name, album,
|
|
||||||
int(timeNode.getAttribute('uts'))))
|
|
||||||
self.scrobbling = True
|
|
||||||
return True
|
|
||||||
|
|
||||||
# if nothing has been scrobbled for too long, an update to the
|
|
||||||
# "currently" playing song should be made
|
|
||||||
if self.scrobbling and not self.lastSongIsRecent():
|
|
||||||
self.scrobbling = False
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
def getLastSong(self):
|
|
||||||
"""
|
|
||||||
Return the last played song as a tuple of (ARTIST, SONG, ALBUM, TIME).
|
|
||||||
"""
|
|
||||||
if len(self.lastSongs) < 1:
|
|
||||||
return None
|
|
||||||
return self.lastSongs[0]
|
|
||||||
|
|
||||||
def getLastScrobbledTime(self):
|
|
||||||
"""
|
|
||||||
Return the Unix time the last song was played.
|
|
||||||
"""
|
|
||||||
if len(self.lastSongs) < 1:
|
|
||||||
return 0
|
|
||||||
return self.lastSongs[0][self.TIME]
|
|
||||||
|
|
||||||
def timeSinceLastScrobbled(self, lst=None):
|
|
||||||
"""
|
|
||||||
Return the time in seconds since the last song has been scrobbled.
|
|
||||||
|
|
||||||
lst, the Unix time at which a song has been scrobbled, defaults to that
|
|
||||||
of the last song
|
|
||||||
"""
|
|
||||||
if lst is None:
|
|
||||||
lst = self.getLastScrobbledTime()
|
|
||||||
return int(time()) - lst
|
|
||||||
|
|
||||||
def lastSongIsRecent(self, delay=None):
|
|
||||||
"""
|
|
||||||
Return a boolean stating whether the last song has been played less
|
|
||||||
the specified delay earlier.
|
|
||||||
|
|
||||||
delay, the delay to use, defaults to self.MAX_DELAY
|
|
||||||
"""
|
|
||||||
if delay is None:
|
|
||||||
delay = self.MAX_DELAY
|
|
||||||
return self.timeSinceLastScrobbled() < delay
|
|
||||||
|
|
||||||
def getLastRecentSong(self, delay=None):
|
|
||||||
"""
|
|
||||||
Return the last *recently* played song.
|
|
||||||
|
|
||||||
"Recently" means that the song has been played less than delay
|
|
||||||
earlier.
|
|
||||||
|
|
||||||
delay, the delay to use, see lastSongIsRecent for the semantics
|
|
||||||
"""
|
|
||||||
self.updateData()
|
|
||||||
if self.lastSongIsRecent(delay):
|
|
||||||
return self.getLastSong()
|
|
||||||
return None
|
|
||||||
|
|
||||||
def formatSongTitle(self, formatString='%(a)s - %(n)s', songTuple=None):
|
|
||||||
"""
|
|
||||||
Format a song tuple according to a format string. This makes use of the
|
|
||||||
basic Python string formatting operations.
|
|
||||||
|
|
||||||
formatString, the string according to which the song should be formated:
|
|
||||||
"%(a)s" is replaced by the artist;
|
|
||||||
"%(n)s" is replaced by the name of the song;
|
|
||||||
"%(b)s" is replaced by the album;
|
|
||||||
defaults to "%s - %t".
|
|
||||||
songTuple, the tuple representing the song, defaults to the last song
|
|
||||||
"""
|
|
||||||
str = ''
|
|
||||||
if songTuple is None:
|
|
||||||
songTuple = self.getLastRecentSong()
|
|
||||||
|
|
||||||
if songTuple is not None:
|
|
||||||
dict = {
|
|
||||||
'a': songTuple[0],
|
|
||||||
'n': songTuple[1],
|
|
||||||
'b': songTuple[2]
|
|
||||||
}
|
|
||||||
str = formatString % dict
|
|
||||||
|
|
||||||
return str
|
|
||||||
|
|
||||||
# Fallback if the script is called directly
|
|
||||||
if __name__ == '__main__':
|
|
||||||
from sys import argv
|
|
||||||
from time import sleep
|
|
||||||
if len(argv) != 2:
|
|
||||||
raise Exception('Incorrect number of arguments. Only the Last.fm username is required.')
|
|
||||||
|
|
||||||
lfm = LastFM(argv[1])
|
|
||||||
print lfm
|
|
||||||
while True:
|
|
||||||
if lfm.updateData():
|
|
||||||
print lfm.formatSongTitle()
|
|
||||||
sleep(60)
|
|
||||||
|
|
||||||
# vim: se ts=3:
|
|
|
@ -1,109 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
## src/lastfm_track_listener.py
|
|
||||||
##
|
|
||||||
## Copyright (C) 2007 Olivier Mehani <shtrom-gajim AT ssji.net>
|
|
||||||
## Yann Leboulanger <asterix AT lagaule.org>
|
|
||||||
##
|
|
||||||
## This file is part of Gajim.
|
|
||||||
##
|
|
||||||
## Gajim 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; version 3 only.
|
|
||||||
##
|
|
||||||
## Gajim 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 Gajim. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
##
|
|
||||||
|
|
||||||
import gobject
|
|
||||||
from lastfm import LastFM
|
|
||||||
|
|
||||||
class LastFMTrackInfo(object):
|
|
||||||
__slots__ = ['title', 'album', 'artist']
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
|
||||||
if self.__class__ != other.__class__:
|
|
||||||
return False
|
|
||||||
return self.title == other.title and self.album == other.album and \
|
|
||||||
self.artist == other.artist
|
|
||||||
|
|
||||||
def __ne__(self, other):
|
|
||||||
return not self.__eq__(other)
|
|
||||||
|
|
||||||
class LastFMTrackListener(gobject.GObject):
|
|
||||||
__gsignals__ = {
|
|
||||||
'music-track-changed': (gobject.SIGNAL_RUN_LAST, None, (object,)),
|
|
||||||
}
|
|
||||||
|
|
||||||
# polling period in milliseconds
|
|
||||||
INTERVAL = 60000 #LastFM.MAX_DELAY * 250 # 1/4 of LastFM's delay (in s)
|
|
||||||
|
|
||||||
_instance = None
|
|
||||||
@classmethod
|
|
||||||
def get(cls, username):
|
|
||||||
if cls._instance is None:
|
|
||||||
cls._instance = cls(username)
|
|
||||||
else:
|
|
||||||
cls._instance._lfm.setUsername(username)
|
|
||||||
return cls._instance
|
|
||||||
|
|
||||||
def __init__(self, username):
|
|
||||||
super(LastFMTrackListener, self).__init__()
|
|
||||||
self._lfm_user = username
|
|
||||||
self._lfm = LastFM(self._lfm_user)
|
|
||||||
self._last_playing_music = None
|
|
||||||
self._lastfm_music_track_change()
|
|
||||||
gobject.timeout_add(self.INTERVAL, self._lastfm_periodic_check)
|
|
||||||
|
|
||||||
def _lastfm_properties_extract(self, song_tuple):
|
|
||||||
if song_tuple:
|
|
||||||
info = LastFMTrackInfo()
|
|
||||||
info.title = song_tuple[LastFM.NAME]
|
|
||||||
info.album = song_tuple[LastFM.ALBUM]
|
|
||||||
info.artist = song_tuple[LastFM.ARTIST]
|
|
||||||
return info
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _lastfm_periodic_check(self):
|
|
||||||
if self._lfm.updateData():
|
|
||||||
self._lastfm_music_track_change()
|
|
||||||
return True
|
|
||||||
|
|
||||||
def _lastfm_music_track_change(self):
|
|
||||||
info = self._lastfm_properties_extract(
|
|
||||||
self._lfm.getLastRecentSong())
|
|
||||||
self._last_playing_music = info
|
|
||||||
self.emit('music-track-changed', info)
|
|
||||||
|
|
||||||
def get_playing_track(self):
|
|
||||||
'''Return a LastFMTrackInfo for the currently playing
|
|
||||||
song, or None if no song is playing'''
|
|
||||||
return self._last_playing_music
|
|
||||||
|
|
||||||
# here we test :)
|
|
||||||
if __name__ == '__main__':
|
|
||||||
from sys import argv
|
|
||||||
if len(argv) != 2:
|
|
||||||
raise Exception("Incorrect number of arguments. Only the Last.fm username is required.")
|
|
||||||
|
|
||||||
def music_track_change_cb(listener, music_track_info):
|
|
||||||
if music_track_info is None:
|
|
||||||
print "Stop!"
|
|
||||||
else:
|
|
||||||
print 'Now playing: "%s" by %s' % (
|
|
||||||
music_track_info.title, music_track_info.artist)
|
|
||||||
|
|
||||||
listener = LastFMTrackListener.get(argv[1])
|
|
||||||
listener.connect('music-track-changed', music_track_change_cb)
|
|
||||||
track = listener.get_playing_track()
|
|
||||||
if track is None:
|
|
||||||
print 'Now not playing anything'
|
|
||||||
else:
|
|
||||||
print 'Now playing: "%s" by %s' % (track.title, track.artist)
|
|
||||||
gobject.MainLoop().run()
|
|
||||||
|
|
||||||
# vim: se ts=3:
|
|
|
@ -68,7 +68,6 @@ from common import dbus_support
|
||||||
if dbus_support.supported:
|
if dbus_support.supported:
|
||||||
from music_track_listener import MusicTrackListener
|
from music_track_listener import MusicTrackListener
|
||||||
import dbus
|
import dbus
|
||||||
from lastfm_track_listener import LastFMTrackListener
|
|
||||||
|
|
||||||
from common.xmpp.protocol import NS_COMMANDS, NS_FILE, NS_MUC
|
from common.xmpp.protocol import NS_COMMANDS, NS_FILE, NS_MUC
|
||||||
from common.pep import MOODS, ACTIVITIES
|
from common.pep import MOODS, ACTIVITIES
|
||||||
|
|
Loading…
Reference in New Issue