def test_work_metadata(): # load the audio metadata for the work mbids audio_meta = _get_saved_meta('audio_meta.json') # get the work metadata work_metadata = WorkMetadata(print_warnings=True) work_meta = [] for w in audio_meta['works']: work_meta.append(work_metadata.from_musicbrainz(w['mbid'])) # load the metadata computed earlier saved_meta = _get_saved_meta('work_meta.json') assert work_meta == saved_meta, 'test_work_metadata failed'
def __init__(self, get_recording_rels=False): self._audioMetadata = AudioMetadata( get_work_attributes=False, print_warnings=False) self._workMetadata = WorkMetadata( get_recording_rels=get_recording_rels, print_warnings=False)
class MusicBrainzMetadata(object): def __init__(self, get_recording_rels=False): self._audioMetadata = AudioMetadata( get_work_attributes=False, print_warnings=False) self._workMetadata = WorkMetadata( get_recording_rels=get_recording_rels, print_warnings=False) @property def get_recording_rels(self): return self._workMetadata.get_recording_rels @get_recording_rels.setter def get_recording_rels(self, value): self._workMetadata.get_recording_rels = value def crawl_musicbrainz(self, mbid): if mbid is None: # empty mbid return {'makam': {}, 'form': {}, 'usul': {}, 'name': {}, 'composer': {}, 'lyricist': {}} try: # attempt crawling mbid = self._parse_mbid(mbid) try: # assume mbid is a work data = self._workMetadata.from_musicbrainz(mbid) data['work'] = {'title': data.pop("title", None), 'mbid': data.pop('mbid', None)} except musicbrainzngs.ResponseError: # assume mbid is a recording data = self._audioMetadata.from_musicbrainz(mbid) data['recording'] = {'title': data.pop("title", None), 'mbid': data.pop('mbid', None)} if self.get_recording_rels: warnings.warn(u"Recording mbid is given. Ignored " u"get_recording_rels boolean.", stacklevel=2) self._add_mb_attributes(data) return data except musicbrainzngs.NetworkError: warnings.warn("Musicbrainz is not available, skipping metadata " "crawling...", stacklevel=2) return {'makam': {}, 'form': {}, 'usul': {}, 'name': {}, 'composer': {}, 'lyricist': {}, 'url': ''} @staticmethod def _add_mb_attributes(data): # scores should have one attribute per type for attr in ['makam', 'form', 'usul']: try: data[attr] = data[attr][0] except (IndexError, KeyError): warnings.warn( "Missing the {0:s} attribute in MusicBrainz".format(attr), stacklevel=2) data.pop(attr, None) @staticmethod def _parse_mbid(mbid): o = urlparse(mbid) # if the url is given get the mbid, which is the last field o_splitted = o.path.split('/') mbid = o_splitted[-1] return mbid @staticmethod def validate_mb_attribute(attrib_dict, score_attrib, scorename): is_attribute_valid = True if 'mb_attribute' in score_attrib.keys(): # work skip_makam_slug = ['12212212', '22222221', '223', '232223', '262', '3223323', '3334', '14_4'] if score_attrib['symbtr_slug'] in skip_makam_slug: warnings.warn(u'{0:s}: The usul attribute is not stored in ' u'MusicBrainz.'.format(scorename), stacklevel=2) else: if not score_attrib['mb_attribute'] == \ attrib_dict['dunya_name']: # dunya_names are (or should be) a superset of the # musicbrainz attributes is_attribute_valid = False if score_attrib['mb_attribute']: warn_str = u'{0:s}, {1:s}: The MusicBrainz ' \ u'attribute does not match.' \ u''.format(scorename, score_attrib['mb_attribute']) warnings.warn(warn_str.encode('utf-8'), stacklevel=2) else: warnings.warn(u'{0:s}: The MusicBrainz attribute does' u' not exist.'.format(scorename), stacklevel=2) return is_attribute_valid @staticmethod def validate_mb_attribute_tag(attrib_dict, score_attrib, scorename): is_attribute_valid = True has_mb_tag = 'mb_tag' in score_attrib.keys() if has_mb_tag and score_attrib['mb_tag'] not in attrib_dict['mb_tag']: is_attribute_valid = False warn_str = u'{0!s}, {1!s}: The MusicBrainz tag does not match.'.\ format(scorename, score_attrib['mb_tag']) warnings.warn(warn_str.encode('utf-8'), stacklevel=2) return is_attribute_valid