def strip_result(id,make_key,disc_index): try: result = musicbrainzngs.get_releases_by_discid(id,includes=["labels","recordings","artist-credits"]) root=result['disc']['release-list'][0] discid=result['disc']['id'] except musicbrainzngs.ResponseError: result = musicbrainzngs.get_release_by_id(id,includes=["labels","recordings","artist-credits"]) root=result['release'] discid=None disc_count=root['medium-count'] track_list=root['medium-list'][disc_index]['track-list'] track_count=root['medium-list'][disc_index]['track-count'] disc_title=root['title'] release=root['id'] out=[] for track in track_list: title=track['recording']['title'] item=dict(artists=track['artist-credit-phrase'], num=track['number'], title=title, key=make_key(track=track)) out.append(item) out_dict=dict(title=disc_title,track_count=track_count,path=the_album,track_list=out,discid=discid, disc_count=disc_count,release=release) return out_dict
def __readNamesFromMB(self, disc: Disc) -> Tuple[str, Dict[int, str]]: """ Reads name of CD and individual tracks from musicbrainz Track names are stored in dictionary trackID -> trackName If not found, returns default CD name and empty dictionary :param disc: :return: """ discID = disc.id # type: str try: result = musicbrainzngs.get_releases_by_discid(discID, includes=["labels", "recordings"]) if result.get('disc'): for release in result['disc']['release-list']: cdName = release['title'] # type:Optional[str] trackNamesByPosition = {} if release.get('medium-list'): media = release['medium-list'] for medium in media: if self.__mediumHasDiscID(medium, discID): for track in medium['track-list']: recording = track['recording'] trackNamesByPosition[int(track['position'])] = recording['title'] if len(trackNamesByPosition) > 0: # found some tracks if len(media) > 1: # multiple media in release - adding medium position to CD name cdName += ", CD " + medium['position'] return cdName, trackNamesByPosition except musicbrainzngs.ResponseError as err: if err.cause.code == 404: logging.debug("disc ID %s not found" % discID) else: logging.error("received bad response from the MB server") return DEFAULT_CD_NAME, {}
def main(): m.set_useragent("application", "0.01", "http://example.com") print(m.get_artist_by_id("952a4205-023d-4235-897c-6fdb6f58dfaa", [])) print(m.get_label_by_id("aab2e720-bdd2-4565-afc2-460743585f16")) print(m.get_release_by_id("e94757ff-2655-4690-b369-4012beba6114")) print(m.get_release_group_by_id("9377d65d-ffd5-35d6-b64d-43f86ef9188d")) print(m.get_recording_by_id("cb4d4d70-930c-4d1a-a157-776de18be66a")) print(m.get_work_by_id("7e48685c-72dd-3a8b-9274-4777efb2aa75")) print(m.get_releases_by_discid("BG.iuI50.qn1DOBAWIk8fUYoeHM-")) print(m.get_recordings_by_puid("070359fc-8219-e62b-7bfd-5a01e742b490")) print(m.get_recordings_by_isrc("GBAYE9300106")) m.auth("", "") m.submit_barcodes( {"e94757ff-2655-4690-b369-4012beba6114": "9421021463277"}) m.submit_tags(recording_tags={ "cb4d4d70-930c-4d1a-a157-776de18be66a": ["these", "are", "my", "tags"] }) m.submit_tags( artist_tags={"952a4205-023d-4235-897c-6fdb6f58dfaa": ["NZ", "twee"]}) m.submit_ratings( recording_ratings={"cb4d4d70-930c-4d1a-a157-776de18be66a": 20}) m.submit_echoprints( {"e97f805a-ab48-4c52-855e-07049142113d": "anechoprint1234567"})
def _rip_cd_in_tmpdir(self) -> None: """ Rip a CD; this requires the S3 bucket be created and the working directory be clean for our use. """ # Get the MusicBrainz metadata self.disc_metadata = mb.get_releases_by_discid(self.disc_id, includes=MB_INCLUDES) self.get_preferred_names() # Get album art for each release found. This modifies the release # structure of the MusicBrainz metadata, so we need to call it first # before uploading that. self.get_album_art() # Now upload the MusicBrainz metadata. self.put_object( ACL="private", Body=json.dumps(self.disc_metadata).encode("utf-8"), ContentType="application/json", Key=f"{self.config.s3_prefix}{self.disc_id}/musicbrainz.json") # Start ripping each track. Don't execute cdparanoia in parallel, # though. for track in self.disc_info.track_information: if track.track_type != TrackType.audio: continue self.rip_convert_track(track.track)
def musicbrainz(discid, country=None, record=False): """ Based on a MusicBrainz disc id, get a list of DiscMetadata objects for the given disc id. Example disc id: Mj48G109whzEmAbPBoGvd4KyCS4- @type discid: str @rtype: list of L{DiscMetadata} """ logger.debug('looking up results for discid %r', discid) import musicbrainzngs ret = [] try: result = musicbrainzngs.get_releases_by_discid( discid, includes=["artists", "recordings", "release-groups"]) except musicbrainzngs.ResponseError, e: if isinstance(e.cause, urllib2.HTTPError): if e.cause.code == 404: raise NotFoundException(e) else: logger.debug('received bad response from the server') raise MusicBrainzException(e)
def musicbrainz(discid, country=None, record=False): """ Based on a MusicBrainz disc id, get a list of DiscMetadata objects for the given disc id. Example disc id: Mj48G109whzEmAbPBoGvd4KyCS4- @type discid: str @rtype: list of L{DiscMetadata} """ log.debug('musicbrainzngs', 'looking up results for discid %r', discid) import musicbrainzngs ret = [] try: result = musicbrainzngs.get_releases_by_discid( discid, includes=["artists", "recordings", "release-groups"]) except musicbrainzngs.ResponseError, e: if isinstance(e.cause, urllib2.HTTPError): if e.cause.code == 404: raise NotFoundException(e) else: log.debug('musicbrainzngs', 'received bad response from the server') raise MusicBrainzException(e)
def releases_by_disc(self, disc): """Lookup releases by MusicBrainzDisc. Does not include track information. """ discid = disc.discid if discid is None: discid = '-' toc = disc.toc if discid == '-' and toc is None: return [] releases = [] try: response = mb_client.get_releases_by_discid( discid, toc=toc, includes=['artist-credits', 'release-groups'], cdstubs=False) if 'disc' in response: releases = response['disc']['release-list'] elif 'release-list' in response: releases = response['release-list'] except mb_client.ResponseError as e: if isinstance(e.cause, HTTPError) and e.cause.code == 404: pass # no matches else: raise MusicBrainzError from e result = [_parse_release(r, disc) for r in releases] return sorted(result, key=_release_key)
def get(self, disc_id): try: musicbrainzngs.set_useragent('codplayer', version, 'https://github.com/petli/codplayer') # TODO: cache the response XML mb_dict = musicbrainzngs.get_releases_by_discid( disc_id, includes=['recordings', 'artist-credits']) discs = model.ExtDisc.get_from_mb_dict(mb_dict, disc_id) if not discs: raise web.HTTPError( 404, 'No Musicbrainz releases matching {0}'.format(disc_id)) self._send_json(discs) except musicbrainzngs.WebServiceError, e: if e.cause and e.cause.code: # Pass on the response code raise web.HTTPError( e.cause.code, 'Musicbrainz web service error: {0}'.format(e)) else: raise web.HTTPError( 500, 'Musicbrainz web service error: {0}'.format(e))
def get_data_for_discid(self, disc_id: int): """get data by disc id""" if not self.__logged_in: return {} includes = ["artists", "recordings", "artist-credits"] return musicbrainzngs.get_releases_by_discid(disc_id, includes=includes).get( "disc", {})
def query(self, disc_id): logger.debug('Retrieving disc meta online') musicbrainzngs.set_useragent('cdp-sa', '0.0.1') musicbrainzngs.auth('', '') disc_meta = {'disc_id': disc_id, 'tracks': []} try: response = musicbrainzngs.get_releases_by_discid( disc_id, includes=["artists", "artist-credits", "recordings"]) except musicbrainzngs.musicbrainz.ResponseError: logger.exception('Could not retrieve disc meta from Musicbrainz') return None if not 'disc' in response.keys( ) or not 'release-list' in response['disc'].keys(): logger.error( 'Musicbrainz response contains no relevant information') return None this_release = response['disc']['release-list'][0] if self.is_single_artist(this_release['artist-credit']): disc_meta['artist'] = this_release['artist-credit-phrase'] disc_meta['title'] = this_release['title'] disc_meta['total_cds'] = len( list( filter(lambda medium: medium['format'] == 'CD', this_release['medium-list']))) for medium in this_release['medium-list']: for disc in medium['disc-list']: if disc['id'] == disc_id: disc_meta['cd'] = int(medium['position']) tracks = medium['track-list'] for track in tracks: artist = track['recording']['artist-credit'][0][ 'artist']['name'] disc_meta['tracks'].append({ 'artist': artist, 'title': track['recording']['title'], 'duration': (int(track['length']) // 1000) * SAMPLE_RATE }) break if not disc_meta['tracks']: logger.error( 'Musicbrainz response has no information about the tracks') return None disc_meta['duration'] = sum(track['duration'] for track in disc_meta['tracks']) return disc_meta
def musicbrainz_lookup(): """ Scans a folder for music files with metadata. Collects metadata information from all music files and assumes they belong to the same album. Produces a simple description of the album that it loads into a KLAP form. """ # Help the user if len(sys.argv) != 2: print "Usage: {} Drive".format(sys.argv[0]) sys.exit(1) tracks = [] musicbrainzngs.set_useragent("KLAP-CDDBAdd", "0.3", "*****@*****.**") disc = discid.read(sys.argv[1]) try: result = musicbrainzngs.get_releases_by_discid(disc.id, includes=["artists","recordings","release-groups"]) except musicbrainzngs.ResponseError: print "Couldn't find that disc in the online database, sorry!" return None else: print "Found disc {}".format(disc.id) subd = None if result.get("disc"): if len(result['disc']['release-list']) == 0: print "Found the disc id, but it didn't have any releases..." return None print "Found a musicbrainz release id" open_url(KLAP_MB_URL.format(result['disc']['release-list'][0]['id'])) sys.exit() elif result.get("cdstub"): artist = normalize(result["cdstub"]["artist"]) album = normalize(result["cdstub"]["title"]) subd = result["cdstub"] c = 1 for track in subd['track-list']: title = normalize(track['title']) tartist = normalize(track['artist']) d = {'number': c, 'title': title} if tartist != artist: d['artist'] = tartist tracks.append(d) c += 1 # Make sure the info is safe for KLAP artist = artist album = album # Make the dict obj = {'artist': artist, 'album': album, 'tracks': tracks, } return obj
def disc_info_fetch(disc_id=None): if not disc_id: disc = _read_disc() disc_id = disc.id musicbrainzngs.set_useragent(afro.name, afro.version, afro.url) try: return musicbrainzngs.get_releases_by_discid(disc_id, includes=['artists', 'recordings']) except musicbrainzngs.ResponseError as exception: return None
def testGetByDiscid(self): musicbrainzngs.get_releases_by_discid("I5l9cCSFccLKFEKS.7wqSZAorPU-") self.assertEqual("http://musicbrainz.org/ws/2/discid/I5l9cCSFccLKFEKS.7wqSZAorPU-", self.opener.get_url()) includes = ["artists"] musicbrainzngs.get_releases_by_discid("I5l9cCSFccLKFEKS.7wqSZAorPU-", includes) self.assertEqual("http://musicbrainz.org/ws/2/discid/I5l9cCSFccLKFEKS.7wqSZAorPU-?inc=artists", self.opener.get_url()) musicbrainzngs.get_releases_by_discid("discid", toc="toc") self.assertEqual("http://musicbrainz.org/ws/2/discid/discid?toc=toc", self.opener.get_url()) musicbrainzngs.get_releases_by_discid("discid", toc="toc", cdstubs=False) self.assertEqual("http://musicbrainz.org/ws/2/discid/discid?cdstubs=no&toc=toc", self.opener.get_url())
def musicbrainz(discid, country=None, record=False): """ Get a list of DiscMetadata objects for the given MusicBrainz disc id. Example disc id: ``Mj48G109whzEmAbPBoGvd4KyCS4-`` :type discid: str :rtype: list of :any:`DiscMetadata` :param country: country name used to filter releases by provenance :type country: str :param record: whether to record to disc as a JSON serialization :type record: bool """ logger.debug('looking up results for discid %r', discid) logging.getLogger("musicbrainzngs").setLevel(logging.WARNING) ret = [] try: result = musicbrainzngs.get_releases_by_discid( discid, includes=["artists", "recordings", "release-groups"]) except musicbrainzngs.ResponseError as e: if isinstance(e.cause, HTTPError): if e.cause.code == 404: raise NotFoundException(e) else: logger.debug('received bad response from the server') raise MusicBrainzException(e) # The result can either be a "disc" or a "cdstub" if result.get('disc'): logger.debug('found %d releases for discid %r', len(result['disc']['release-list']), discid) _record(record, 'releases', discid, result) # Display the returned results to the user. for release in result['disc']['release-list']: formatted = json.dumps(release, sort_keys=False, indent=4) logger.debug('result %s: artist %r, title %r', formatted, release['artist-credit-phrase'], release['title']) md = getReleaseMetadata(release['id'], discid, country, record) if md: logger.debug('duration %r', md.duration) ret.append(md) return ret elif result.get('cdstub'): logger.debug('query returned cdstub: ignored') return None
def getMusicBrainzReleases(discId): try: releases = musicbrainzngs.get_releases_by_discid(discId, includes=["recordings", "artists"]) return releases except musicbrainzngs.ResponseError as err: if err.cause.code == 404: log("ERROR. Disc not found") else: log("ERROR. Received bad response from the MB server") return None
def load_cd_info(self): # JH - added code to query musicbrainz for disk info, build track list and times from that info # instead of the cd-discid output, if available. track_offsets = [] m.set_useragent('raspberry-pi-cdplayer', '0.2', 'https://github.com/JoeHartley3/raspberry-pi-cdplayer') try: this_disc = libdiscid.read('/dev/cdrom') except: print('DiskID could not read /dev/cdrom') self._numtracks = 0 self._track_lengths = [] self._cd_info = None return try: # A CD stub is an anonymously submitted track list that contains a disc ID, barcode, comment field, and # basic metadata like a release title and track names. ( https://wiki.musicbrainz.org/CD_Stub ) # By using cdstubs=False here, we force a ResponseError rather than try and parse the stub. Remove the # argument to enable cdstubs. self._cd_info = m.get_releases_by_discid(this_disc.id, includes=["recordings", "artists"], cdstubs=False) except m.ResponseError: print("Disk not found or database unavailable") discid = subprocess.getstatusoutput('cd-discid --musicbrainz') if discid[0] == 0: output_split = discid[1].split() self._numtracks = int(output_split[0]) track_offsets = list(map(lambda i: int(i), output_split[1:])) if self._cd_info is not None: if self._cd_info.get("disc"): self._numtracks = self._cd_info['disc']['offset-count'] track_offsets = self._cd_info['disc']['offset-list'] # Append the total time to the track_offsets track_offsets.append(int(self._cd_info['disc']['sectors'])) elif self._cd_info.get("cdstub"): pass else: # We should never actually get to this point with or without cdstubs, but let's make sure. # This is the same code as for a ResponseError above. print("Unknown disk type from MB - use track numbers") discid = subprocess.getstatusoutput('cd-discid --musicbrainz') if discid[0] == 0: output_split = discid[1].split() self._numtracks = int(output_split[0]) track_offsets = list(map(lambda i: int(i), output_split[1:])) try: self._track_lengths = list( map(lambda i, offsets=track_offsets: int((offsets[i + 1] - offsets[i]) * 1000 / 75), range(0, self._numtracks))) except: self._numtracks = 0 self._track_lengths = []
def get_musicbrainz_release(disc): mb.set_useragent(app='get-contents', version='0.1') try: release = mb.get_releases_by_discid(disc.id, includes=['artists', 'recordings']) except mb.ResponseError: release = None if release is not None and "disc" in release: this_release = release['disc']['release-list'][0] else: this_release = None return this_release
def lookup_mb(self): status_label = self.status_label status_label.setText('Checking the MusicBrainz database') disc_id = self.wizard.disc_id #disc_id = '203b2nNoBhUpSWCAejk5rojPuOU-' #testing #disc_id = 'OnYoxOJ8mAwXzTJcq42vROwOKSM-' #test cdstub #disc_id = 'CvLoGpzPT2GKm1hx8vGEpP0lBwc-' #test 404 musicbrainzngs.set_useragent(self.wizard.useragent, self.wizard.version, self.wizard.url) try: mb = musicbrainzngs.get_releases_by_discid(disc_id, includes=["artists", "recordings"]) except Exception: mb = {} print mb if 'disc' in mb: releases = mb['disc']['release-list'] elif 'cdstub' in mb: releases = [mb['cdstub']] else: releases = [] #404 case metadata = [] for release in releases: id = release.get('id') title = release.get('title', '') artist = release.get('artist-credit-phrase', '') if artist == '': artist = release.get('artist', '') #support cdstubs country = release.get('country', '') date = release.get('date', '') md_obj = {'id': id, 'qimg': None, 'title': title, 'creator': artist, 'date': date, 'country': country, } description = self.get_mb_track_list(release) if description: md_obj['description'] = description metadata.append(md_obj) return metadata
def get_metadata(self): self.get_disk_id() musicbrainzngs.set_useragent(ffripper.__name__, ffripper.__version__) try: result = musicbrainzngs.get_releases_by_discid( self.id, includes=[ "recordings", "artists", "recording-rels", "labels", "artist-rels", "release-rels", "work-rels", "aliases", "artist-credits", "release-groups" ]) except musicbrainzngs.musicbrainz.NetworkError as e: raise RipperError(Reason.NETWORKERROR, "Problem communicating with the MB server") except musicbrainzngs.ResponseError: return None return result
def get_releases_by_discid(self, disc_id, includes=[]): try: response = musicbrainzngs.get_releases_by_discid(disc_id, includes=includes) except ResponseError as err: if err.cause.code == 404: return [] else: print_error("Couldn't fetch release: %s" % err) sys.exit(1) except WebServiceError as err: print_error("Couldn't fetch release: %s" % err) sys.exit(1) else: if response.get("disc"): return response["disc"]["release-list"] else: return []
def read(self): try: disc_id = discid.read() logger.debug( 'Read disc: MusicBrainz DiscID %s, FreeDB ID %s, %d tracks', disc_id.id, disc_id.freedb_id, len(disc_id.tracks)) except (discid.DiscError, NotImplementedError) as e: logger.info('Error identifying disc: %s', e) self.disc = UNKNOWN_DISC return # use cached disc info if possible if self.disc.discid == disc_id.id: return try: mbrainz_info = musicbrainzngs.get_releases_by_discid( id=disc_id.id, toc=disc_id.toc_string, includes=['artist-credits', 'recordings'], cdstubs=False) # mbrainz_info is either # a {disc: {release-list: [...]}, ...} dict or # a {release-list: [...]} dict when matched by ToC release = mbrainz_info.get('disc', mbrainz_info)['release-list'][0] try: images = musicbrainzngs.get_image_list(release['id']) except musicbrainzngs.ResponseError as e: logger.debug('Error getting CD images from MusicBrainz: %s', e) images = {'images': ()} self.disc = Disc( id=release['id'], discid=disc_id.id, title=release['title'], discs=release['medium-count'], year=release['date'], images=CdRom._extract_images(images['images']), artists=CdRom._extract_artists(release['artist-credit']), tracks=CdRom._extract_tracks(disc_id, release['medium-list'])) except (LookupError, musicbrainzngs.WebServiceError) as e: logger.info('Error accessing MusicBrainz: %s', e) self.disc = UNKNOWN_DISC._replace( discid=disc_id.id, tracks=CdRom._extract_tracks(disc_id))
def testGetDiscId(self): musicbrainzngs.get_releases_by_discid("xp5tz6rE4OHrBafj0bLfDRMGK48-") self.assertEqual("http://musicbrainz.org/ws/2/discid/xp5tz6rE4OHrBafj0bLfDRMGK48-", self.opener.get_url()) # one include musicbrainzngs.get_releases_by_discid("xp5tz6rE4OHrBafj0bLfDRMGK48-", includes=["recordings"]) self.assertEqual("http://musicbrainz.org/ws/2/discid/xp5tz6rE4OHrBafj0bLfDRMGK48-?inc=recordings", self.opener.get_url()) # more than one include musicbrainzngs.get_releases_by_discid("xp5tz6rE4OHrBafj0bLfDRMGK48-", includes=["artists", "recordings", "artist-credits"]) expected = "http://musicbrainz.org/ws/2/discid/xp5tz6rE4OHrBafj0bLfDRMGK48-?inc=artists+recordings+artist-credits" self.assertEqual(expected, self.opener.get_url())
def com_mediabrainz_get_releases(self, disc_id=None, artist_name=None, artist_recording=None, return_limit=5, strict_flag=False): """ # search by artist and album name """ if disc_id is not None: result = musicbrainzngs.get_releases_by_discid(disc_id, includes=["artists", "recordings"]) else: result = musicbrainzngs.search_releases(artist=artist_name, release=artist_recording, limit=return_limit, strict=strict_flag) if not result['release-list']: common_global.es_inst.com_elastic_index('error', {'stuff': "no release found"}) return None else: for (idx, release) in enumerate(result['release-list']): common_global.es_inst.com_elastic_index('info', {"match #{}:".format(idx + 1)}) self.show_release_details(release) return release['id']
def get(self, disc_id): try: musicbrainzngs.set_useragent('codplayer', version, 'https://github.com/petli/codplayer') # TODO: cache the response XML mb_dict = musicbrainzngs.get_releases_by_discid( disc_id, includes = ['recordings', 'artist-credits']) discs = model.ExtDisc.get_from_mb_dict(mb_dict, disc_id) if not discs: raise web.HTTPError(404, 'No Musicbrainz releases matching {0}'.format(disc_id)) self._send_json(discs) except musicbrainzngs.WebServiceError, e: if e.cause and e.cause.code: # Pass on the response code raise web.HTTPError(e.cause.code, 'Musicbrainz web service error: {0}'.format(e)) else: raise web.HTTPError(500, 'Musicbrainz web service error: {0}'.format(e))
def getlist(self): try: self.mblist = musicbrainzngs.get_releases_by_discid(self.disc,toc=None,cdstubs=True,\ includes=["artists","recordings"]) except: self.mblist = False if self.mblist: try: # These things are occasionally missing. for i in range(len(self.mblist['disc']['release-list'])): if 'date' not in self.mblist['disc']['release-list'][i]: self.mblist['disc']['release-list'][i]['date'] = '0000' if 'country' not in self.mblist['disc']['release-list'][i]: self.mblist['disc']['release-list'][i][ 'country'] = 'XX' except: print('Looks like this is a cdstub.') return (self.mblist)
def get_release(discid): """ Returns a Musicbrainz disc object from the current CD. """ # Query for all discs matching the given DiscID. result = musicbrainzngs.get_releases_by_discid(discid) releases = result['disc']['release-list'] logging.debug("Found %i releases", len(releases)) # Select the higher score release release_id = releases[-1]['id'] # The returned release object only contains title and artist, but no tracks. # Query the web service once again to get all data we need. includes = ['artists', 'recordings', 'discids'] result = musicbrainzngs.get_release_by_id(release_id, includes=includes) return result['release']
def _fetch_musicbrainz(self, disc_id, disc_toc): mb.set_useragent(self._useragent) try: # note: adding a toc here will add fuzzy matching, which will return # _many_ results result = mb.get_releases_by_discid( id=self._disc.id, includes=["artists", "recordings"], toc=self._disc.toc_string) except mb.ResponseError as e: print("disc not found or bad response") pprint(vars(e)) return None #print("--- raw mb:"); #print(json.dumps(result,indent=2)) #print("---"); # three possibilities here: "The result is a dict with either a ‘disc’ , a # ‘cdstub’ key or a ‘release-list’ (fuzzy match with TOC). A ‘disc’ has an # ‘offset-count’, an ‘offset-list’ and a ‘release-list’. A ‘cdstub’ key # has direct ‘artist’ and ‘title’ keys." if result.get("disc"): print("disc id: %s" % result["disc"]["id"]) print("Releases:") for release in result["disc"]["release-list"]: #print(json.dumps(release,indent=4)) if 'packaging' not in release: release['packaging'] = 'UNKNOWN' print( " {id}: {artist-credit-phrase} / {title} / {medium-count} / {packaging}" .format(**release)) return result['disc'] elif result.get("cdstub"): return result['cdstub'] elif result.get("release-list"): raise NotImplementedError # never reached raise Exception('Never reached')
def get_title(discid, job): """ Ask musicbrainz.org for the release of the disc only gets the title of the album and artist arguments: discid - identification object from discid package job - the job object for the database entry return: the label of the disc as a string or "" if nothing was found Notes: dont try to use logging here - doing so will break the arm setuplogging() function """ mb.set_useragent("arm", "v1.0") try: infos = mb.get_releases_by_discid(discid, includes=['artist-credits']) logging.debug('mb info = %s', infos) title = str(infos['disc']['release-list'][0]['title']) logging.debug('title = %s', title) # Start setting our db stuff job.crc_id = str(infos['disc']['release-list'][0]['id']) logging.debug('crc = %s', job.crc_id) artist = str(infos['disc']['release-list'][0]['artist-credit'][0] ['artist']['name']) logging.debug('artist = %s', artist) # log = clean_for_log(artist) + "_" + clean_for_log(title) + ".log" job.title = job.title_auto = artist + " " + title logging.debug('job.title = %s', job.title) job.video_type = "Music" clean_title = clean_for_log(artist) + "-" + clean_for_log(title) logging.debug('clean title = %s', clean_title) db.session.commit() return clean_title # return artist + "_" + title except mb.WebServiceError as exc: logging.error("mb.gettitle - ERROR: " + str(exc)) logging.debug('error = %s', str(exc)) db.session.rollback() return "not identified"
def main(): result = None musicbrainzngs.set_hostname(MUSICBRAINZ_HOST) musicbrainzngs.set_useragent('freedb2musicbrainz.py', __version__, contact='Freso') try: disc = discid.read(features=['mcn']) except discid.disc.DiscError as err: print("Error reading disc: %s" % (err)) exit(1) try: result = musicbrainzngs.get_releases_by_discid(disc.id) except musicbrainzngs.ResponseError as err: print('Disc not currently in MusicBrainz (or bad response): %s' % (err)) if result: if result.get('disc'): print('This release seems to already be in MusicBrainz.') print( 'Check %s to verify that it is the same or submit your specific copy' % (disc.submission_url)) elif result.get("cdstub"): print('There seems to be a CD stub of your disc.') print('Go to %s to add the stub fully into the database.' % (disc.submission_url)) else: print('The release seems to not be in MusicBrainz. Let’s try FreeDB…') freedb = Cddb.CddbServer() print(cddb_lookup_string(disc)) result = freedb.getDiscs(cddb_lookup_string(disc)) if result: for r in result: print(r.artist, "-", r.title) else: print('This release is non-existant! Add it to MB!!') print(disc.submission_url)
import musicbrainzngs as mb import requests import json from getpass import getpass this_disc = libdiscid.read(libdiscid.default_device()) mb.set_useragent(app='get-contents', version='0.1') mb.auth(u=input('Musicbrainz username: '******'artists', 'recordings']) if release.get('disc'): this_release=release['disc']['release-list'][0] title = this_release['title'] artist = this_release['artist-credit'][0]['artist']['name'] if this_release['cover-art-archive']['artwork'] == 'true': url = 'http://coverartarchive.org/release/' + this_release['id'] art = json.loads(requests.get(url, allow_redirects=True).content) for image in art['images']: if image['front'] == True: cover = requests.get(image['image'], allow_redirects=True) fname = '{0} - {1}.jpg'.format(artist, title) print('COVER="{}"'.format(fname)) f = open(fname, 'wb') f.write(cover.content) f.close() break print('TITLE="{}"'.format(title))
print ('Length :', disc.sectors, 'sectors', file=tocf) i = disc.first_track_num for track in disc.tracks: print ("Track %-2d : %8d %8d" % (i, track.offset, track.length), file=tocf) i += 1 # TODO fix this print ('Submit via:', disc.submission_url, file=tocf) print ('Submit via:', disc.submission_url) print ('DiscID:', disc.id) try: io.write ("Querying MusicBrainz...") result = mb.get_releases_by_discid(disc.id, includes=["artists"]) io.write ('OK\n') except mb.ResponseError: print("disc not found or bad response") continue else: if result.get("disc"): for i, rel in enumerate(result['disc']['release-list']): print ("\nResult : %d" % i) #if rel.score: #print " Score : %d" % rel.score print ("Release :", rel['id']) print ("Artist :", rel['artist-credit-phrase']) print ("Title :", rel['title']) print ("Date :", rel['date'] if 'date' in rel else '') print ("Country :", rel['country'] if 'country' in rel else '')
def musicbrainz_info(): try: # Read the disc disc_read = discid.read() # Get the disc ID from the read object disc_id = disc_read.id # Also get the submission URL in case of an accident disc_submission = disc_read.submission_url except: print("Please insert a compact disc") sys.exit(0) musicbrainzngs.set_useragent("Tedm ripper", "0.0.1", "*****@*****.**") try: result = musicbrainzngs.get_releases_by_discid(disc_id, includes=['artists', 'labels', 'recordings']) release_list = result['disc']['release-list'][0] number_of_discs = release_list['medium-count'] disc_number_list = list(range(1, (number_of_discs + 1))) disc_string = ', '.join(map(str, disc_number_list)) if number_of_discs > 1: print('This disc is part of a set. You can choose from %s' % disc_string) choice = input('Please enter the proper disc number: ') if not int(choice) in disc_number_list: print("Invalid disc number") sys.exit(0) pretty_disc_number = choice raw_disc_number = int(pretty_disc_number) - 1 else: pretty_disc_number = '1' raw_disc_number = 0 except musicbrainzngs.ResponseError: print("Disc was not found in database, check if available on musicbrainz.org") print(disc_submission) sys.exit(0) except musicbrainzngs.musicbrainz.NetworkError: print("You do not seem to be connected to the internet") sys.exit(0) else: # Define metadata for the entire album album_info_dict = { 'album': release_list['title'], 'album_artist': release_list['artist-credit'][0]['artist']['name'], 'artist': release_list['artist-credit'][0]['artist']['name'], 'date': release_list['date'], 'disc': pretty_disc_number, 'disc_id': result['disc']['id'], 'total_discs': str(number_of_discs), 'total_tracks': release_list['medium-list'][raw_disc_number]['track-count'], } try: album_info_dict['label'] = release_list['label-info-list'][0]['label']['name'] except IndexError: album_info_dict['label'] = '' track_dict = {} for track in release_list['medium-list'][raw_disc_number]['track-list']: title = track['recording']['title'] track_number = track['position'] track_dict[track_number] = title return album_info_dict, track_dict
def identify(self): """Drrn drrn """ ## XXX: Do we really need the old library for this? try: disc = mbdisc.readDisc(deviceName=DEVICE) except mbdisc.DiscError as e: logger.error('[FAIL] %s' % e) logger.error(''.join(traceback.format_exception(*sys.exc_info()))) self.interface.queue_to_identify_interface.send('FAILED_IDENTIFY') return disc_id = disc.getId() submission_url = mbdisc.getSubmissionUrl(disc) logger.info('[URL] %s' % submission_url) logger.info('[SUCCESS] Identified disc as: %s' % disc_id) ## XXX: The library doesn't understand a tuple here includes = ['artist-credits', 'labels', 'release-rels', 'recordings'] try: data = musicbrainzngs.get_releases_by_discid(disc_id, includes=includes) except musicbrainzngs.ResponseError as e: ## Fake response to make flow easier if e.cause.code == 404: data = { 'disc': { 'id': disc_id, 'release-list': [] } } else: raise except Exception as e: logger.error('[FAIL] %s' % e) logger.error(''.join(traceback.format_exception(*sys.exc_info()))) self.interface.queue_to_identify_interface.send('FAILED_IDENTIFY') return else: if not data: logger.error('[FAIL] No data returned. Check submission url') return try: releases = data['disc']['release-list'] except KeyError: if 'cdstub' in data: logger.warn('[DISC] This release is only a stub, fill it in at MusicBrainz') self.interface.queue_to_identify_interface.send('NO_DATA') return # Make the chance slimmer that selecting a release breaks if mb sends results in odd orders releases.sort() logger.info('[SUCCESS] Got %d releases' % len(releases)) if len(releases) == 0: self.interface.queue_to_identify_interface.send('NO_DATA') self.interface.queue_to_identify_interface.send(submission_url) return elif len(releases) > 1: self.interface.queue_to_identify_interface.send('MULTIPLE_RELEASES') self.interface.queue_to_identify_interface.send(releases) rel_num = self.interface.queue_to_identify_interface.recv() else: rel_num = 0 ## Which release do we want? release = releases[rel_num] ## Disc title title = release['title'].encode('utf-8') disambiguation = release.get('disambiguation', None) is_remaster = False for rel_release in release.get('release-relation-list', ()): if rel_release.get('type', None) == 'remaster': is_remaster = True break extra_str = '' if disambiguation: extra_str = '%s' % disambiguation if is_remaster: extra_str = '%s remaster' % extra_str extra_str = extra_str.strip() if extra_str: title = '%s (%s)' % (title, extra_str) ## Require release date date = release['date'] if not date: self.interface.queue_to_identify_interface.send('NO_DATE') return year = date.split('-', 1)[0] ## 0th artist... if len(release['artist-credit']) > 1: self.interface.queue_to_identify_interface.send('TOO_MANY_ARTISTS') return artist_sort_name = release['artist-credit'][0]['artist']['sort-name'] artist_sort_name = artist_sort_name.encode('utf-8') ## Media count and name disc_num = 1 if 'medium-count' not in release: disc_count = len(release['medium-list']) else: disc_count = release['medium-count'] medium_n = 0 media_name = None if disc_count > 1: for medium_n, medium in enumerate(release['medium-list']): if 'title' in medium: media_name = medium['title'] else: media_name = None if disc_id in [d['id'] for d in medium['disc-list']]: disc_num = medium_n + 1 break # Pass the media_name along if required, otherwise it's None if media_name is not None and media_name == title: media_name = None ## Unlike the mb example code, disregard different track artists track_tuples = [] for track in release['medium-list'][medium_n]['track-list']: formatted_track_num = '%02d' % int(track['number']) track_title = track['recording']['title'].encode('utf-8') track_tuple = TrackTuple(disc_id=disc_id, release_id=release['id'], artist=artist_sort_name, year=year, title=title, formatted_track_num=formatted_track_num, track_title=track_title, disc_num=disc_num, disc_count=disc_count, media_name=media_name) track_tuples.append(track_tuple) self.interface.queue_to_identify_interface.send('FINISHED_IDENTIFY') self.interface.queue_to_identify_interface.send(tuple(track_tuples))
def get_releases(discid): ret = mb.get_releases_by_discid(discid) releases = ret.get("disc", {}).get("release-list") if not releases: raise Exception(f"no release found for {discid}") return [get_cd_info(r, discid) for r in releases]
def find_disc(cddrive): import discid from lxml import etree root = etree.XML(u'<finddisc></finddisc>') try: disc = discid.read(cddrive, ["mcn", "isrc"]) id = disc.id toc = disc.toc_string except discid.DiscError as err: etree.SubElement(root, "error").text = "Failed to get discid ({})".format( str(err)) log( True, convert_etree( etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))) sys.exit(1) etree.SubElement(root, "discid").text = id etree.SubElement(root, "toc").text = toc try: # the "labels" include enables the cat#s we display result = musicbrainzngs.get_releases_by_discid(id, includes=["labels"], toc=toc, cdstubs=False) except musicbrainzngs.ResponseError as err: if err.cause.code == 404: etree.SubElement(root, "error").text = "Disc not found" log( True, convert_etree( etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))) sys.exit(1) else: etree.SubElement( root, "error").text = "Received bad response from the MB server" log( True, convert_etree( etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))) sys.exit(1) # The result can either be a "disc" or a "cdstub" if result.get('disc'): discnode = etree.SubElement(root, "disc") etree.SubElement(discnode, "sectors").text = result['disc']['sectors'] if "offset-list" in result['disc']: offsets = None for offset in result['disc']['offset-list']: if offsets is None: offsets = str(offset) else: offsets += " " + str(offset) etree.SubElement(discnode, "offsets").text = offsets etree.SubElement(discnode, "tracks").text = str( result['disc']['offset-count']) for release in result['disc']['release-list']: relnode = etree.SubElement(discnode, "release") etree.SubElement(relnode, "title").text = release['title'] etree.SubElement(relnode, "musicbrainzid").text = release['id'] if release.get('barcode'): etree.SubElement(relnode, "barcode").text = release['barcode'] for info in release['label-info-list']: if info.get('catalog-number'): etree.SubElement( relnode, "catalog-number").text = info['catalog-number'] elif result.get('cdstub'): stubnode = etree.SubElement(root, "cdstub") etree.SubElement(stubnode, "artist").text = result['cdstub']['artist'] etree.SubElement(stubnode, "title").text = result['cdstub']['title'] if result['cdstub'].get('barcode'): etree.SubElement(stubnode, "barcode").text = result['cdstub']['barcode'] else: etree.SubElement(root, "error").text = "No valid results" log( True, convert_etree( etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))) sys.exit(1) log( True, convert_etree( etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True))) sys.exit(0)
# get discid: try: disc = libdiscid.read(device) tracknum = disc.last_track except libdiscid.DiscError: print( "Disc error! Please make sure a disc is inserted and {} is the right device!" .format(device)) exit(1) # set the musicbrainz useragent_ musicbrainzngs.set_useragent("cd2mp3", "0.2", None) # needs "includes=..." to get a non-empty tracklist: try: result = musicbrainzngs.get_releases_by_discid( disc.id, includes=["artists", "recordings"]) except musicbrainzngs.ResponseError: print("No matches found on musicbrainz... Trying cd-info:") get_cdtextinfo() else: # the above command returns a dict of more dicts,lists, even more dicts... release = result['disc']['release-list'][0] artist = release['artist-credit-phrase'] title = release['title'] tracklist = release['medium-list'][0]['track-list'] print("Artist: ", artist) print("Album: ", title) print("%d track(s)" % tracknum) for entry in tracklist: tracktitle = entry['recording']['title']
# get Audio CD details try: disc = discid.read() # reads from default device except discid.DiscError, e: if str(e) == u'cannot read table of contents': print 'Could not read CD.' sys.exit(1) # try to find Audio CD match on MusicBrainz print "\nFetching release data for CD ..." musicbrainzngs.set_useragent(scriptName, scriptVersion, scriptURL) try: discReleases = musicbrainzngs.get_releases_by_discid(disc.id, ['artist-credits', 'recordings'], disc.toc_string, False) except: print sys.exc_info() sys.exit(2) try: discReleases['disc'] releaseList = discReleases['disc']['release-list'] except: try: discReleases['release-list'] releaseList = discReleases['release-list'] except: print releaseList print sys.exc_info() sys.exit(2)
for offset in offset_list: if offsets == None: offsets = str(offset) else: offsets += " " + str(offset) print("\toffsets: {}".format(offsets)) if __name__ == '__main__': args = sys.argv[1:] if len(args) != 1: sys.exit("usage: {} DISC_ID".format(sys.argv[0])) discid = args[0] try: # the "labels" include enables the cat#s we display result = musicbrainzngs.get_releases_by_discid(discid, includes=["labels"]) except musicbrainzngs.ResponseError as err: if err.cause.code == 404: sys.exit("disc not found") else: sys.exit("received bad response from the MB server") # The result can either be a "disc" or a "cdstub" if result.get('disc'): print("disc:") print("\tSectors: {}".format(result['disc']['sectors'])) # offset-list only available starting with musicbrainzngs 0.6 if "offset-list" in result['disc']: show_offsets(result['disc']['offset-list']) print("\tTracks: {}".format(result['disc']['offset-count'])) for release in result['disc']['release-list']:
def main(): parser = optparse.OptionParser() parser.add_option("-u", "--user", type=str, help="Username") parser.add_option("-p", "--password", type=str, help="Password") parser.add_option("-d", "--device", type=str, default=discid.get_default_device(), help="Device name, the default is %s" % discid.get_default_device()) (args, options) = parser.parse_args() if not args.user: exit("No username given") if not args.password: password = getpass.getpass() else: password = args.password try: disc = discid.read(args.device) except discid.DiscError: exit("No discid could be calculated") musicbrainzngs.auth(args.user, password) musicbrainzngs.set_useragent("isrcsubmit-cdrdao", "0.2", "Mineo@Freenode") results = musicbrainzngs.get_releases_by_discid( disc.id, includes=["recordings", "isrcs", "artist-credits"])["disc"]["release-list"] if len(results) == 0: print "The disc is not in the database" print "Please submit it with: %s" % disc.submission_url exit(1) elif len(results) > 1: print "This Disc ID is ambiguous:" for i, release in enumerate(results): print str(i)+":", release["artist-credit-phrase"] print "-", release["title"] print release["id"] num = -1 while True: try: num = raw_input("Which one do you want? [0-%d] " % i) release = results[int(num)] except (IndexError, ValueError): continue break else: release = results[0] print 'Artist: %s' % release["artist-credit-phrase"] print 'Release: %s' % release["title"] real_medium = None for medium in release["medium-list"]: for mdisc in medium["disc-list"]: print mdisc if mdisc["id"] == disc.id: real_medium = medium break filename = "/tmp/cdrdao-%s.toc" % datetime.now() try: proc = subprocess.Popen(["cdrdao", "read-toc", "--fast-toc", "--device", args.device, "-v", "0", filename], stderr=subprocess.PIPE, stdout=subprocess.PIPE) proc.wait() except Exception, e: exit("Exception while calling cdrdao: %s" % str(e))
def _get_releases_from_toc(toc): """Returns a list of musicbrainz release IDs from a toc string""" res = musicbrainzngs.get_releases_by_discid(id="", toc=toc) if res['release-list']: return [release['id'] for release in res['release-list']]
def musicbrainz(discid, country=None, record=False): """Get a list of DiscMetadata objects for the given MusicBrainz disc id. Example disc id: Mj48G109whzEmAbPBoGvd4KyCS4- :param discid: :type discid: str :param country: (Default value = None). :type country: :param record: (Default value = False). :type record: :returns: :rtype: list of L{DiscMetadata} """ logger.debug('looking up results for discid %r', discid) import musicbrainzngs ret = [] try: result = musicbrainzngs.get_releases_by_discid( discid, includes=["artists", "recordings", "release-groups"]) except musicbrainzngs.ResponseError as e: if isinstance(e.cause, urllib2.HTTPError): if e.cause.code == 404: raise NotFoundException(e) else: logger.debug('received bad response from the server') raise MusicBrainzException(e) # The result can either be a "disc" or a "cdstub" if result.get('disc'): logger.debug('found %d releases for discid %r', len(result['disc']['release-list']), discid) _record(record, 'releases', discid, result) # Display the returned results to the user. import json for release in result['disc']['release-list']: formatted = json.dumps(release, sort_keys=False, indent=4) logger.debug('result %s: artist %r, title %r' % ( formatted, release['artist-credit-phrase'], release['title'])) # to get titles of recordings, we need to query the release with # artist-credits res = musicbrainzngs.get_release_by_id( release['id'], includes=["artists", "artist-credits", "recordings", "discids", "labels"]) _record(record, 'release', release['id'], res) releaseDetail = res['release'] formatted = json.dumps(releaseDetail, sort_keys=False, indent=4) logger.debug('release %s' % formatted) md = _getMetadata(release, releaseDetail, discid, country) if md: logger.debug('duration %r', md.duration) ret.append(md) return ret elif result.get('cdstub'): logger.debug('query returned cdstub: ignored') return None else: return None
def musicbrainz(discid, country=None, record=False): """ Based on a MusicBrainz disc id, get a list of DiscMetadata objects for the given disc id. Example disc id: Mj48G109whzEmAbPBoGvd4KyCS4- @type discid: str @rtype: list of L{DiscMetadata} """ logger.debug('looking up results for discid %r', discid) import musicbrainzngs musicbrainzngs.set_useragent("whipper", whipper.__version__, "https://github.com/whipper-team/whipper") ret = [] try: result = musicbrainzngs.get_releases_by_discid( discid, includes=["artists", "recordings", "release-groups"]) except musicbrainzngs.ResponseError as e: if isinstance(e.cause, urllib2.HTTPError): if e.cause.code == 404: raise NotFoundException(e) else: logger.debug('received bad response from the server') raise MusicBrainzException(e) # The result can either be a "disc" or a "cdstub" if result.get('disc'): logger.debug('found %d releases for discid %r', len(result['disc']['release-list']), discid) _record(record, 'releases', discid, result) # Display the returned results to the user. import json for release in result['disc']['release-list']: formatted = json.dumps(release, sort_keys=False, indent=4) logger.debug('result %s: artist %r, title %r', formatted, release['artist-credit-phrase'], release['title']) # to get titles of recordings, we need to query the release with # artist-credits res = musicbrainzngs.get_release_by_id(release['id'], includes=[ "artists", "artist-credits", "recordings", "discids", "labels" ]) _record(record, 'release', release['id'], res) releaseDetail = res['release'] formatted = json.dumps(releaseDetail, sort_keys=False, indent=4) logger.debug('release %s', formatted) md = _getMetadata(release, releaseDetail, discid, country) if md: logger.debug('duration %r', md.duration) ret.append(md) return ret elif result.get('cdstub'): logger.debug('query returned cdstub: ignored') return None else: return None
args = parser.parse_args() # Setup MusicBrainz client mb.set_useragent('Antiquarian Backups', '1.0.0') # get Username/Password creds = open('credentials', 'r').read().split('\n') mb.auth(creds[0], creds[1]) # Select the disc and retrieve the MusicBrainz discid disc = libdiscid.read(device=u'/dev/sr0') disc_id = disc.id # Collect the valuable metadata information from the discid in the MusicBrainz CDDA database try: results = mb.get_releases_by_discid(disc_id, includes=['artists', 'recordings']) except mb.musicbrainz.ResponseError as re: print( 'Error retrieving the releases data, check if the Title has a discID on musicbrainz.org' ) sys.exit(1) # save the releaseid release_id = results['disc']['release-list'][0]['id'] disc_info = {} tracks = [] # grab the track names of each song for item in results['disc']['release-list'][0]['medium-list'][0]['track-list']: tracks.append(item['recording']['title'])
def find_disc(cddrive): import discid from lxml import etree root = etree.XML(u'<finddisc></finddisc>') try: disc = discid.read(cddrive, ["mcn", "isrc"]) id = disc.id toc = disc.toc_string except discid.DiscError as err: etree.SubElement(root, "error").text = "Failed to get discid ({})".format(str(err)) log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)) sys.exit(1) etree.SubElement(root, "discid").text = id etree.SubElement(root, "toc").text = toc try: # the "labels" include enables the cat#s we display result = musicbrainzngs.get_releases_by_discid(id, includes=["labels"], toc=toc, cdstubs=False) except musicbrainzngs.ResponseError as err: if err.cause.code == 404: etree.SubElement(root, "error").text = "Disc not found" log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)) sys.exit(1) else: etree.SubElement(root, "error").text = "Received bad response from the MB server" log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)) sys.exit(1) # The result can either be a "disc" or a "cdstub" if result.get('disc'): discnode = etree.SubElement(root, "disc") etree.SubElement(discnode, "sectors").text = result['disc']['sectors'] if "offset-list" in result['disc']: offsets = None for offset in result['disc']['offset-list']: if offsets == None: offsets = str(offset) else: offsets += " " + str(offset) etree.SubElement(discnode, "offsets").text = offsets etree.SubElement(discnode, "tracks").text = str(result['disc']['offset-count']) for release in result['disc']['release-list']: relnode = etree.SubElement(discnode, "release") etree.SubElement(relnode, "title").text = release['title'] etree.SubElement(relnode, "musicbrainzid").text = release['id'] if release.get('barcode'): etree.SubElement(relnode, "barcode").text = release['barcode'] for info in release['label-info-list']: if info.get('catalog-number'): etree.SubElement(relnode, "catalog-number").text = info['catalog-number'] elif result.get('cdstub'): stubnode = etree.SubElement(root, "cdstub") etree.SubElement(stubnode, "artist").text = result['cdstub']['artist'] etree.SubElement(stubnode, "title").text = result['cdstub']['title'] if result['cdstub'].get('barcode'): etree.SubElement(stubnode, "barcode").text = result['cdstub']['barcode'] else: etree.SubElement(root, "error").text = "No valid results" log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)) sys.exit(1) log(True, etree.tostring(root, encoding='UTF-8', pretty_print=True, xml_declaration=True)) sys.exit(0)