So then I realized... "I'm a programmer, d*mnit! I can make this computer do what I want!"
That's when I set out to write a Python script to generate all my playlists for me, and I wanted it to write the playlists twice, once in the file where the ripped music itself was, and once more in a dedicated "Playlists" file in my Music directory.
After a few hours, here's my finished script:
import sys
import os
import re
# Sh*tty workaround for Python 2.5 relative imports
sys.path.append(os.path.join(os.getcwd(), ".."))
from oggvorbis import OggVorbis
class Album:
def __init__(self, filename):
self.file = filename
self.songs = []
def get_files(dir):
foundFiles = []
if dir[-1:] == "/":
dir = dir[0:-1]
for x in os.listdir(dir):
if os.path.isdir(dir + "/" + x):
foundFiles.extend(get_files(dir + "/" + x))
else:
if x[-3:] == "ogg":
foundFiles.append(dir + "/" + x)
return foundFiles
def compare_songs(first, second):
return int(first[:2]) - int(second[:2])
def get_and_split(dir):
files = get_files(dir)
retlist, templist = [], []
temp = files[0].split('/')[-2]
alb = Album(files[0].rpartition('/')[0])
for file in files:
temp2 = file.split('/')[-2]
if temp != temp2:
if alb.songs != []:
alb.songs.sort(cmp=compare_songs)
retlist.append(alb)
alb = Album(file.rpartition('/')[0])
temp = temp2
else:
st = file.rpartition('/')[2]
if re.search(r'^\d{1,2}(?=(\.\s|\s-\s))', st) != None:
alb.songs.append(st)
temp = temp2
return retlist
def make_playlist(alb):
"""This should get an Album object. To hell if I checked!"""
# Every file has this precise way to begin:
location = unicode(alb.file)
filestring = u"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + \
u"<playlist version=\"1\" xmlns=\"http://xspf.org/ns/0/\">\n" + \
u"\t<title>Playlist</title>\n\t<location>file://" + \
location + "/" + alb.file.rpartition("/")[2] + \
u".xspf</location>\n\t<trackList>\n"
addstring = u""
for song in alb.songs:
try: thefile = OggVorbis(os.path.join(alb.file, song))
except IOError: continue
addstring += u"\t\t<track>\n\t\t\t<location>" + location + u"/" + \
unicode(song, errors='replace') + u"</location>\n"
try: addstring += u"\t\t\t<title>" + thefile["title"][0] + u"</title>\n"
except KeyError: pass
try: addstring += u"\t\t\t<creator>" + thefile["artist"][0] + u"</creator>\n"
except KeyError: pass
try: addstring += u"\t\t\t<album>" + thefile["album"][0] + u"</album>\n"
except KeyError: pass
addstring += u"\t\t</track>\n"
filestring += addstring + u"\t</tracklist>\n</playlist>"
return filestring.replace("&", "&")
if len(sys.argv) != 2:
print "Not correct arguments. Please format your arguments"
print "like so: Program location"
exit(0)
# As per usual, my personal scripts don't have any error checking
# whatsoever. If you use it, you better know what it does!
loc = sys.argv[1]
if loc[-1:] == "/":
loc = loc[0:-1]
if not os.path.isdir(loc + "/Playlists"):
os.mkdir(loc + "/Playlists")
for x in get_and_split(loc):
y = make_playlist(x).encode('utf-8')
file = open(x.file + "/" + x.file.rpartition("/")[2] + ".xspf", "w")
file.write(y)
file = open(loc + "/Playlists/" + x.file.rpartition("/")[2] + ".xspf", "w")
file.write(y)
file.close()
It's probably a bit excessively long and not very pythonic. I wasn't going after making a production program, I had decided. Instead, I wanted something fast I could use. The only hairy part of this program was dealing with Unicode, since I wasn't expecting to have to at first, so you'll see some hastily-put-together Unicode support. Either way, this will produce .xspf playlists for VLC Media Player! I don't see any reason why it wouldn't work on Mac, however this was only tested and really used on a Linux machine. I can say with pretty clear certainty that this won't work on Windows, however I've heard that Python will natively switch slashes to their proper orientation when using them to open files. Still, the .xspf files will be written with hardcoded "/"s, so I don't think they'll work even if you did make the playlists. It shouldn't be terribly hard to modify this for Windows use, though!Yes, I realize there's no error checking, it's not the most efficient Python program, and all-in-all it's actually rather bad (such as completely ignoring certain Unicode Decoding errors), but this isn't meant to be a production program, it was a personal Quick-and-Dirty solution to me needing some playlists! If you choose to use it, you can use it like so:
python GenPlaylists.py /home/USERNAME/MusicAnd it should automatically go through each file, find any music that is in .ogg format and begins with either "XX -" or "XX. " (where X is a digit), and make playlists from them! Again, this was just a personal script, but I thought that, on the off chance someone else happens to have a similar set-up (with all their songs beginning with numbers and all in .ogg format) and wants the same thing, they can use it! This program relies on parts of Mutagen, which I have very kindly ripped apart, taken, and placed in a convenient attachment below (along with GenPlaylists, the above program). The easiest way to use it is to simply extract the file pretty much anywhere (MUST be named "PlaylistGen"), open that folder in the command line, and run the above command. That should work.
Since this is based on Mutagen, which is under the GNU General Public License Version 2, my program must also be. Otherwise I'd give it a more permissive license. I might update this in the future, but I doubt it. I think I should emphasize the part of the GPL that states this:
Quote
This program 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.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
EDIT: Smoothed out some Unicode support. VLC seems to have a problem opening up .xspf files that aren't formatted just for VLC, it keeps putting the first song on the bottom of the playlist and cutting off the last song entirely. Strange error, but I haven't encountered that error with any other program that supports opening XSPF playlists, so I can only conclude that VLC is doing it. >_<
Attached Files
Edited by ZekeDragon, 14 October 2009 - 06:34 PM.
Added Sorting algorithm. XD 2: Generic XSPF support, eliminated VLC specific code, smoothing out Unicode support


Sign In
Create Account


Back to top









