|
N900 /
Playlist SyncN900.PlaylistSync HistoryHide minor edits - Show changes to output March 12, 2010, at 03:03 PM
by -
Added lines 9-10:
This is a work in progress so nothing is guaranteed! Right now I am using my Wiki as a means of transferring code between different sites. March 10, 2010, at 03:48 PM
by -
Added lines 1-201:
(:title Playlist Sync:) While the N900 is AWESOME, it is really new and some things are just not quite perfect yet! One of these things is the playlist editor for the default Media Player. That is to say that there ISN'T a playlist editor!! Now my computer at home has an many, many great playlist editors... So why not use them?? This program will sync playlists between your N900 and your home machine. (Actually it will sync playlists between any two machines) (:div style="border-style:ridge; border-width:2px; background-color:#ffffcc; margin-left:50px; overflow:auto; font-size:small; width:650px; height:500px;":) [@ #!/usr/bin/python # -*- coding: utf-8 -*- """ PlaylistSync by Bob Brandt (projects@brandt.ie). Licensed under GPL version 3 Created on 10 March 2010 """ import sys, os, optparse, re version = "0.1" class playlistsync(object): ''' This class is used to sync a playlist from one device to another and all relevant files ''' def __init__(self, sourceRoot, destMountPoint, destRoot = None, hierarchical = False, debug = False): if os.path.isdir(sourceRoot): self.__sourceRoot = sourceRoot else: raise IOError, "There is no such directory: '%s'" % sourceRoot if os.path.isdir(destMountPoint): self.__destMountPoint = destMountPoint else: raise IOError, "There is no such directory: '%s'" % destMountPoint if not destRoot: destRoot = destMountPoint self.__destRoot = destRoot self.__hierarchical = bool(hierarchical) self.__sourcePlaylists = self.__loadplaylists(self.__sourceRoot) self.__destPlaylists = self.__loadplaylists(self.__destMountPoint) self.__playlists = {} for playlist in self.__sourcePlaylists.keys(): if playlist in self.__destPlaylists.keys(): self.__playlists[playlist] = {"source":self.__sourcePlaylists[playlist], "dest":self.__destPlaylists[playlist]} playlistextenstions = property(lambda self: (".m3u",".pls") ) sourcePlaylists = property(lambda self: self.__sourcePlaylists ) destPlaylists = property(lambda self: self.__destPlaylists ) playlists = property(lambda self: self.__playlists ) def __loadplaylists(self, root): playlists = {} def checknames(junk, dirpath, namelist): for name in namelist: if os.path.splitext(name)[1].lower() in self.playlistextenstions: playlists[os.path.splitext(name)[0].lower()] = os.path.join(dirpath,name) os.path.walk(root, checknames, None) return playlists def __isInPlaylist(self, Playlist, PlayLists): Playlist = str(Playlist).lower() if Playlist in PlayLists.keys(): return {"name":Playlist, "path":PlayLists[Playlist] } for tmp in PlayLists.keys(): if Playlist == str(PlayLists[tmp]).lower(): return {"name":Playlist, "path":PlayLists[tmp] } return None def addPlaylist(self, Playlist): tmpPlaylist = str(Playlist).lower() path = "" if self.__isInPlaylist(tmpPlaylist, self.__playlists): raise ValueError, "%s is already being synced." % Playlist self.__convertplaylist(tmpPlaylist) def __convertplaylist(self, Playlist): if not self.__isInPlaylist(Playlist, self.__sourcePlaylists): raise IOError, "There is no such playlist: '%s' underneath: %s" % ( Playlist , self.__sourceRoot ) f = open(self.__isInPlaylist(Playlist, self.__sourcePlaylists)["path"], "r") playlisttext = f.read() f.close() pathseperator = os.path.normpath("/") extension = os.path.splitext(self.__isInPlaylist(Playlist, self.__sourcePlaylists)["path"])[1].lower() if extension == ".m3u" and self.__hierarchical: search = re.compile("^" + self.__sourceRoot + pathseperator, re.IGNORECASE | re.MULTILINE | re.UNICODE) replace = self.__destRoot + pathseperator elif extension == ".m3u" and not self.__hierarchical: search = re.compile("^" + self.__sourceRoot + ".*" + pathseperator, re.IGNORECASE | re.MULTILINE | re.UNICODE) replace = self.__destRoot + pathseperator elif extension == ".pls" and self.__hierarchical: search = re.compile("=" + self.__sourceRoot + pathseperator, re.IGNORECASE | re.MULTILINE | re.UNICODE) replace = "=" + self.__destRoot + pathseperator elif extension == ".pls" and not self.__hierarchical: search = re.compile("=" + self.__sourceRoot + ".*" + pathseperator, re.IGNORECASE | re.MULTILINE | re.UNICODE) replace = "=" + self.__destRoot + pathseperator else: search = None replace = None if not (search and replace) : raise ValueError, "Invalid Extension or Hierarchical Setting: %s, %s" % ( str(extension), str(self.__hierarchical) ) playlisttext = search.sub(replace, playlisttext) if self.__hierarchical: search = re.compile("^/home/BrandtB/Desktop/playlists-orig.*" + pathseperator, re.IGNORECASE | re.MULTILINE | re.UNICODE) else: search = re.compile("^/home/BrandtB/Desktop/playlists-orig" + pathseperator, re.IGNORECASE | re.MULTILINE | re.UNICODE) replace = "/home/BrandtB/Desktop/playlists-dest" + pathseperator filename = search.sub(replace, self.__isInPlaylist(Playlist, self.__sourcePlaylists)["path"]) f = open(filename, "w") f.write(playlisttext) f.flush() f.close() def removePlaylist(self, Playlist): tmpPlaylist = str(Playlist).lower() path = "" if not self.__isInPlaylist(tmpPlaylist, self.__playlists): raise ValueError, "%s is not being synced." % Playlist os.remove(self.__destPlaylists[tmpPlaylist]) def listPlayLists(self): allplaylists = {} for playlist in self.__sourcePlaylists.keys(): allplaylists[playlist] = {"source":True, "dest":False} for playlist in self.__destPlaylists.keys(): if allplaylists.has_key(playlist): allplaylists[playlist]["dest"] = True else: allplaylists[playlist] = {"dest":True, "source":False} length = 0 for playlist in allplaylists.keys(): if len(playlist) > length: length = len(playlist) print "Playlists:" for playlist in allplaylists.keys(): if allplaylists[playlist]["source"] and allplaylists[playlist]["dest"]: print playlist + " " * (length - len(playlist)) + "\t" + "Sync" else: print playlist + " " * (length - len(playlist)) + "\t" + "Available" print "\n" def syncPlaylists(self): pass def cleanupPlaylists(self): pass if __name__ == '__main__': usageText="usage: %prog [options] Source Destination RemotePath" versionText = "\n" + " ".join(["GNU","%prog",str(version)]) + "\n" versionText += "This program is distributed in the hope that it will be useful,\n" versionText += "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" versionText += "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" versionText += "GNU General Public License for more details.\n\n" versionText += "Originally written by Bob Brandt <projects@brandt.ie>.\n" parser = optparse.OptionParser(usage=usageText, version=versionText) parser.add_option("-a", "--add", dest="add", default="", type="string", help="Add playlist to sync list.") parser.add_option("-r", "--remove", dest="remove", default="", type="string", help="Remove playlist from sync list.") parser.add_option("-l", "--list", dest="list", action="store_true", default=False, help="List all playlists and whether or not they will be synced.") parser.add_option("-c", "--cleanup", dest="cleanup", action="store_true", default=False, help="Remove all media not specified in the playlists.") parser.add_option("-t", "--tree", dest="tree", action="store_true", default=False, help="Keep tree structure when copying files.") parser.add_option("-d", "--debug", dest="debug", action="store_true", default=False, help="To run the command in Debug mode.") (options, args) = parser.parse_args() # Source = args[0] # Destination = args[1] # RemotePath = args[2] Source = "/home/BrandtB/Desktop/playlists-orig" Destination = "/home/BrandtB/Desktop/playlists-dest" RemotePath = "/home/user/MyDocs/Music" options.tree = False options.list = True temp = playlistsync(Source, Destination, RemotePath, options.tree, options.debug) if options.add: temp.addPlaylist(options.add) if options.remove: temp.removePlaylist(options.remove) if options.list: temp.listPlayLists() if not (options.add or options.remove or options.list or options.cleanup): temp.syncPlaylists() if options.cleanup: temp.cleanupPlaylists() sys.exit() @] (:divend:) |