Recent Changes - Search:

Bob Brandt

Linux Projects


Server Projects

Desktop Projects

Novell Projects


VMware Projects


N900 (Maemo) Projects


Python Projects


OpenOffice.org Projects


Other Projects


PmWiki

edit SideBar

Playlist Sync

N900.PlaylistSync History

Hide minor edits - Show changes to output

March 12, 2010, at 03:03 PM by 137.191.238.232 -
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 137.191.238.232 -
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:)
Edit - History - Print - Recent Changes - Search
Page last modified on March 12, 2010, at 03:03 PM