# HG changeset patch # User brad # Date 1352509859 21600 # Node ID af65171c2294aa39fb0c98dfed5be23daa92697d Read support, experimental write support (.dat only) diff -r 000000000000 -r af65171c2294 Media.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Media.py Fri Nov 09 19:10:59 2012 -0600 @@ -0,0 +1,10 @@ +class Media: + + file_name = title = artist = album = genre = comment = album_artist = \ + composer = publisher = category = year = track = length = type = \ + last_update = last_play = rating = play_count = file_time = \ + file_size = bit_rate = disc = replaygain_album_gain = \ + replaygain_track_gain = bpm = discs = tracks = is_podcast = \ + podcast_channel = podcast_pub_date = gracenote_file_id = \ + gracenote_ext_data = lossless = codec = director = producer = width = \ + height = tuid2 = None diff -r 000000000000 -r af65171c2294 WinampLibrary.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WinampLibrary.py Fri Nov 09 19:10:59 2012 -0600 @@ -0,0 +1,260 @@ +import os +import struct +import Media +import time +from datetime import datetime + +class WinampLibrary: + + base_dir = '' + # Fields mappings in the format: + # : {'name': , 'type': , 'winamp_id': } + field_encode = { + 'file_name': {'name': 'filename', 'type': 12, 'winamp_id': 0}, + 'title': {'name': 'title', 'type': 3, 'winamp_id': 1}, + 'artist': {'name': 'artist', 'type': 3, 'winamp_id': 2}, + 'album': {'name': 'album', 'type': 3, 'winamp_id': 3}, + 'year': {'name': 'year', 'type': 4, 'winamp_id': 4}, + 'genre': {'name': 'genre', 'type': 3, 'winamp_id': 5}, + 'comment': {'name': 'comment', 'type': 3, 'winamp_id': 6}, + 'album_artist': {'name': 'albumartist', 'type': 3, 'winamp_id': 20}, + 'composer': {'name': 'composer', 'type': 3, 'winamp_id': 24}, + 'publisher': {'name': 'publisher', 'type': 3, 'winamp_id': 23}, + 'category': {'name': 'category', 'type': 3, 'winamp_id': 34}, + 'track': {'name': 'trackno', 'type': 4, 'winamp_id': 7}, + 'length': {'name': 'length', 'type': 11, 'winamp_id': 8}, + 'type': {'name': 'type', 'type': 4, 'winamp_id': 9}, + 'last_update': {'name': 'lastupd', 'type': 10, 'winamp_id': 10}, + 'last_play': {'name': 'lastplay', 'type': 10, 'winamp_id': 11}, + 'rating': {'name': 'rating', 'type': 4, 'winamp_id': 12}, + 'play_count': {'name': 'playcount', 'type': 4, 'winamp_id': 15}, + 'file_time': {'name': 'filetime', 'type': 10, 'winamp_id': 16}, + 'file_size': {'name': 'filesize', 'type': 4, 'winamp_id': 17}, + 'bit_rate': {'name': 'bitrate', 'type': 4, 'winamp_id': 18}, + 'disc': {'name': 'disc', 'type': 4, 'winamp_id': 19}, + 'replaygain_album_gain': {'name': 'replaygain_album_gain', 'type': 3, 'winamp_id': 21}, + 'replaygain_track_gain': {'name': 'replaygain_track_gain', 'type': 3, 'winamp_id': 22}, + 'bpm': {'name': 'bpm', 'type': 4, 'winamp_id': 25}, + 'discs': {'name': 'discs', 'type': 4, 'winamp_id': 26}, + 'tracks': {'name': 'tracks', 'type': 4, 'winamp_id': 27}, + 'is_podcast': {'name': 'ispodcast', 'type': 4, 'winamp_id': 28}, + 'podcast_channel': {'name': 'podcastchannel', 'type': 3, 'winamp_id': 29}, + 'podcast_pub_date': {'name': 'podcastpubdate', 'type': 10, 'winamp_id': 30}, + 'gracenote_file_id': {'name': 'GracenoteFileID', 'type': 3, 'winamp_id': 31}, + 'gracenote_ext_data': {'name': 'GracenoteExtData', 'type': 3, 'winamp_id': 32}, + 'lossless': {'name': 'lossless', 'type': 4, 'winamp_id': 33}, + 'codec': {'name': 'codec', 'type': 3, 'winamp_id': 35}, + 'director': {'name': 'director', 'type': 3, 'winamp_id': 36}, + 'producer': {'name': 'producer', 'type': 3, 'winamp_id': 37}, + 'width': {'name': 'width', 'type': 4, 'winamp_id': 38}, + 'height': {'name': 'height', 'type': 4, 'winamp_id': 39}, + 'tuid2': {'name': 'tuid2', 'type': 3, 'winamp_id': 14}, + } + field_decode = dict((v['name'], k) for k, v in field_encode.iteritems()) + medias = [] + + #def __init__(self): + # self.base_dir = base_dir + + def files_from_path(self, path): + path = os.path.normpath(path) + if not os.path.isdir(path): + path = os.path.dirname(path) + idxfile = os.path.join(path, 'main.idx') + datfile = os.path.join(path, 'main.dat') + return idxfile, datfile + + def read(self, path): + self.fields = {} + idxfile, datfile = self.files_from_path(path) + if not os.path.isfile(idxfile): + raise IOError('Could not find Winamp library index file ' + idxfile) + if not os.path.isfile(idxfile): + raise IOError('Could not find Winamp library data file ' + datfile) + + idx = open(idxfile, 'rb') + if idx.read(8) != 'NDEINDEX': + idx.close() + raise Exception(idxfile + ' does not appear to be a valid Winamp library index file') + num_records, = struct.unpack(' 1: # not column or index field + return media + +lib = WinampLibrary() +lib.read('C:\\Users\\Brad\\AppData\\Roaming\\Winamp\\Plugins\\ml') +lib.write('C:\\Users\\Brad\\AppData\\Roaming\\Winamp\\Plugins\\ml\\out') diff -r 000000000000 -r af65171c2294 test.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test.py Fri Nov 09 19:10:59 2012 -0600 @@ -0,0 +1,4 @@ +import Media + +media = Media.Media() +media.artist = 'asdf' \ No newline at end of file