import time, os.path, hashlib, mutagen def log(x): print x def detect_filetype( filepath ): if len(filepath.split('.')) > 1: return filepath.rsplit('.',1)[1].lower() else: return None class Playlist(object): def __init__(self): self.filename = None # The object's unique identifier self.hash = None self.__current_file = 0 self.__filelist = [] def append( self, fileobject ): """ Append a FileObject to the queue """ if isinstance( fileobject, FileObject ): # if self.__filelist: # fileobject.prev = self.__filelist[-1] # self.__filelist[-1].next = fileobject self.__filelist.append( fileobject ) else: log('fileobject must be of type FileObject!') def append_filepath( self, filepath ): if os.path.exists(filepath): self.append( FileObject(filepath,self) ) else: log('File cannot be found: %s' % filepath) def get_current_file(self): """ Get the FileObject of the current file """ if self.__filelist: return self.__filelist[self.__current_file] def md5( self, string ): """ Return the md5sum of string """ return hashlib.md5(string).hexdigest() ################################## # File importing functions ################################## def m3u_importer( self, filename ): """ Import an m3u playlist TODO: make this actually support proper m3u playlists... """ f = open( filename, 'r' ) files = f.read() self.hash = self.md5(files) files = files.splitlines() f.close() for f in files: if not f: continue self.append_filepath(f) def single_file_import( self, filename ): """ Add a single track to the playlist """ self.append_filepath( filename ) ################################## # Plalist controls ################################## def play(self): """ This gets called by the player to get the file to play and the last time it was paused. """ current_file = self.get_current_file() pause_time = current_file.play() return ( current_file.filepath, pause_time ) def pause(self, position): """ Called whenever the player is paused """ current_file = self.get_current_file() current_file.pause(position) def skip(self, skip_by=None, skip_to=None, dont_loop=False): """ Skip to another track in the playlist. Use either skip_by or skip_to, skip_by has precedence. skip_to: skip to a known playlist position skip_by: skip by n number of episodes (positive or negative) dont_loop: applies only to skip_by, if we're skipping past the last track loop back to the begining. """ if not self.__filelist: return False if skip_by is not None: if dont_loop: skip = self.__current_file + skip_by else: skip = ( self.__current_file + skip_by ) % len(self.__filelist) elif skip_to is not None: skip = skip_to else: log('No skip method provided...') if not ( 0 <= skip < len(self.__filelist) ): log('Can\'t skip to non-existant file. (requested=%d, total=%d)' % ( skip, len(self.__filelist)) ) return False self.__current_file = skip log('Skipping to file %d (%s)' % (skip, self.get_current_file().filepath) ) return True def next(self): """ Move the playlist to the next track. False indicates end of playlist. """ return self.skip( skip_by=1, dont_loop=True ) def prev(self): """ Same as next() except moves to the previous track. """ return self.skip( skip_by=-1, dont_loop=True ) class FileObject(object): def __init__(self, filepath, playlist): self.last_listened_time = 0 # time is secs since the file was played self.pause_time = 0 # if the file was paused, that time in ns self.filepath = filepath # the full path to the file self.playlist = playlist # the Playlist object that this belongs to # cached file metadata self.title = None self.artist = None self.album = None self.length = None self.coverart = None self.extract_metadata() def extract_metadata(self): filetype = detect_filetype(self.filepath) File = mutagen.File(self.filepath) self.length = File.info.length if filetype == 'mp3': for tag,value in File.iteritems(): if tag == 'TIT2': self.title = value elif tag == 'TALB': self.album = value elif tag == 'TPE1': self.artist = value elif tag == 'APIC': self.coverart = value elif filetype in ['ogg', 'flac']: for tag,value in File.iteritems(): if tag == 'title': self.title = value elif tag == 'album': self.album = value elif tag == 'artist': self.artist = value else: self.title = os.path.basename( self.filepath ).rsplit('.',1)[0].replace('_', ' ') def play(self): self.last_listened_time = time.time() return self.pause_time def pause(self, position): """ position = nanoseconds into the file """ self.pause_time = position if __name__ == '__main__': p = Playlist() p.m3u_importer( 'flobots.m3u' ) while p.next(): print p.get_current_file().title while p.prev(): pass