#!/usr/bin/env python ################################################################### # # RandSong: # Reads a text file containing a list of tracks and randomly # chooses songs. The songs are copied to a destination directory. # Intended to be used with portable mp3/ogg players to get a # random sampling of music from a larger collection. # # Author: Mike Pilone # http://www.slac.com/mpilone/projects/ # # License: BSD # http://www.opensource.org/licenses/bsd-license.html # # Copyright: 2002 Mike Pilone # # Modified: 02/15/02 # # Changelog: # v0.1: # o Initial release # ################################################################### import string, sys, random import os, shutil, stat, re APP_VERSION = "0.1" def loadPlaylist(playlist): "Loads the playlist from file into a list of strings" try: playlistFile = open(playlist, "r") except: print "Error opening file", playlist, ". Aborting..." sys.exit(0) lines = playlistFile.readlines() playlistFile.close() return lines def copyFiles(songs, size, dest): "Copies files from the song list to the destination dir" # Generate a random number random.shuffle(songs) # While the total size is less than the max and we haven't gotten to the # end of the list, copy the file to the destination numCopy = 0 totalSize = 0 for song in songs: song = song[:-1] # Trim return char filename = os.path.basename(song) # Check the file is valid. Sometimes playlists get out of date. if not os.path.isfile(song): print "WARNING:", filename, "doesn't seem to exist. Skipping..." continue st = os.lstat(song) if (st[stat.ST_SIZE] + totalSize <= (size*1024*1024)): print "\t\to", filename shutil.copy(song, dest) numCopy += 1 totalSize += st[stat.ST_SIZE] return numCopy def filterSongs(songs, songFilter): "Filters the list based on the regexp" prog = re.compile(songFilter) index = 0 while index < len(songs): song = songs[index] if not prog.match(song): del songs[index] else: index += 1 return songs def printUsage(appName): print "RandSong v" + APP_VERSION print "Usage:", appName, "[-sf] \n" print """ \tThe playlist to load from \tThe destination directory to copy to -s \tThe maximum total megabytes to copy [default: 30] -f \tA regular expression used to filter tracks [default: '.*']""" def main(): dest = "" playlist = "" songFilter = ".*" size = 30 # Check the args index = 1 while index < len(sys.argv): arg = sys.argv[index] index += 1 if arg == "-s": size = int(sys.argv[index]) index += 1 if arg == "-f": songFilter = sys.argv[index] index += 1 elif index == len(sys.argv): dest = arg else: playlist = arg if len(playlist) == 0 or len(dest) == 0: printUsage(sys.argv[0]) sys.exit(0) # Make sure dest is valid if not os.path.isdir(dest): print "Error: Destination not a valid directory. Aborting..." sys.exit(0) print "RandSong v" + APP_VERSION + " initialized" print "\to Loading playlist from file." # We have the playlist, now load it songs = loadPlaylist(playlist) print "\to Playlist contained", len(songs), "unfiltered tracks." print "\to Filtering tracks using '" + songFilter + "'" songs = filterSongs(songs, songFilter) print "\to Copying", size, "megabytes from " + str(len(songs)), print "tracks..." numCopy = copyFiles(songs, size, dest) print "\to Finished.", numCopy, "tracks copied to", dest if __name__ == "__main__": main()