Permalink
Browse files

basic playlist management for ncmpcpp added

  • Loading branch information...
1 parent a38c7bd commit 162398e4a3917580d6a0b7473cbb5c6ff1054f7c @wendlers committed Oct 5, 2012
View
@@ -20,8 +20,9 @@ Main features currently supported:
* Browse predefined set of favorite users (see "~/.pyscmpd/pyscmpd.conf")
* Browse predefined set of favorite groups (see "~/.pyscmpd/pyscmpd.conf")
* Browse the favorite tracks of a predefined set of users (see "~/.pyscmpd/pyscmpd.conf")
-* Browse a set of random users as provided by soundcloud API
-* Browse a set of random groups as provided by soundcloud API
+* Current playlist is persisted on SIGTERM and restored on next restart
+* Save current playlist to defined name (I needed to remove random-groups/users for this, since otherwise songs will not be found again)
+* Browse/Load playlists (only ncmpcpp yet, since sonata uses different command)
* Add tracks to current play-list
* Play tracks from play-list
* Change song order in current play-list
View
@@ -261,7 +261,7 @@ def readConfig(self, cfgFile, foreground=False):
def run(self):
logging.info("pyscmpd v%s started" % PYSCMPD_VERSION)
- mpd = scmpd.ScMpdServerDaemon(self.favoriteUsers, self.favoriteGroups,
+ self.mpd = scmpd.ScMpdServerDaemon(self.favoriteUsers, self.favoriteGroups,
self.favoriteFavorites, self.port)
self.mainloop = gobject.MainLoop()
View
@@ -23,7 +23,12 @@
import logging
import gst
+import os
+
import pyscmpd.resource as resource
+import pyscmpd.respersist as persist
+
+from config import *
class GstPlayer(resource.DirectoryResource):
@@ -304,3 +309,45 @@ def setVolume(self, percent):
def getVolume(self):
return int(self.player.get_property('volume') * 100)
+ def storePlaylist(self, plName = CURR_PLAYLIST_KEY):
+
+ logging.info("Storing playlist with key: %s" % plName)
+
+ p = persist.ResourceFilePersistence(PLAYLIST_DIR)
+ p.store(plName, self.children)
+
+ def retrivePlaylist(self, plName = CURR_PLAYLIST_KEY, makeCurrent = True):
+
+ logging.info("Retriving playlist with key: %s" % plName)
+
+ self.stop()
+ self.currentSongNumber = -1
+ self.currentSongId = -1
+
+ p = persist.ResourceFilePersistence(PLAYLIST_DIR)
+ c = p.retrive(plName)
+
+ if not c == None and makeCurrent:
+ self.children = c
+ self.playlistVersion = self.playlistVersion + 1
+
+ return c
+
+ def listPlaylists(self):
+
+ plFiles = []
+
+ try:
+ for (root, dirs, files) in os.walk(PLAYLIST_DIR):
+
+ logging.info("found playlist files: %s" % files)
+
+ for f in files:
+ plFiles.append(f)
+
+ return plFiles
+
+ except Exception as e:
+ logging.warn("Unable to retrive playlists: %s" % `e`)
+
+ return plFiles
View
@@ -59,6 +59,9 @@ def prepare():
f.write("favorites: kaltpost\n")
f.close()
+pyscmpd = None
+args = None
+
try:
parser = argparse.ArgumentParser(description='Python Soundcloud Music Player Daemon "pyscmpd"')
@@ -114,7 +117,12 @@ def prepare():
os.remove(args.pidfile)
except KeyboardInterrupt:
- pass
+
+ try:
+ if args.foreground:
+ pyscmpd.mpd.exitHandler()
+ except:
+ pass
except Exception as e:
View
@@ -122,7 +122,7 @@ def getChildByPath(self, path):
logging.info("Consuming path [%s]/[%s]" % (l, r))
- if l == "" or not c.getType() == Resource.TYPE_DIRECTORY:
+ if l == "" or c == None or not c.getType() == Resource.TYPE_DIRECTORY:
return None
c = c.getChildByName(l)
@@ -36,7 +36,7 @@ def store(self, key, obj):
try:
- f = open("%s/%s.dump" % (self.baseDir, key), "wb")
+ f = open("%s/%s" % (self.baseDir, key), "wb")
pickle.dump(obj, f)
except Exception as e:
@@ -50,10 +50,11 @@ def store(self, key, obj):
def retrive(self, key):
obj = None
+ f = None
try:
- f = open("%s/%s.dump" % (self.baseDir, key), "rb")
+ f = open("%s/%s" % (self.baseDir, key), "rb")
obj = pickle.load(f)
except Exception as e:
@@ -62,7 +63,8 @@ def retrive(self, key):
finally:
- f.close()
+ if not f == None:
+ f.close()
return obj
View
@@ -28,9 +28,6 @@
import pyscmpd.scprovider as provider
import pyscmpd.gstplayer as gstplayer
-import pyscmpd.respersist as persist
-
-from config import *
class ScMpdServerDaemon(mpdserver.MpdServerDaemon):
@@ -40,28 +37,11 @@ class ScMpdServerDaemon(mpdserver.MpdServerDaemon):
def __init__(self, favoriteUsers, favoriteGroups, favoriteFavorites, serverPort = 9900):
- ScMpdServerDaemon.player = gstplayer.GstPlayer()
-
- # try to read last playlist
- try:
-
- logging.info("Restoring last playlist")
- p = persist.ResourceFilePersistence(PLAYLIST_DIR)
- c = p.retrive(CURR_PLAYLIST_KEY)
-
- if not c == None:
- ScMpdServerDaemon.player.children = c
- ScMpdServerDaemon.player.playlistVersion = 1
-
- logging.info("Done restoring last playlist")
-
- except Exception as e:
+ ScMpdServerDaemon.player = gstplayer.GstPlayer()
+ ScMpdServerDaemon.player.retrivePlaylist()
- logging.warn("Unable to read last playlist: %s" % `e`)
-
- ScMpdServerDaemon.scp = provider.ResourceProvider(favoriteUsers, favoriteGroups,
- favoriteFavorites)
- ScMpdServerDaemon.scroot = ScMpdServerDaemon.scp.getRoot()
+ ScMpdServerDaemon.scp = provider.ResourceProvider(favoriteUsers, favoriteGroups, favoriteFavorites)
+ ScMpdServerDaemon.scroot = ScMpdServerDaemon.scp.getRoot()
mpdserver.MpdServerDaemon.__init__(self, serverPort)
@@ -81,20 +61,17 @@ def __init__(self, favoriteUsers, favoriteGroups, favoriteFavorites, serverPort
self.requestHandler.RegisterCommand(SetVol)
self.requestHandler.RegisterCommand(mpdserver.Move)
self.requestHandler.RegisterCommand(mpdserver.MoveId)
+ self.requestHandler.RegisterCommand(Save)
+ self.requestHandler.RegisterCommand(Load)
+ self.requestHandler.RegisterCommand(ListPlaylistInfo)
self.requestHandler.Playlist = MpdPlaylist
signal.signal(signal.SIGTERM, self.exitHandler)
- def exitHandler(self, signal, func = None):
-
- logging.info("Ending server daemon. Persisting current playlist")
-
- c = ScMpdServerDaemon.player.getAllChildren()
- p = persist.ResourceFilePersistence(PLAYLIST_DIR)
- p.store(CURR_PLAYLIST_KEY, c)
+ def exitHandler(self, signal = 0, func = None):
- logging.info("Done persisting current playlist")
+ ScMpdServerDaemon.player.storePlaylist()
exit(0)
class Play(mpdserver.Play):
@@ -196,6 +173,7 @@ def items(self):
logging.warn("[%s] is not a directory" % r.getName())
return i
+ # process 'directory'
for e in r.getAllChildren():
logging.debug("LsInfo sending item: %s/%s" % (self.directory, e.__str__()))
@@ -208,8 +186,46 @@ def items(self):
i.append(("Title", e.getMeta("Title")))
i.append(("Time", int(e.getMeta("Time") % 1000)))
+ # also list 'playlists'
+ if self.directory == None:
+
+ for pl in ScMpdServerDaemon.player.listPlaylists():
+ i.append(("playlist", pl))
+
return i
+class ListPlaylistInfo(mpdserver.ListPlaylistInfo):
+
+ playlistName = None
+
+ def handle_args(self, playlistName):
+ logging.info("ListPlaylistInfo for: %s" % playlistName)
+ self.playlistName = playlistName
+
+ def songs(self):
+
+ pl = []
+ i = 0
+ p = ScMpdServerDaemon.player.retrivePlaylist(self.playlistName, False)
+ l = len(p)
+
+ for t in p:
+ logging.info("Track: %s" % t.__str__())
+ s = mpdserver.MpdPlaylistSong(
+ playlistPosition = i,
+ artist = t.getMeta("Artist").encode('ASCII', 'ignore'),
+ title = t.getMeta("Title").encode('ASCII', 'ignore'),
+ file = t.getMeta("file").encode('ASCII', 'ignore'),
+ track = "%d/%d" % (i + 1, l),
+ time = "%d" % (t.getMeta("Time") / 1000),
+ songId = t.getId())
+
+ i = i + 1
+
+ pl.append(s)
+
+ return pl
+
class Add(mpdserver.Add):
def handle_args(self, song):
@@ -237,7 +253,7 @@ def handle_args(self, song):
t = ScMpdServerDaemon.scroot.getChildByPath(song)
if t == None:
- logging.error("Track [%s] not found in directory [%s]" % (track, user))
+ logging.error("Track [%s] not found" % song)
return
ScMpdServerDaemon.player.addChild(t)
@@ -316,3 +332,14 @@ def items(self):
playlistSongId = ScMpdServerDaemon.player.currentSongId)
return self.helper_status_stop()
+
+class Save(mpdserver.Save):
+
+ def handle_args(self, playlistName):
+ ScMpdServerDaemon.player.storePlaylist(playlistName)
+
+class Load(mpdserver.Load):
+
+ def handle_args(self, playlistName):
+ ScMpdServerDaemon.player.retrivePlaylist(playlistName)
+
View
@@ -49,7 +49,7 @@ def __init__(self, favoriteUsers, favoriteGroups, favoriteFavorites):
resource.DirectoryResource.__init__(self, 0, "pyscmpd", "pyscmpd")
- uall = Users("random-users")
+ # uall = Users("random-users")
ufavgrp = "favorite-users"
ufav = resource.DirectoryResource(0, ufavgrp, ufavgrp)
@@ -59,8 +59,7 @@ def __init__(self, favoriteUsers, favoriteGroups, favoriteFavorites):
f = FavoriteUsers(fav["name"], fav["users"], ufavgrp)
ufav.addChild(f)
- grps = Groups("random-groups")
-
+ # grps = Groups("random-groups")
gfavgrp = "favorite-groups"
gfav = resource.DirectoryResource(0, gfavgrp, gfavgrp)
@@ -81,11 +80,12 @@ def __init__(self, favoriteUsers, favoriteGroups, favoriteFavorites):
ffav.addChild(u)
self.addChild(ufav)
- self.addChild(uall)
- self.addChild(grps)
+ # self.addChild(uall)
+ # self.addChild(grps)
self.addChild(gfav)
self.addChild(ffav)
+'''
class Users(resource.DirectoryResource):
retriveLock = None
@@ -135,6 +135,7 @@ def retriveChildren(self):
except Exception as e:
logging.warn("Unable to retrive data for URI users: %s" % `e`)
+'''
class FavoriteUsers(resource.DirectoryResource):
@@ -237,7 +238,7 @@ def retriveChildren(self):
except Exception as e:
logging.warn("Unable to retrive data for groups: %s" % `e`)
-
+'''
class Groups(resource.DirectoryResource):
retriveLock = None
@@ -283,6 +284,7 @@ def retriveChildren(self):
except Exception as e:
logging.warn("Unable to retrive data for groups: %s" % `e`)
+'''
class Group(resource.DirectoryResource):

0 comments on commit 162398e

Please sign in to comment.