コード例 #1
0
ファイル: artist.py プロジェクト: lidel/mmda
def _create_shallow_releases_mb(mb_artist):
    """
    Create CachedReleaseGroup documents using basic MusicBrainz data fetched with artist.

    @param mb_artist: a musicbrainz2.model.Artist object
    """
    mb_releases = mb_artist.getReleases()
    artist_mbid = extractUuid(mb_artist.id)

    # magical place where all data is cached/processed before database commit
    there_will_be_dragons = {}

    for mb_release in mb_releases:
        group_mbid      = extractUuid(mb_release.releaseGroup.id)
        release_mbid    = extractUuid(mb_release.id)

        # its ugly, but we fill this only once (place for future improvements)
        if group_mbid not in there_will_be_dragons:
            release_group                       = {}
            release_group['_id']                = group_mbid
            release_group['artist_mbid']        = artist_mbid
            release_group['artist_name']        = mb_artist.name
            release_group['title']              = mb_release.releaseGroup.title
                                                # small fix: in some rare cases, ReleaseGroup at Musicbrainz has no 'type' property
            release_group['release_type']       = decruft_mb(mb_release.releaseGroup.type) if mb_release.releaseGroup.type else 'Other'
            release_group['releases']           = {}
            there_will_be_dragons[group_mbid]   = release_group
        else:
            release_group = there_will_be_dragons[group_mbid]

        # store only basic information about release event
        mb_release_events = []
        for mb_event in mb_release.getReleaseEvents():
            event = {}
            if mb_event.date:
                event['date']    = mb_event.date
            if mb_event.format:
                event['format']  = decruft_mb(mb_event.format)
            if mb_event.country:
                event['country'] = mb_event.country
            if event:
                mb_release_events.append(event)

        release_group['releases'][release_mbid] = {
                'title':mb_release.title,
                'tracks_count':mb_release.tracksCount,
                'release_events':mb_release_events,
                'cache_state':{'mb':[1,datetime.utcnow()]}
                }

        # primary release is the one with earliest release date (place for future improvements)
        mb_earliest_release_date = mb_release.getEarliestReleaseEvent().getDate() if mb_release.getEarliestReleaseEvent() else None
        if 'primary' not in release_group or release_group['primary'][1] == None or mb_earliest_release_date < release_group['primary'][1]:
            release_group['primary'] = [release_mbid, mb_earliest_release_date]

    # just to make sure no old data is left..
    old_cached_release_groups = get_db('artists').view('artists/release_groups', key=artist_mbid)
    for group in old_cached_release_groups:
        del get_db('artists')[group['id']]

    for release_group in there_will_be_dragons.itervalues():
        cached_release_group = CachedReleaseGroup.wrap(release_group) # TODO: think if wrap is the best way of dealing with this
        cached_release_group.cache_state['mb'] = [1,datetime.utcnow()]
        cached_release_group.save() # TODO: add try in case of ResourceConflict? 
        mmda_logger('db','store', cached_release_group)
コード例 #2
0
ファイル: release.py プロジェクト: lidel/mmda
def _populate_deep_release_mb(release_group,release_mbid):
    """
    Make sure ReleaseGroup contains additional, detailed information about specified release.

    @param release_group: a CachedReleaseGroup object
    @param release_mbid:  a string containing a MusicBrainz ID of a release

    @return: a verified/updated CachedReleaseGroup object
    """
    release = release_group.releases[release_mbid]
    if release['cache_state']['mb'][0] == 1:
        # TODO: remove unused includes
        try:
            t = mmda_logger('mb','request','release',release_mbid)
            mb_release  = mb_query.getReleaseById(release_mbid, MB_RELEASE_INCLUDES)
            mmda_logger('mb','result','release',mb_release.title,t)
        except WebServiceError, e:
            # TODO: hard error here
            mmda_logger('mb-release','ERROR',e)
            raise e
        else:
            # make sure mbid of an artist is present
            if 'artist_mbid' not in release_group:
                release_group.artist_mbid = extractUuid(mb_release.artist.id)

            # TRACK LISTING
            # TODO: think about duration representation here
            tracks = []
            for mb_track in mb_release.tracks:
                track = {'title':mb_track.title, 'mbid':extractUuid(mb_track.id)}
                if mb_track.duration:
                    track['duration'] = humanize_duration(mb_track.duration)
                tracks.append(track)
            release['tracks'] = tracks

            # URL relations
            urls = {}
            for relation in mb_release.getRelations(Relation.TO_URL):
                relation_type = decruft_mb(relation.type)
                if relation_type not in urls:
                    urls[relation_type] = []
                urls[relation_type].append(relation.targetId)
            # urls is used in many places, so its handy to have it ready
            release['urls'] = urls

            # CREDIT relations
            credits = [{'type':decruft_mb(r.type), 'mbid':extractUuid(r.targetId), 'name':r.target.name} for r in mb_release.getRelations(Relation.TO_ARTIST)]
            if credits:
                release['credits'] = credits

            # MULTI-DISC-RELEASE information
            remasters = []
            for relation in mb_release.getRelations(Relation.TO_RELEASE):
                relation_type = decruft_mb(relation.type)
                linked_release = {'mbid':extractUuid(relation.targetId), 'title':relation.target.title}

                if relation_type == 'PartOfSet':
                    if relation.direction == 'backward':
                        release['set_prev'] = linked_release
                    else:
                        release['set_next'] = linked_release

                elif relation_type == 'Remaster':
                    if relation.direction == 'backward':
                        remasters.append(linked_release)
                    else:
                        release['remaster_of'] = linked_release
            if remasters:
                release['remasters'] = remasters

            release['cache_state']['mb'] = [2,datetime.utcnow()]
            release_group = _perform_cover_lookup_on_mb_data(release_group, release_mbid)
            release_group.changes_present = True
コード例 #3
0
ファイル: artist.py プロジェクト: lidel/mmda
def _populate_artist_mb(artist, mb_artist):
    """
    Process data from MusicBrainz and store it in dedicated structures of CachedArtist.

    @param artist: a CachedArtist object
    @param mb_artist: a musicbrainz2.model.Artist object

    @return: a populated CachedArtist object
    """
    artist.artist_type          = decruft_mb(mb_artist.type)
    artist.name                 = mb_artist.name
    artist.sort_name            = mb_artist.sortName

    if mb_artist.disambiguation:
        artist.disambiguation   = mb_artist.disambiguation
    if mb_artist.aliases:
        artist.aliases          = [a.value for a in mb_artist.aliases]

    if mb_artist.beginDate or mb_artist.endDate:
        artist.dates = {}
    if mb_artist.beginDate:
        artist.dates['from']    = mb_artist.beginDate
    if mb_artist.endDate:
        artist.dates['to']      = mb_artist.endDate

    # urls are stored in dict with lists as values (there can be many of the same type)
    urls = {}
    for relation in mb_artist.getRelations(Relation.TO_URL):
        relation_type = decruft_mb(relation.type)
        if relation_type not in urls:
            urls[relation_type] = []
        urls[relation_type].append(relation.targetId)
    if urls:
        artist.urls = urls

    # on the other hand, memberships and collaborations are stored in lists of dicts ;-)
    members             = []
    member_of           = []
    collaborations      = []
    collaboration_of    = []

    for relation in mb_artist.getRelations(Relation.TO_ARTIST):
        relation_type = decruft_mb(relation.type)
        if relation_type == 'MemberOfBand':
            member_info = {
                    'name':relation.target.name,
                    'mbid':extractUuid(relation.targetId),
                    'from':relation.beginDate,
                    'to':relation.endDate
                    }
            if relation.direction == 'backward':
                members.append(member_info)
            else:
                member_of.append(member_info)
        elif relation_type == 'Collaboration':
            member_info = {
                    'name':relation.target.name,
                    'mbid':extractUuid(relation.targetId)
                    }
            if relation.direction == 'backward':
                collaboration_of.append(member_info)
            else:
                collaborations.append(member_info)

    if members:
        artist.members          = members
    if member_of:
        artist.member_of        = member_of
    if collaborations:
        artist.collaborations   = collaborations
    if collaboration_of:
        artist.collaboration_of = collaboration_of
    return artist