[Tutor] How to map different keys together ?

Damon Timm damontimm at gmail.com
Mon Apr 19 01:43:49 CEST 2010


Thanks again for your input.  Comments below with working (yea!) code.

On Sun, Apr 18, 2010 at 3:23 PM, ALAN GAULD <alan.gauld at btinternet.com> wrote:
> Does what I've shown make sense?

Alan - I think I got my mind around it -- I had never used lambda
functions before, so this is new territory to me.  Thanks for the
examples and I think it has me in the right direction.  I included
updated code below, which is working.

2010/4/18 spir ☣ <denis.spir at gmail.com>:
> All of this is not only plain data, but constant! The case of non-exisitng tag for a given format is, as shown by your 'pass', not to be handled here. Using a class is not only averkill but (wrong in my opininon and) misleading.
>
> Anyway it won't work since you need more than simple lookup in the case above, meaning some process must be done, and also the case of mp3 (iirc) titles shown in your first post.

Denis - I thought that with all the extra functions that would be
needed, making a class would simplify it for the user (me, in this
case).  I actually have another class that this will be merged into
(maybe it will make more sense then) ... I was just setting up the Tag
classes so I didn't confuse everyone with all the other code ...

Again - I believe I am on the right track (even if it is overkill --
wink).  Here is what I updated and what is working:

class TagNotSupported(Exception):
    '''Raised when trying to use a tag that is not currently supported across
    filetypes.  Hopefully we cover enough so this does not happen!'''

def set_tag(mutagen, tag, value):
    mutagen[tag] = value

class Tags(object):
    '''Wrapper class for a mutagen music file object.'''
    _get_tags = {}
    _set_tags = {}

    def __init__(self, mutagen):
        '''Requires a loaded mutagen object to get us rolling'''
        self._mutagen = mutagen

    def keys(self):
        '''Get list of tag keys in the file.'''
        keys = []
        for key in self._get_tags.keys():
            try:
                self._get_tags[key](self._mutagen)
                keys.append(key)
            except KeyError:
                pass
        return keys

    def save(self):
        '''Save the mutagen changes.'''
        self._mutagen.save()

class MP4Tags(Tags):

    _get_tags = {
        'album'         : lambda x: x['\xa9alb'],
        'artist'        : lambda x: x['\xa9ART'],
        'albumartist'   : lambda x: x['aART'],
        'compilation'   : lambda x: x['cpil'],
        'composer'      : lambda x: x['\xa9wrt'],
        'description'   : lambda x: x['\xa9cmt'],
        'discnumber'    : lambda x: [str(x['disk'][0][0]).decode('utf-8')],
        'disctotal'     : lambda x: [str(x['disk'][0][1]).decode('utf-8')],
        'genre'         : lambda x: x['\xa9gen'],
        'title'         : lambda x: x['\xa9nam'],
        'tracknumber'   : lambda x: [str(x['trkn'][0][0]).decode('utf-8')],
        'tracktotal'    : lambda x: [str(x['trkn'][0][1]).decode('utf-8')],
        'date'          : lambda x: x['\xa9day'],
        }

    _set_tags = {
        'album'         : lambda x, v: set_tag(x._mutagen, '\xa9alb', v),
        'albumartist'   : lambda x, v: set_tag(x._mutagen, 'aART',    v),
        'artist'        : lambda x, v: set_tag(x._mutagen, '\xa9ART', v),
        'compilation'   : lambda x, v: set_tag(x._mutagen, 'cpil',    v),
        'composer'      : lambda x, v: set_tag(x._mutagen, '\xa9wrt', v),
        'description'   : lambda x, v: set_tag(x._mutagen, '\xa9cmt', v),
        'discnumber'    : lambda x, v: x.x_of_y('disk', 0, v),
        'disctotal'     : lambda x, v: x.x_of_y('disk', 1, v),
        'genre'         : lambda x, v: set_tag(x._mutagen, '\xa9gen', v),
        'title'         : lambda x, v: set_tag(x._mutagen, '\xa9nam', v),
        'tracknumber'   : lambda x, v: x.x_of_y('trkn', 0, v),
        'tracktotal'    : lambda x, v: x.x_of_y('trkn', 1, v),
        'date'          : lambda x, v: set_tag(x._mutagen, '\xa9day', v),
    }

    def __getitem__(self, key):
        try:
            return self._get_tags[key](self._mutagen)
        except KeyError:
            pass

    def __setitem__(self, key, value):
        try:
            self._set_tags[key](self, value)
        except KeyError:
            raise TagNotSupported('The tag "' + key + '" is not supported.')

    def x_of_y(self, key, index, value):
        '''Used to set our disc and track information.  MP4 stores everything
        in a tuple of (x,y).'''

        try: # if this value is not already set, we need defaults
            init_val = self._mutagen[key][0]
        except KeyError:
            init_val = (0,0)

        try: # mutagen often passes things in lists, eg [u'1']
            value = int(value)
        except TypeError:
            value = int(value[0])

        if not index: # if index == 0
            self._mutagen[key] = [(value, init_val[1])]
        else: # if index == 1
            self._mutagen[key] = [(init_val[0], value)]

Thanks again.


More information about the Tutor mailing list