Hi Alan, et al - thanks for your response and your ideas. I sat down and did a little more coding so that I might tackle what I can and bring back where I am having trouble. I have implemented the basic 'tag_map' you suggested without a hitch using my own class and getitem/setitem builtins. Right now, if there is a one-to-one correlation between my *generic* key (as a standard between my music files) and the specific tag for the filetype, I am doing well.
However, everything is not so clear cut in the world of metatagging! My first stumbling block is that M4A files store the track number and track total in a single tuple ... but I need them as separate fields (which is how some of the other formats do it). This is going to be one of many hurdles -- I need a way to accomplish more than a one-to-one data map. See my code, below, as well as some command line examples where I am having trouble. I feel there may be a way to pass functions through my tag_map dictionary (maybe a lambda?!) but I can't get my head around what approach is best (I can't think of any approach, right now, actually). Code follows. Thanks again. class Tags(object): '''Wrapper class for a mutagen music file object.''' tag_map = {} def __init__(self, mutagen): self._mutagen = mutagen self.tags = {} def keys(self): '''Get list of generic tag keys in use''' keys = [] for k in self.tag_map.keys(): try: self._mutagen[self.tag_map[k]] keys.append(k) except KeyError: pass return keys def save(self): '''Save the mutagen changes.''' self._mutagen.save() class MP4Tags(Tags): tag_map = { # GENERIC : SPECIFIC 'title' : '\xa9nam', 'album' : '\xa9alb', 'artist' : '\xa9ART', 'albumartist' : 'aART', 'comment' : '\xa9cmt', 'compilation' : 'cpil', 'composer' : '\xa9wrt', 'genre' : '\xa9gen', 'discnumber' : 'disk', # returns: (2,10) need lmbda or something ?! 'disctotal' : 'disk', # returns: (2,10) need lmbda or something ?! 'year' : '\xa9day', 'tracknumber' : 'trkn', # returns: (2,10) need lmbda or something ?! 'tracktotal' : 'trkn' # returns: (2,10) need lmbda or something ?! } def __getitem__(self, key): try: return self._mutagen[self.tag_map[key]] except KeyError: pass def __setitem__(self, key, value): self._mutagen[self.tag_map[key]] = value #EOF **Here is how it works: >>> import tagging >>> from mutagen.mp4 import MP4 >>> mp4 = MP4('../tests/data/Compressed/M4A-256.m4a') >>> mp4_tags = tagging.MP4Tags(mp4) >>> mp4_tags['title'] [u'bob the builder'] # woo hoo! it works! >>> mp4_tags['title'] = [u'I can change the title!'] >>> mp4_tags['title'] [u'I can change the title!'] # changing the titles works too >>> mp4_tags['discnumber'] [(1, 1)] # TODO - I need to return disk[0][0] ... not the tuple >>> mp4_tags.save() So, I need to modify how the data is shown to me as well as how I would go about writing the data something like: return_tag(disk): return disk[0][0] save_tag(num): return [(%s, %s)] % ( num, somehow_get_the_original_second_value_before_re_saving) Thanks again and any advice or guidance about how to approach this is greatly appreciated. Damon On Sat, Apr 17, 2010 at 3:55 PM, Alan Gauld <alan.ga...@btinternet.com> wrote: > > "Damon Timm" <damont...@gmail.com> wrote > >> I am struggling, on a theoretical level, on how to map the various >> filetype's tag/key naming conventions. I have already created my own >> MusicFile objects to handle each filetype (with functions for >> encoding/decoding) but I can't wrap my head around how to map the >> tags. > > I'd define a mapping table per file type that maps from a standad > set of keys to the file specific tag. > > Then define a class that works with the generic tags. > You can then eirther subclass per file type and use the file specific > mapping(a class variable) to translate internally or just create a function > that takes the file mapping as a parameter(maybe in the init() ) and sets > it up for the generic methods to use. > >> And here is what I would need to do to find the song's TITLE text: >> >>>>> flac['title'] >> >> [u'Christmas Waltz'] >>>>> >>>>> mp3['TIT2'].text #notice this one takes another additional step, as >>>>> well, by specifying text ! >> >> [u'Christmas Waltz'] >>>>> >>>>> mp4['\xa9nam'] >> >> [u"Christmas Waltz"] > > So if the file is mp3 the generic > > foo.setTag('title') > > will inside the setTag method do > > def setTag(self, tag, value) > key = self.mapping[tag] # get file specific tag > fileData[key] = value # and use it > # or > self.value = fileData[key] > >> approach this. I know I could manually assign each key to a class >> property (using the @property tag) ... but this seems tedious: > > That would definitely be overklilll and not bvery flexible for adding new > file types. > > HTH, > > > -- > Alan Gauld > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > > _______________________________________________ > Tutor maillist - tu...@python.org > To unsubscribe or change subscription options: > http://mail.python.org/mailman/listinfo/tutor > _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor