示例#1
0
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
示例#2
0
 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)
示例#3
0
 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],
     )
示例#4
0
 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}")
示例#5
0
文件: beatport.py 项目: wickism/beets
    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)
示例#6
0
    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)

                         )
示例#7
0
    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)
示例#8
0
    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)
示例#9
0
    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'],
        )
示例#10
0
    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),
                )
示例#11
0
    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))