def generate_album_info(album_id, track_values): """Return `AlbumInfo` populated with mock data. Sets the album info's `album_id` field is set to the corresponding argument. For each pair (`id`, `values`) in `track_values` the `TrackInfo` from `generate_track_info` is added to the album info's `tracks` field. Most other fields of the album and track info are set to "album info" and "track info", respectively. """ tracks = [generate_track_info(id, values) for id, values in track_values] album = AlbumInfo( album_id=u'album info', album=u'album info', artist=u'album info', artist_id=u'album info', tracks=tracks, ) for field in ALBUM_INFO_FIELDS: setattr(album, field, u'album info') return album
def get_album_info(self, result): """Returns an AlbumInfo object for a discogs Release object. """ artist, artist_id = self.get_artist([a.data for a in result.artists]) album = re.sub(r' +', ' ', result.title) album_id = result.data['id'] # Use `.data` to access the tracklist directly instead of the # convenient `.tracklist` property, which will strip out useful artist # information and leave us with skeleton `Artist` objects that will # each make an API call just to get the same data back. tracks = self.get_tracks(result.data['tracklist']) albumtype = ', '.join( result.data['formats'][0].get('descriptions', [])) or None va = result.data['artists'][0]['name'].lower() == 'various' if va: artist = config['va_name'].as_str() year = result.data['year'] label = result.data['labels'][0]['name'] mediums = len(set(t.medium for t in tracks)) catalogno = result.data['labels'][0]['catno'] if catalogno == 'none': catalogno = None country = result.data.get('country') media = result.data['formats'][0]['name'] # Explicitly set the `media` for the tracks, since it is expected by # `autotag.apply_metadata`, and set `medium_total`. for track in tracks: track.media = media track.medium_total = mediums data_url = result.data['uri'] return AlbumInfo(album, album_id, artist, artist_id, tracks, asin=None, albumtype=albumtype, va=va, year=year, month=None, day=None, label=label, mediums=mediums, artist_sort=None, releasegroup_id=None, catalognum=catalogno, script=None, language=None, country=country, albumstatus=None, media=media, albumdisambig=None, artist_credit=None, original_year=None, original_month=None, original_day=None, data_source='Discogs', data_url=data_url)
def set_albuminfo(self, tracks, **kwargs): fields = ["index", "title_id", "artist", "title", "length", "alt"] iter_tracks = [zip(fields, (idx, *track)) for idx, track in enumerate(tracks, 1)] self.albuminfo = AlbumInfo( album=kwargs["album"], album_id=self.album_id, artist=kwargs["albumartist"], artist_id=self.artist_id, data_url=self.album_id, year=kwargs["release_date"].year, month=kwargs["release_date"].month, day=kwargs["release_date"].day, label=kwargs["label"], va=kwargs["va"], albumtype=kwargs["albumtype"], catalognum=kwargs["catalognum"], country=kwargs["country"], mediums=kwargs["mediums"], albumstatus=OFFICIAL, media=self.media, data_source=DATA_SOURCE, tracks=[TrackInfo(**self.track_data(**dict(t))) for t in iter_tracks], )
def _get_album(self, album_url): """ return AlbumInfo object corresponding to album linked to by `album_url`. """ try: soup = self._open_url(album_url) # catalog number, date (also potentially producer, mastering, etc.) meta = soup.find("dl", class_="clearfix") catalognum, date = [dd.get_text(strip=True) for dd in meta.find_all("dd")][:2] if len(date.split("/")) == 3: year, month, day = [int(x) for x in date.split("/")] else: year, month, day = [int(x) for x in date.split(".")] # album/circle information album = soup.find(id="single").find(class_="xfd_none").find("h2").get_text(strip=True) artist = label = soup.find(class_="cw clearfix").find("a").get_text(strip=True) artist_id = album_url[:(album_url.rfind("/", 0, -1) + 1)] # discs and tracks mediums = len(soup.find("div", class_="left fl").find("ul", class_="clearfix")) tracks = self._get_tracks(album_url, soup=soup) return AlbumInfo(album, album_url, artist, artist_id, tracks, year=year, month=month, day=day, label=label, mediums=mediums, catalognum=catalognum, country=COUNTRY, data_source=DATA_SOURCE, data_url=album_url) except: self._log.debug(f"Error while scraping {album_url}")
def _get_album_info(self, release): """Returns an AlbumInfo object for a Beatport Release object. """ va = len(release.artists) > 3 artist, artist_id = self._get_artist(release.artists) if va: artist = u"Various Artists" tracks = [self._get_track_info(x) for x in release.tracks] return AlbumInfo(album=release.name, album_id=release.beatport_id, artist=artist, artist_id=artist_id, tracks=tracks, albumtype=release.category, va=va, year=release.release_date.year, month=release.release_date.month, day=release.release_date.day, label=release.label_name, catalognum=release.catalog_number, media=u'Digital', data_source=u'Beatport', data_url=release.url)
def get_album_info(self, item, ns, va_likely): album = item.findtext('{0}ItemAttributes/{0}Title'.format(ns)) album_id = item.findtext('{0}ItemAttributes/{0}EAN'.format(ns)) album_UPC = item.findtext('{0}ItemAttributes/{0}UPC'.format(ns)) country = ",".join([cat.text.replace("Country Of Release:", '') for cat in item.findall('{0}ItemAttributes/{0}Feature'.format(ns)) if "Country Of Release:" in cat.text]) catnumlisbig = None catalog = ",".join([cat.text.replace("Catalog#", '') for cat in item.findall('{0}ItemAttributes/{0}Feature'.format(ns)) if "Catalog#" in cat.text]) catnumlis = [it.text for it in item.findall( '{0}ItemAttributes/{0}CatalogNumberList/{0}CatalogNumberListElement' .format(ns))] catnumlis.sort() catnumlisbig = catnumlis[0] if catnumlis else catalog perf = ",".join([role.text for role in item.findall( '{0}ItemAttributes/{0}Creator'.format(ns)) if role.attrib.get("Role") == "Performer"]) art = ",".join([artist.text for artist in item.findall( '{0}ItemAttributes/{0}Artist'.format(ns))]) artists = art or perf va = False if artists == album and va_likely: artists = "Various Artists" va = True artist_id = artists.split(",")[0] Tracks = [] trn = 1 for disc in item.iterfind(".//{0}Disc".format(ns)): tr = disc.findall(".//{0}Track".format(ns)) for track in disc.iterfind(".//{0}Track".format(ns)): title = track.text index = trn medium = disc.attrib.get("Number") medium_index = track.attrib.get("Number") newtrack = TrackInfo( self.decod(title), int(index), index=int(index), medium=int(medium), medium_index=int(medium_index), medium_total=len(tr) ) Tracks.append(newtrack) trn = trn + 1 asin = item.findtext('{0}ASIN'.format(ns)) albumtype = item.findtext( '{0}ItemAttributes/{0}Binding'.format(ns)) rd = item.findtext( '{0}ItemAttributes/{0}ReleaseDate'.format(ns)) year = month = day = None if rd: releasedate = rd.split("-") year = releasedate[0] month = releasedate[1] day = releasedate[2] label = item.findtext('{0}ItemAttributes/{0}Label'.format(ns)) ProductTypeName = item.findtext( '{0}ItemAttributes/{0}ProductTypeName'.format(ns)) label = label if label else ProductTypeName mediums = item.findtext( '{0}ItemAttributes/{0}NumberOfDiscs'.format(ns)) if mediums is None: mediums = 1 Composers = [role.text for role in item.findall( '{0}ItemAttributes/{0}Creator'.format(ns)) if role.attrib.get("Role") == "Composer"] Conductors = [role.text for role in item.findall( '{0}ItemAttributes/{0}Creator'.format(ns)) if role.attrib.get("Role") == "Conductor"] Orchestras = [role.text for role in item.findall( '{0}ItemAttributes/{0}Creator'.format(ns)) if role.attrib.get("Role") == "Orchestra"] comps = ",". join(Composers) cond = ",".join(Conductors) orch = ",".join(Orchestras) media = item.findtext('{0}ItemAttributes/{0}Binding'.format(ns)) data_url = item.findtext('{0}DetailPageURL'.format(ns)) return AlbumInfo(self.decod(album), self.decod(album_id), self.decod(artists), self.decod(artist_id), Tracks, asin=self.decod(asin), albumtype=self.decod(albumtype), va=va, year=int(year), month=int(month), day=int(day), label=self.decod(label), mediums=int(mediums), media=self.decod(media), data_source=self.decod('Amazon'), data_url=self.decod(data_url), country=self.decod(country), catalognum=self.decod(catnumlisbig) )
def get_album_info(self, result): """Returns an AlbumInfo object for a discogs Release object. """ # Explicitly reload the `Release` fields, as they might not be yet # present if the result is from a `discogs_client.search()`. if not result.data.get('artists'): result.refresh() # Sanity check for required fields. The list of required fields is # defined at Guideline 1.3.1.a, but in practice some releases might be # lacking some of these fields. This function expects at least: # `artists` (>0), `title`, `id`, `tracklist` (>0) # https://www.discogs.com/help/doc/submission-guidelines-general-rules if not all([ result.data.get(k) for k in ['artists', 'title', 'id', 'tracklist'] ]): self._log.warning(u"Release does not contain the required fields") return None artist, artist_id = MetadataSourcePlugin.get_artist( [a.data for a in result.artists]) album = re.sub(r' +', ' ', result.title) album_id = result.data['id'] # Use `.data` to access the tracklist directly instead of the # convenient `.tracklist` property, which will strip out useful artist # information and leave us with skeleton `Artist` objects that will # each make an API call just to get the same data back. tracks = self.get_tracks(result.data['tracklist']) # Extract information for the optional AlbumInfo fields, if possible. va = result.data['artists'][0].get('name', '').lower() == 'various' year = result.data.get('year') mediums = [t.medium for t in tracks] country = result.data.get('country') data_url = result.data.get('uri') style = self.format(result.data.get('styles')) genre = self.format(result.data.get('genres')) discogs_albumid = self.extract_release_id(result.data.get('uri')) # Extract information for the optional AlbumInfo fields that are # contained on nested discogs fields. albumtype = media = label = catalogno = labelid = None if result.data.get('formats'): albumtype = ', '.join(result.data['formats'][0].get( 'descriptions', [])) or None media = result.data['formats'][0]['name'] if result.data.get('labels'): label = result.data['labels'][0].get('name') catalogno = result.data['labels'][0].get('catno') labelid = result.data['labels'][0].get('id') # Additional cleanups (various artists name, catalog number, media). if va: artist = config['va_name'].as_str() if catalogno == 'none': catalogno = None # Explicitly set the `media` for the tracks, since it is expected by # `autotag.apply_metadata`, and set `medium_total`. for track in tracks: track.media = media track.medium_total = mediums.count(track.medium) # Discogs does not have track IDs. Invent our own IDs as proposed # in #2336. track.track_id = str(album_id) + "-" + track.track_alt # Retrieve master release id (returns None if there isn't one). master_id = result.data.get('master_id') # Assume `original_year` is equal to `year` for releases without # a master release, otherwise fetch the master release. original_year = self.get_master_year(master_id) if master_id else year return AlbumInfo(album=album, album_id=album_id, artist=artist, artist_id=artist_id, tracks=tracks, albumtype=albumtype, va=va, year=year, label=label, mediums=len(set(mediums)), releasegroup_id=master_id, catalognum=catalogno, country=country, style=style, genre=genre, media=media, original_year=original_year, data_source='Discogs', data_url=data_url, discogs_albumid=discogs_albumid, discogs_labelid=labelid, discogs_artistid=artist_id)
def get_album_info(self, result): """Returns an AlbumInfo object for a discogs Release object. """ # Explicitly reload the `Release` fields, as they might not be yet # present if the result is from a `discogs_client.search()`. if not result.data.get('artists'): result.refresh() # Sanity check for required fields. The list of required fields is # defined at Guideline 1.3.1.a, but in practice some releases might be # lacking some of these fields. This function expects at least: # `artists` (>0), `title`, `id`, `tracklist` (>0) # https://www.discogs.com/help/doc/submission-guidelines-general-rules if not all([ result.data.get(k) for k in ['artists', 'title', 'id', 'tracklist'] ]): self._log.warn(u"Release does not contain the required fields") return None artist, artist_id = self.get_artist([a.data for a in result.artists]) album = re.sub(r' +', ' ', result.title) album_id = result.data['id'] # Use `.data` to access the tracklist directly instead of the # convenient `.tracklist` property, which will strip out useful artist # information and leave us with skeleton `Artist` objects that will # each make an API call just to get the same data back. tracks = self.get_tracks(result.data['tracklist']) # Extract information for the optional AlbumInfo fields, if possible. va = result.data['artists'][0].get('name', '').lower() == 'various' year = result.data.get('year') mediums = len(set(t.medium for t in tracks)) country = result.data.get('country') data_url = result.data.get('uri') # Extract information for the optional AlbumInfo fields that are # contained on nested discogs fields. albumtype = media = label = catalogno = None if result.data.get('formats'): albumtype = ', '.join(result.data['formats'][0].get( 'descriptions', [])) or None media = result.data['formats'][0]['name'] if result.data.get('labels'): label = result.data['labels'][0].get('name') catalogno = result.data['labels'][0].get('catno') # Additional cleanups (various artists name, catalog number, media). if va: artist = config['va_name'].as_str() if catalogno == 'none': catalogno = None # Explicitly set the `media` for the tracks, since it is expected by # `autotag.apply_metadata`, and set `medium_total`. for track in tracks: track.media = media track.medium_total = mediums return AlbumInfo(album, album_id, artist, artist_id, tracks, asin=None, albumtype=albumtype, va=va, year=year, month=None, day=None, label=label, mediums=mediums, artist_sort=None, releasegroup_id=None, catalognum=catalogno, script=None, language=None, country=country, albumstatus=None, media=media, albumdisambig=None, artist_credit=None, original_year=None, original_month=None, original_day=None, data_source='Discogs', data_url=data_url)
def album_for_id(self, album_id): """Fetch an album by its Spotify ID or URL and return an AlbumInfo object or None if the album is not found. :param album_id: Spotify ID or URL for the album :type album_id: str :return: AlbumInfo object for album :rtype: beets.autotag.hooks.AlbumInfo or None """ spotify_id = self._get_id('album', album_id) if spotify_id is None: return None album_data = self._handle_response(requests.get, self.album_url + spotify_id) artist, artist_id = self.get_artist(album_data['artists']) date_parts = [ int(part) for part in album_data['release_date'].split('-') ] release_date_precision = album_data['release_date_precision'] if release_date_precision == 'day': year, month, day = date_parts elif release_date_precision == 'month': year, month = date_parts day = None elif release_date_precision == 'year': year = date_parts[0] month = None day = None else: raise ui.UserError(u"Invalid `release_date_precision` returned " u"by {} API: '{}'".format( self.data_source, release_date_precision)) tracks = [] medium_totals = collections.defaultdict(int) for i, track_data in enumerate(album_data['tracks']['items'], start=1): track = self._get_track(track_data) track.index = i medium_totals[track.medium] += 1 tracks.append(track) for track in tracks: track.medium_total = medium_totals[track.medium] return AlbumInfo( album=album_data['name'], album_id=spotify_id, artist=artist, artist_id=artist_id, tracks=tracks, albumtype=album_data['album_type'], va=len(album_data['artists']) == 1 and artist.lower() == 'various artists', year=year, month=month, day=day, label=album_data['label'], mediums=max(medium_totals.keys()), data_source=self.data_source, data_url=album_data['external_urls']['spotify'], )
def get_album_info(self, item, va_likely): """Convert json data into a format beets can read""" # If a preferred lang is available use that instead album_name = item["name"] for lang in self.lang: if lang in item["names"]: album_name = item["names"][lang] break album_id = item["link"][6:] country = "JP" catalognum = item["catalog"] # Get Artist information if "performers" in item and len(item["performers"]) > 0: artist_type = "performers" else: artist_type = "composers" artists = [] for artist in item[artist_type]: for lang in self.lang: if lang in artist["names"]: artists.append(artist["names"][lang]) break artist = artists[0] if "link" in item[artist_type][0]: artist_id = item[artist_type][0]["link"][7:] else: artist_id = None # Get Track metadata Tracks = [] total_index = 0 for disc_index, disc in enumerate(item["discs"]): for track_index, track in enumerate(disc["tracks"]): total_index += 1 title = list(track["names"].values())[0] for lang in self.lang: if lang in track["names"]: title = track["names"][lang] break index = total_index if track["track_length"] == "Unknown": length = 0 else: length = track["track_length"].split(":") length = (float(length[0]) * 60) + float(length[1]) media = item["media_format"] medium = disc_index medium_index = track_index new_track = TrackInfo( title, int(index), length=float(length), index=int(index), medium=int(medium), medium_index=int(medium_index), medium_total=item["discs"].count, ) Tracks.append(new_track) # Format Album release date release_date = item["release_date"].split("-") year = release_date[0] month = release_date[1] day = release_date[2] for lang in self.lang: if lang in item["publisher"]["names"]: label = item["publisher"]["names"][lang] mediums = len(item["discs"]) media = item["media_format"] data_url = item["vgmdb_link"] return AlbumInfo( album_name, str(album_id), artist, str(artist_id), Tracks, asin=None, albumtype=None, va=False, year=int(year), month=int(month), day=int(day), label=label, mediums=int(mediums), media=str(media), data_source="VGMdb", data_url=str(data_url), country=str(country), catalognum=str(catalognum), )
def get_album_info(self, item): """"Convert JSON data into a format beets can read.""" album_name, language = self.get_preferred_name(item) album_id = item['id'] catalognum = (item['catalogNumber'] if 'catalogNumber' in item else None) artist = item['artistString'] artist_id = None artist_credit = None va = (artist == 'Various artists' or item['discType'] == 'Compilation') # if compilation # More detailed artist information if 'artists' in item and not self.config['canonical_artists'].get(): orig_artist = artist # the original artist before we start trying to find better ones artist_corrected = False producers = [ _artist for _artist in item['artists'] if 'Producer' in _artist['categories'].split(', ') and not _artist['isSupport'] ] circles = [ _artist for _artist in item['artists'] if 'Circle' in _artist['categories'].split(', ') and not _artist['isSupport'] ] for val in self.config['artist_priority'].as_str_seq(): if val == 'circles': for _artist in circles: if 'artist' in _artist: if (_artist['artist']['name'] in self.config['circles_exclude'].as_str_seq()\ and not len(producers) > 1): # Use a circle, even if it's excluded, when there are multiple primary producers break if ('Default' in _artist['roles'].split(', ') or orig_artist == 'Various artists'): artist_credit = orig_artist artist = _artist['artist']['name'] artist_id = _artist['artist']['id'] artist_corrected = True break else: artist = _artist['name'] elif val == 'producers': if len(producers) == 1: _artist = producers[0] artist_credit = orig_artist artist = _artist['artist'][ 'name'] if 'artist' in _artist else _artist['name'] artist_id = _artist['artist'][ 'id'] if 'artist' in _artist else None artist_corrected = True if artist_corrected: break albumtype = None or item['discType'] year = item['releaseDate']['year'] if 'year' in item[ 'releaseDate'] else None month = item['releaseDate']['month'] if 'month' in item[ 'releaseDate'] else None day = item['releaseDate']['day'] if 'day' in item[ 'releaseDate'] else None mediums = 0 disctitles = None if 'discs' in item: mediums = len(item['discs']) disctitles = { disc['discNumber']: disc['name'] for disc in item['discs'] } label = None for _artist in item['artists']: if 'Label' in _artist['categories'].split(', '): label = _artist['name'] break tracks = self.tracks_for_album_id(album_id) track_index = 1 for track in tracks: if track.medium_index > track_index: track_index = track.medium_index track.index = track_index track_index += 1 if disctitles and track.medium and (track.medium in disctitles)\ and disctitles[track.medium]: track.disctitle = disctitles[track.medium] return AlbumInfo( album_name, album_id, artist, artist_id, tracks, albumtype=albumtype, va=va, year=year, month=month, day=day, label=label, mediums=mediums, artist_sort=None, catalognum=catalognum, script='utf-8', # VocaDB's JSON responses are encoded in UTF-8 language=language, country=None, artist_credit=artist_credit, data_source='VocaDB', data_url=(self.base_url + '/albums/%d' % album_id))