def browse(self, uri):
        logger.debug('browse: %r', uri)
        if not uri:
            return []

        if uri in self._refs:
            return self._refs[uri]

        # show root
        if uri == self._archive_uri_base:
            # add current stream
            refs = [self._track_to_ref(self._stream_track, self._stream_uri)]
            # browse archive
            fd = urllib.urlopen(self._archive_url)
            soup = BeautifulSoup(fd)
            container = soup.find(id='listingContainer')
            if container:
                for link in soup.find_all('a'):
                    url = link.get('href', None)
                    name = link.string
                    if url and name and name[0] in '1234567':
                        # show active shows only
                        # former shows are down
                        # file names for special events/shows are hard to parse
                        refs.append(
                            Ref.album(uri=self._archive_uri % url, name=name))
                if len(refs) > 0:
                    self._refs[uri] = refs
            return refs

        parts = uri.split(':')

        # browse archive
        # uri == 'bassdrive:archive:/url
        if len(parts) == 3 and parts[1] == 'archive':
            base_url = parts[2]
            fd = urllib.urlopen('http://archives.bassdrivearchive.com%s' %
                                base_url)
            soup = BeautifulSoup(fd)
            refs = []
            for link in soup.find_all('a'):
                url = link.get('href', None)
                name = str(link.string).strip('/')
                if url and name and str(url[0]) != '/':
                    name = str(name).strip()
                    url = base_url + url
                    ref_uri = self._archive_uri % url
                    logger.debug('ref_uri: %r', ref_uri)
                    if url[-1] == '/':
                        refs.append(Ref.album(uri=ref_uri, name=name))
                    else:
                        track = self._link_to_track(ref_uri)
                        if track:
                            refs.append(self._track_to_ref(track, ref_uri))
            if len(refs) > 0:
                self._refs[uri] = refs
            return refs

        logger.warning('Unknown uri: %r', uri)
        return []
def test_browse_charts(config, library, genres, charts, lookup):
    responses.add(responses.GET, re.compile(r'.*/genres\b.*'), json=genres)
    responses.add(responses.GET, re.compile(r'.*/charts\b.*'), json=charts)
    responses.add(responses.GET, re.compile(r'.*/lookup\b.*'), json=lookup)
    assert library.browse('podcast+itunes:charts:1000') == [
        Ref.album(name='foo', uri='podcast+http://example.com/1234'),
        Ref.album(name='bar', uri='podcast+http://example.com/5678')
    ]
Exemple #3
0
def createRef(refType, name, uri):
    if refType == Ref.TRACK:
        return Ref.track(name=name, uri=uri)
    elif refType == Ref.ALBUM:
        return Ref.album(name=name, uri=uri)
    elif refType == Ref.ARTIST:
        return Ref.artist(name=name, uri=uri)
    elif refType == Ref.DIRECTORY:
        return Ref.directory(name=name, uri=uri)
    elif refType == Ref.PLAYLIST:
        return Ref.album(name=name, uri=uri)
    else:
        return None
def test_album_ref():
    assert translator.ref({
        'DisplayName': 'Foo',
        'URI': BASEURI + '/foo',
        'Type': 'container',
        'TypeEx': ALBUM_TYPE
    }) == Ref.album(uri=BASEURI+'/foo', name='Foo')
 def raw_album_to_ref(self, album):
     if album is None:
         return None
     return Ref.album(
         name=album.get("title") or album.get("name") or UNKNOWN_ALBUM,
         uri=uri.get_album_uri(album.get("id")),
     )
def test_album_ref():
    assert translator.ref({
        'DisplayName': 'Foo',
        'URI': BASEURI + '/foo',
        'Type': 'container',
        'TypeEx': ALBUM_TYPE
    }) == Ref.album(uri=BASEURI+'/foo', name='Foo')
Exemple #7
0
def ref(obj, uri=uri):
    identifier = obj["identifier"]
    mediatype = obj["mediatype"]
    if mediatype == "collection":
        return Ref.directory(name=name(obj), uri=uri(identifier))
    else:
        return Ref.album(name=name(obj), uri=uri(identifier))
def ref(obj, uri=uri):
    identifier = obj['identifier']
    mediatype = obj['mediatype']
    if mediatype == 'collection':
        return Ref.directory(name=name(obj), uri=uri(identifier))
    else:
        return Ref.album(name=name(obj), uri=uri(identifier))
    def test_listallinfo_without_uri(self):
        tracks = [
            Track(uri="dummy:/a", name="a"),
            Track(uri="dummy:/foo/b", name="b"),
        ]
        self.backend.library.dummy_library = tracks
        self.backend.library.dummy_browse_result = {
            "dummy:/": [
                Ref.track(uri="dummy:/a", name="a"),
                Ref.directory(uri="dummy:/foo", name="foo"),
                Ref.album(uri="dummy:/album", name="album"),
                Ref.artist(uri="dummy:/artist", name="artist"),
                Ref.playlist(uri="dummy:/pl", name="pl"),
            ],
            "dummy:/foo": [Ref.track(uri="dummy:/foo/b", name="b")],
        }

        self.send_request("listallinfo")

        self.assertInResponse("file: dummy:/a")
        self.assertInResponse("Title: a")
        self.assertInResponse("directory: dummy/foo")
        self.assertInResponse("directory: dummy/album")
        self.assertInResponse("directory: dummy/artist")
        self.assertInResponse("directory: dummy/pl")
        self.assertInResponse("file: dummy:/foo/b")
        self.assertInResponse("Title: b")
        self.assertInResponse("OK")
Exemple #10
0
    def test_listallinfo_without_uri(self):
        tracks = [
            Track(uri='dummy:/a', name='a'),
            Track(uri='dummy:/foo/b', name='b')
        ]
        self.backend.library.dummy_library = tracks
        self.backend.library.dummy_browse_result = {
            'dummy:/': [
                Ref.track(uri='dummy:/a', name='a'),
                Ref.directory(uri='dummy:/foo', name='foo'),
                Ref.album(uri='dummy:/album', name='album'),
                Ref.artist(uri='dummy:/artist', name='artist'),
                Ref.playlist(uri='dummy:/pl', name='pl')
            ],
            'dummy:/foo': [Ref.track(uri='dummy:/foo/b', name='b')]
        }

        self.send_request('listallinfo')

        self.assertInResponse('file: dummy:/a')
        self.assertInResponse('Title: a')
        self.assertInResponse('directory: /dummy/foo')
        self.assertInResponse('directory: /dummy/album')
        self.assertInResponse('directory: /dummy/artist')
        self.assertInResponse('directory: /dummy/pl')
        self.assertInResponse('file: dummy:/foo/b')
        self.assertInResponse('Title: b')
        self.assertInResponse('OK')
Exemple #11
0
def spotify_browse_process_results(results):
    logger.debug('Processing spotify browse result')
    if 'categories' in results:
        result_list = results['categories']
        browse_uri = 'spotifyweb:browse:categories:'
        arr = [
            Ref.directory(uri=browse_uri + cat['id'], name=cat['name'])
            for cat in result_list['items']
        ]
    elif 'playlists' in results:
        result_list = results['playlists']
        arr = [
            Ref.playlist(uri=playlist['uri'], name=playlist['name'])
            for playlist in result_list['items']
        ]
    elif 'albums' in results:
        result_list = results['albums']
        arr = [
            Ref.album(uri=album['uri'], name=album['name'])
            for album in result_list['items']
        ]
    else:
        result_list = None
        arr = []

    cont = result_list is not None and result_list['next'] is not None
    logger.debug('Spotify browse result cont: %s' % cont)
    return arr, cont
 def select_favourites(self):
     self.add_level(_favourites_ref)
     favs=self.favourites.favourites
     refs=[]
     for f in favs:
         name=f[0]
         uri=f[1]
         ref=_favourites_cache.get(uri)
         if ref is None:
             ref=self.core.library.browse(uri).get()
             if ref is not None:
                 if len(ref) == 0:
                     ref=self.core.library.lookup(uri).get()
                     if len(ref)>0:ref=Ref.track(name=name,uri=uri)
                     else: ref = None
                 elif len(ref) == 1:
                     ref=ref[0]
                 else:
                     r = next((rf for rf in ref if rf.uri==uri),None)
                     if r is not None:
                         ref=r
                     elif all(r.type in self.playable_types for r in ref):
                         ref=Ref.album(name=f[0],uri=f[1])
                     else:
                         ref=Ref.directory(name=f[0],uri=f[1])
                 if ref is not None:
                     _favourites_cache.add(uri,ref)
         if ref is not None:
             refs.append(ref)
     self.current_list = refs
 def select_subscriptions(self):
     if not self.include_subscriptions: return
     self.add_level(_subscriptions_ref)
     refs=[Ref.album(name=c.name,
         uri='{}{}'.format(_channels_scheme,c.uri)) for c in \
         self.subscriptions.channels]  
     self.current_list = refs
def spotify_browse_process_results(results):
    logger.debug('Processing spotify browse result')
    if 'categories' in results:
        result_list = results['categories']
        browse_uri = 'spotifyweb:browse:categories:'
        arr = [Ref.directory(uri=browse_uri + cat['id'],
                             name=cat['name'])
               for cat in result_list['items']]
    elif 'playlists' in results:
        result_list = results['playlists']
        arr = [Ref.playlist(uri=playlist['uri'],
                            name=playlist['name'])
               for playlist in result_list['items']]
    elif 'albums' in results:
        result_list = results['albums']
        arr = [Ref.album(uri=album['uri'],
                         name=album['name'])
               for album in result_list['items']]
    else:
        result_list = None
        arr = []

    cont = result_list is not None and result_list['next'] is not None
    logger.debug('Spotify browse result cont: %s' % cont)
    return arr, cont
def _ref(metadata):
    identifier = metadata['identifier']
    uri = uritools.uricompose(SCHEME, path=identifier)
    name = metadata.get('title', identifier)
    if metadata.get('mediatype', 'collection') == 'collection':
        return Ref.directory(uri=uri, name=name)
    else:
        return Ref.album(uri=uri, name=name)
    def browse(self, uri):
        logger.debug("Request to browse %s in SpotifyWebLibraryProvider", uri)
        if uri == self.root_directory.uri:
            return self._root
        elif uri == 'spotifyweb:artists':
            return self._cache.sortedArtists
            # return Ref directory with all artists
        elif uri.startswith('spotifyweb:artist:'):
            # get artist uri
            return self._cache.artists2albums.get(uri)
            # return Ref directory with all albums for artist
        elif uri.startswith('spotifyweb:album:'):
            # get album uri
            return self._cache.albums2tracks.get(uri)
            # return Ref directory with all tracks for album
        elif uri == 'spotifyweb:albums':
            return self._cache.sortedAlbums
            # return Ref directory for all albums
        elif uri.startswith('spotifyweb:featured-playlists') or \
             uri.startswith('spotifyweb:new-releases') or \
             uri.startswith('spotifyweb:categories') :
            
            ids = uri.split(':')
            webapi_url = 'browse/' + '/'.join(ids[1:])

            # we browse the /playlists endpoint for categories
            if len(ids) == 3 and ids[1] == 'categories':
                webapi_url += '/playlists'

            try:
                offset = 0
                arr = []

                while True:
                    results = self.sp_webapi()._get(webapi_url, limit=50, offset=offset)
                    if results.has_key('categories'):
                        result_list = results['categories']
                        arr += [ Ref.directory(uri='spotifyweb:categories:'+cat['id'],
                                        name=cat['name']) for cat in result_list['items']]
                    elif results.has_key('playlists'):
                        result_list = results['playlists']
                        arr += [ Ref.playlist(uri=playlist['uri'],
                                        name=playlist['name']) for playlist in result_list['items']]
                    elif results.has_key('albums'):
                        result_list = results['albums']
                        arr += [ Ref.album(uri=album['uri'],
                                        name=album['name']) for album in result_list['items']]
                    if result_list['next'] is None:
                        break
                    offset = len(arr)

                return arr
            except spotipy.SpotifyException as e:
                logger.info('spotipy called failed')
                return []
        else:
            return []
Exemple #17
0
def test_album_ref():
    assert translator.ref(
        {
            "DisplayName": "Foo",
            "URI": BASEURI + "/foo",
            "Type": "container",
            "TypeEx": ALBUM_TYPE,
        }
    ) == Ref.album(uri=BASEURI + "/foo", name="Foo")
def spotify_albums_results(results):
    logger.debug('Processing spotify albums result')
    albums = [Ref.album(uri=album['uri'],
                        name=album['name'])
              for album in results['items']]
    logger.debug('Processing spotify albums result; next %s' % results['next'])
    cont = results['next'] is not None
    logger.debug('Spotify get albums result cont: %s' % cont)
    return albums, cont
Exemple #19
0
def spotify_albums_results(results):
    logger.debug('Processing spotify albums result')
    albums = [
        Ref.album(uri=album['uri'], name=album['name'])
        for album in results['items']
    ]
    logger.debug('Processing spotify albums result; next %s' % results['next'])
    cont = results['next'] is not None
    logger.debug('Spotify get albums result cont: %s' % cont)
    return albums, cont
Exemple #20
0
    def loadRootAlbumRefs(self):
        refs = []
        # get the user details
        payload = {'client_id': self.clientId}

        r = requests.get(sc_api + '/users/' + self.userId,
                         params=payload,
                         headers=defaultHeaders,
                         timeout=10)
        jsono = json.loads(r.text)
        # get stream node
        streamUri = scs_uri_stream
        ref = Ref.album(name=myStreamLabel, uri=streamUri)
        imguri = jsono['avatar_url']
        imguri = imguri.replace("large.jpg", imageSelector)
        self.imageCache[streamUri] = Image(uri=imguri)
        refs.append(ref)

        # get followings
        logger.info("Loading followings for user " + self.userId)
        payload = {'client_id': self.clientId, 'limit': limit}
        r = requests.get(sc_api + '/users/' + self.userId + '/followings',
                         params=payload,
                         headers=defaultHeaders,
                         timeout=10)

        if r.status_code != 200:
            logger.warn("Got HTTP " + str(r.status_code))

        jsono = json.loads(r.text)

        for follow in jsono['collection']:
            followingUri = scs_uri_user + str(follow['id'])
            ref = Ref.album(name=follow['username'], uri=followingUri)
            imguri = follow['avatar_url']
            imguri = imguri.replace("large.jpg", imageSelector)
            self.imageCache[followingUri] = Image(uri=imguri)
            refs.append(ref)
        self.refCache[scs_uri_root] = refs
        return refs
Exemple #21
0
def make_ref(data):
    if isinstance(data, Track):
        ref = Ref.track(uri=data.uri, name=data.name)
    elif isinstance(data, Album):
        ref = Ref.album(uri=data.uri, name=data.name)
    elif isinstance(data, Artist):
        ref = Ref.artist(uri=data.uri, name=data.name)
    elif isinstance(data, Playlist):
        ref = Ref.playlist(uri=data.uri, name=data.name)
    elif isinstance(data, Directory):
        ref = Ref.directory(uri=data.uri, name=data.name)

    return RefWithData(ref, data)
Exemple #22
0
def test_browse_albums(tmp_path, caplog):
    make_album(tmp_path / "media" / "a1", {"name": "John Doe - One Day"})
    provider = KitchenLibraryProvider(backend={}, config=make_config(tmp_path))

    result = provider.browse("kitchen:albums")

    assert caplog.text == ""
    assert len(result) > 0
    assert result[0].type == "album"
    assert result == [
        Ref.album(uri="kitchen:album:95506c273e4ecb0333d19824d66ab586",
                  name="John Doe - One Day")
    ]
 def loadRootAlbumRefs(self):
   refs=[]
   
   # latest shows
   r =requests.get(mx_api + "/" + self.mxaccount,timeout=10)
   logger.info("Loading root")
   jsono = json.loads(r.text)
   ref = Ref.album(name=latestShowsLabel, uri=mc_uri_stream)
   imguri = jsono['pictures']['320wx320h']
   self.imageCache[mc_uri_stream] = Image(uri=imguri)
   refs.append(ref)
   
   # following's tracks
   r =requests.get(mx_api + "/" + self.mxaccount + '/following/',timeout=10)
   logger.info("Loading followings")
   jsono = json.loads(r.text)
   for p in jsono['data']:
     accounturi = mc_uri + p['key']
     ref = Ref.album(name=p['name'], uri=accounturi)
     self.imageCache[accounturi] = Image(uri=p['pictures']['320wx320h'])
     refs.append(ref)
   self.refCache[mc_uri_root] = refs
   return refs
Exemple #24
0
    def browse(self, uri):
        result = []
        if not uri.startswith('yle:'):
            return result

        if uri == 'yle:root':
            categories = self.__yleapi.get_yle_category('root')
            for item in categories:
                result.append(Ref.directory(name=item['name'],
                                            uri=item['uri']))
            result.append(
                Ref.directory(name='Live radio', uri='yle:category:live'))
            return result

        elif uri.startswith('yle:category:'):
            item_url = uri.split(':')
            id = item_url[2]
            result = []
            if id == 'live':
                for station in LIVERADIO:
                    result.append(
                        Ref.track(name=LIVERADIO[station],
                                  uri='yle:liveradio:{0}'.format(station)))
            else:
                categories = self.__yleapi.get_yle_category(id)
                if categories:
                    for item in categories:
                        result.append(
                            Ref.directory(name=item['name'], uri=item['uri']))
                else:
                    albums, tracks = self.__yleapi.get_yle_item(offset=0,
                                                                category=id,
                                                                limit=100)
                    for i in albums:
                        result.append(
                            Ref.album(name=albums[i]['name'],
                                      uri=albums[i]['uri']))
            return result

        elif uri.startswith('yle:series:'):
            item_url = uri.split(':')
            id = item_url[2]
            tracks = self.__yleapi.get_yle_series_info(id)
            result = []
            for track in tracks:
                result.append(Ref.track(name=track['name'], uri=track['uri']))
            return result

        return result
Exemple #25
0
def test_browse_stations(tmp_path, caplog):
    make_station(tmp_path / "media" / "r1", {
        "name": "Radio 1",
        "stream": "http://radio1.com/stream"
    })
    provider = KitchenLibraryProvider(backend={}, config=make_config(tmp_path))

    result = provider.browse("kitchen:stations")

    assert caplog.text == ""
    assert len(result) > 0
    assert result[0].type == "album"
    assert result == [
        Ref.album(uri="kitchen:station:770e06d40b8b4d64e89c24098d25fdc2",
                  name="Radio 1")
    ]
 def browse(self, uri):
     logger.debug(u"Browse being called for %s" % uri)
     level = urisplit(uri).path
     query = self._sanitize_query(dict(urisplit(uri).getquerylist()))
     logger.debug("Got parsed to level: %s - query: %s" % (level,
                                                           query))
     result = []
     if not level:
         logger.error("No level for uri %s" % uri)
         # import pdb; pdb.set_trace()
     if level == 'root':
         for row in self._browse_genre():
             result.append(Ref.directory(
                 uri=uricompose('beetslocal',
                                None,
                                'genre',
                                dict(genre=row[0])),
                 name=row[0] if bool(row[0]) else u'No Genre'))
     elif level == "genre":
         # artist refs not browsable via mpd
         for row in self._browse_artist(query):
             result.append(Ref.directory(
                 uri=uricompose('beetslocal',
                                None,
                                'artist',
                                dict(genre=query['genre'][0],
                                     artist=row[1])),
                 name=row[0] if bool(row[0]) else u'No Artist'))
     elif level == "artist":
         for album in self._browse_album(query):
             result.append(Ref.album(
                 uri=uricompose('beetslocal',
                                None,
                                'album',
                                dict(album=album.id)),
                 name=album.album))
     elif level == "album":
         for track in self._browse_track(query):
             result.append(Ref.track(
                 uri="beetslocal:track:%s:%s" % (
                     track.id,
                     uriencode(track.path, '/')),
                 name=track.title))
     else:
         logger.debug('Unknown URI: %s', uri)
     # logger.debug(result)
     return result
Exemple #27
0
    def test_listall_without_uri(self):
        tracks = [Track(uri='dummy:/a', name='a'),
                  Track(uri='dummy:/foo/b', name='b')]
        self.backend.library.dummy_library = tracks
        self.backend.library.dummy_browse_result = {
            'dummy:/': [Ref.track(uri='dummy:/a', name='a'),
                        Ref.directory(uri='dummy:/foo', name='foo'),
                        Ref.album(uri='dummy:/album', name='album'),
                        Ref.playlist(uri='dummy:/pl', name='pl')],
            'dummy:/foo': [Ref.track(uri='dummy:/foo/b', name='b')]}

        self.sendRequest('listall')

        self.assertInResponse('file: dummy:/a')
        self.assertInResponse('directory: /dummy/foo')
        self.assertInResponse('directory: /dummy/album')
        self.assertInResponse('directory: /dummy/pl')
        self.assertInResponse('file: dummy:/foo/b')
        self.assertInResponse('OK')
 def browse(self, uri):
     logger.debug(u"Browse being called for %s" % uri)
     level = urisplit(uri).path
     query = self._sanitize_query(dict(urisplit(uri).getquerylist()))
     logger.debug("Got parsed to level: %s - query: %s" % (level, query))
     result = []
     if not level:
         logger.error("No level for uri %s" % uri)
         # import pdb; pdb.set_trace()
     if level == 'root':
         for row in self._browse_genre():
             result.append(
                 Ref.directory(
                     uri=uricompose('beetslocal', None, 'genre',
                                    dict(genre=row[0])),
                     name=row[0] if bool(row[0]) else u'No Genre'))
     elif level == "genre":
         # artist refs not browsable via mpd
         for row in self._browse_artist(query):
             result.append(
                 Ref.directory(
                     uri=uricompose(
                         'beetslocal', None, 'artist',
                         dict(genre=query['genre'][0], artist=row[1])),
                     name=row[0] if bool(row[0]) else u'No Artist'))
     elif level == "artist":
         for album in self._browse_album(query):
             result.append(
                 Ref.album(uri=uricompose('beetslocal', None, 'album',
                                          dict(album=album.id)),
                           name=album.album))
     elif level == "album":
         for track in self._browse_track(query):
             result.append(
                 Ref.track(uri="beetslocal:track:%s:%s" %
                           (track.id, uriencode(track.path, '/')),
                           name=track.title))
     else:
         logger.debug('Unknown URI: %s', uri)
     # logger.debug(result)
     return result
Exemple #29
0
    def test_listall_without_uri(self):
        tracks = [Track(uri="dummy:/a", name="a"), Track(uri="dummy:/foo/b", name="b")]
        self.backend.library.dummy_library = tracks
        self.backend.library.dummy_browse_result = {
            "dummy:/": [
                Ref.track(uri="dummy:/a", name="a"),
                Ref.directory(uri="dummy:/foo", name="foo"),
                Ref.album(uri="dummy:/album", name="album"),
                Ref.playlist(uri="dummy:/pl", name="pl"),
            ],
            "dummy:/foo": [Ref.track(uri="dummy:/foo/b", name="b")],
        }

        self.sendRequest("listall")

        self.assertInResponse("file: dummy:/a")
        self.assertInResponse("directory: /dummy/foo")
        self.assertInResponse("directory: /dummy/album")
        self.assertInResponse("directory: /dummy/pl")
        self.assertInResponse("file: dummy:/foo/b")
        self.assertInResponse("OK")
Exemple #30
0
def list_user(user_name):

    try:
        name = enc(user_name[1:-1])
        decoded = dec(urllib.unquote(name))
        pre0 = u'{} '.format(decoded)
        pre = u"{}'s ".format(decoded)
    except:
        pre0 = ''
        pre = u''

    cloudcasts = Ref.album(name=pre + u'cloudcasts',
                           uri=make_special_uri(user_name, uri_cloudcasts))
    favorites = Ref.directory(name=pre + u'favorites',
                              uri=make_special_uri(user_name, uri_favorites))
    playlists = Ref.directory(name=pre + u'playlists',
                              uri=make_special_uri(user_name, uri_playlists))
    following = Ref.directory(name=pre0 + u'follows',
                              uri=make_special_uri(user_name, uri_following))
    followers = Ref.directory(name=pre + u'followers',
                              uri=make_special_uri(user_name, uri_followers))
    listens = Ref.directory(name=pre0 + u'listened to',
                            uri=make_special_uri(user_name, uri_listens))
    return [cloudcasts, favorites, playlists, following, followers, listens]
def releases_to_mopidy_albums(tunigo_releases):
    releases = []
    for release in tunigo_releases:
        name = '{} - {}'.format(release.artist_name, release.album_name)
        releases.append(Ref.album(uri=release.uri, name=name))
    return releases
Exemple #32
0
def create_album(tidal_album):
    return Ref.album(uri="tidal:album:" + str(tidal_album.id),
                     name=tidal_album.name)
Exemple #33
0
 def browse(self, uri):
     logger.info("YTMusic browsing uri \"%s\"", uri)
     if uri == "ytm:root":
         return [
             Ref.directory(uri="ytm:artist", name="Artists"),
             Ref.directory(uri="ytm:album", name="Albums"),
             Ref.directory(uri="ytm:liked", name="Liked Songs"),
         ]
     elif uri == "ytm:artist":
         try:
             library_artists = [
                 Ref.artist(
                     uri=f"ytm:artist?id={a['browseId']}&upload=false",
                     name=a["artist"])
                 for a in API.get_library_artists(limit=100)
             ]
             logger.info("YTMusic found %d artists in library",
                         len(library_artists))
         except Exception:
             logger.exception("YTMusic failed getting artists from library")
             library_artists = []
         # try:
         #     upload_artists = [
         #         Ref.artist(uri=f"ytm:artist?id={a['browseId']}&upload=true", name=a["artist"])
         #         for a in API.get_library_upload_artists(limit=100)
         #     ]
         #     logger.info("YTMusic found %d uploaded artists", len(upload_artists))
         # except Exception:
         #     logger.exception("YTMusic failed getting uploaded artists")
         #     upload_artists = []
         return library_artists  # + upload_artists
     elif uri == "ytm:album":
         try:
             library_albums = [
                 Ref.album(uri=f"ytm:album?id={a['browseId']}&upload=false",
                           name=a["title"])
                 for a in API.get_library_albums(limit=100)
             ]
             logger.info("YTMusic found %d albums in library",
                         len(library_albums))
         except Exception:
             logger.exception("YTMusic failed getting albums from library")
             library_albums = []
         # try:
         #     upload_albums = [
         #         Ref.album(uri=f"ytm:album?id={a['browseId']}&upload=true", name=a["title"])
         #         for a in API.get_library_upload_albums(limit=100)
         #     ]
         #     logger.info("YTMusic found %d uploaded albums", len(upload_albums))
         # except Exception:
         #     logger.exception("YTMusic failed getting uploaded albums")
         #     upload_albums = []
         return library_albums  # + upload_albums
     elif uri == "ytm:liked":
         try:
             res = API.get_liked_songs(limit=100)
             logger.info("YTMusic found %d liked songs", len(res["tracks"]))
             playlistToTracks(res)
             return [
                 Ref.track(uri=f"ytm:video?id={t['videoId']}",
                           name=t["title"])
                 for t in ("tracks" in res and res["tracks"]) or []
             ]
         except Exception:
             logger.exception("YTMusic failed getting liked songs")
     elif uri.startswith("ytm:artist?"):
         id_, upload = parse_uri(uri)
         # if upload:
         #     try:
         #         res = API.get_library_upload_artist(id_)
         #         uploadArtistToTracks(res)
         #         return [
         #             Ref.track(uri=f"ytm:album?id={t['videoId']}", name=t["title"])
         #             for t in res
         #         ]
         #         logger.info("YTMusic found %d songs for uploaded artist \"%s\"", len(res), res[0]["artist"]["name"])
         #     except Exception:
         #         logger.exception("YTMusic failed getting tracks for uploaded artist \"%s\"", id_)
         # else:
         try:
             res = API.get_artist(id_)
             logger.info(
                 "YTMusic found %d songs for artist \"%s\" in library",
                 len(res["songs"]), res["name"])
             artistToTracks(res)
             return [
                 Ref.track(uri=f"ytm:video?id={t['videoId']}",
                           name=t["title"])
                 for t in ("songs" in res and "results" in res["songs"]
                           and res["songs"]["results"]) or []
             ]
         except Exception:
             logger.exception(
                 "YTMusic failed getting tracks for artist \"%s\"", id_)
     elif uri.startswith("ytm:album?"):
         id_, upload = parse_uri(uri)
         # if upload:
         #     try:
         #         res = API.get_library_upload_album(id_)
         #         uploadAlbumToTracks(res, id_)
         #         return [
         #             Ref.track(uri=f"ytm:video?id={t['videoId']}", name=t["title"])
         #             for t in ("tracks" in res and res["tracks"]) or []
         #         ]
         #         logger.info("YTMusic found %d songs for uploaded album \"%s\"", len(res["tracks"]), res["title"])
         #     except Exception:
         #         logger.exception("YTMusic failed getting tracks for uploaded album \"%s\"", id_)
         # else:
         try:
             res = API.get_album(id_)
             logger.info(
                 "YTMusic found %d songs for album \"%s\" in library",
                 len(res["tracks"]), res["title"])
             albumToTracks(res, id_)
             return [
                 Ref.track(uri=f"ytm:video?id={t['videoId']}",
                           name=t["title"])
                 for t in ("tracks" in res and res["tracks"]) or []
             ]
         except Exception:
             logger.exception(
                 "YTMusic failed getting tracks for album \"%s\"", id_)
     return []
Exemple #34
0
 def raw_album_to_ref(self, album):
     if album is None:
         return None
     return Ref.album(name=album.get('title') or album.get('name')
                      or UNKNOWN_ALBUM,
                      uri=uri.get_album_uri(album.get('id')))
def create_album(tidal_album):
    return Ref.album(uri="tidal:album:" + str(tidal_album.id),
                     name=tidal_album.name)
 def ref(album):
     return Ref.album(name=album.name, uri=album.uri)
Exemple #37
0
def _make_station_ref(station_id: str, station: StationIndex):
    return Ref.album(uri=str(StationUri(station_id)), name=station.name)
Exemple #38
0
 def ref(album):
     return Ref.album(name=album.name, uri=album.uri)
 def browse(self, uri):
     if not uri:
         return []
     logger.debug("YoutubeMusic browsing uri \"%s\"", uri)
     if uri == "youtubemusic:root":
         dirs = []
         if self.backend.auth:
             dirs += [
                 Ref.directory(uri="youtubemusic:artist", name="Artists"),
                 Ref.directory(uri="youtubemusic:album", name="Albums"),
             ]
             if self.backend.liked_songs:
                 dirs.append(
                     Ref.directory(uri="youtubemusic:liked",
                                   name="Liked Songs"))
             if self.backend.history:
                 dirs.append(
                     Ref.directory(uri="youtubemusic:history",
                                   name="Recently Played"))
             if self.backend.subscribed_artist_limit:
                 dirs.append(
                     Ref.directory(uri="youtubemusic:subscriptions",
                                   name="Subscriptions"))
         dirs.append(
             Ref.directory(uri="youtubemusic:watch",
                           name="Similar to last played"))
         if self.backend.mood_genre:
             dirs.append(
                 Ref.directory(uri="youtubemusic:mood",
                               name="Mood and Genre Playlists"))
         if self.backend._auto_playlist_refresh_rate:
             dirs.append(
                 Ref.directory(uri="youtubemusic:auto",
                               name="Auto Playlists"))
         return (dirs)
     elif uri == "youtubemusic:subscriptions" and self.backend.subscribed_artist_limit:
         try:
             subs = self.backend.api.get_library_subscriptions(
                 limit=self.backend.subscribed_artist_limit)
             logger.debug("YoutubeMusic found %d artists in subscriptions",
                          len(subs))
             return [
                 Ref.artist(uri=f"youtubemusic:artist:{a['browseId']}",
                            name=a["artist"]) for a in subs
             ]
         except Exception:
             logger.exception(
                 "YoutubeMusic failed getting artists from subscriptions")
     elif uri == "youtubemusic:artist":
         try:
             library_artists = [
                 Ref.artist(uri=f"youtubemusic:artist:{a['browseId']}",
                            name=a["artist"])
                 for a in self.backend.api.get_library_artists(limit=100)
             ]
             logger.debug("YoutubeMusic found %d artists in library",
                          len(library_artists))
         except Exception:
             logger.exception(
                 "YoutubeMusic failed getting artists from library")
             library_artists = []
         if self.backend.auth:
             try:
                 upload_artists = [
                     Ref.artist(
                         uri=f"youtubemusic:artist:{a['browseId']}:upload",
                         name=a["artist"])
                     for a in self.backend.api.get_library_upload_artists(
                         limit=100)
                 ]
                 logger.debug("YoutubeMusic found %d uploaded artists",
                              len(upload_artists))
             except Exception:
                 logger.exception(
                     "YoutubeMusic failed getting uploaded artists")
                 upload_artists = []
         else:
             upload_artists = []
         return library_artists + upload_artists
     elif uri == "youtubemusic:album":
         try:
             library_albums = [
                 Ref.album(uri=f"youtubemusic:album:{a['browseId']}",
                           name=a["title"])
                 for a in self.backend.api.get_library_albums(limit=100)
             ]
             logger.debug("YoutubeMusic found %d albums in library",
                          len(library_albums))
         except Exception:
             logger.exception(
                 "YoutubeMusic failed getting albums from library")
             library_albums = []
         if self.backend.auth:
             try:
                 upload_albums = [
                     Ref.album(
                         uri=f"youtubemusic:album:{a['browseId']}:upload",
                         name=a["title"])
                     for a in self.backend.api.get_library_upload_albums(
                         limit=100)
                 ]
                 logger.debug("YoutubeMusic found %d uploaded albums",
                              len(upload_albums))
             except Exception:
                 logger.exception(
                     "YoutubeMusic failed getting uploaded albums")
                 upload_albums = []
         else:
             upload_albums = []
         return library_albums + upload_albums
     elif uri == "youtubemusic:liked":
         try:
             res = self.backend.api.get_liked_songs(
                 limit=self.backend.playlist_item_limit)
             tracks = self.playlistToTracks(res)
             logger.debug("YoutubeMusic found %d liked songs",
                          len(res["tracks"]))
             return [Ref.track(uri=t.uri, name=t.name) for t in tracks]
         except Exception:
             logger.exception("YoutubeMusic failed getting liked songs")
     elif uri == "youtubemusic:history":
         try:
             res = self.backend.api.get_history()
             tracks = self.playlistToTracks({'tracks': res})
             logger.debug("YoutubeMusic found %d songs from recent history",
                          len(res))
             return [Ref.track(uri=t.uri, name=t.name) for t in tracks]
         except Exception:
             logger.exception(
                 "YoutubeMusic failed getting listening history")
     elif uri == "youtubemusic:watch":
         try:
             playback = self.backend.playback
             if playback.last_id is not None:
                 track_id = playback.last_id
             elif self.backend.auth:
                 hist = self.backend.api.get_history()
                 track_id = hist[0]['videoId']
             if track_id:
                 res = self.backend.api.get_watch_playlist(
                     track_id, limit=self.backend.playlist_item_limit)
                 if 'tracks' in res:
                     logger.debug(
                         "YoutubeMusic found %d watch songs for \"%s\"",
                         len(res["tracks"]), track_id)
                     res['tracks'].pop(0)
                     tracks = self.playlistToTracks(res)
                     return [
                         Ref.track(uri=t.uri, name=t.name) for t in tracks
                     ]
         except Exception:
             logger.exception("YoutubeMusic failed getting watch songs")
     elif uri == "youtubemusic:mood":
         try:
             logger.debug('YoutubeMusic loading mood/genre playlists')
             moods = {}
             response = self.backend.api._send_request(
                 'browse', {"browseId": "FEmusic_moods_and_genres"})
             for sect in nav(response, SINGLE_COLUMN_TAB + SECTION_LIST):
                 for cat in nav(sect, ['gridRenderer', 'items']):
                     title = nav(cat, [
                         'musicNavigationButtonRenderer', 'buttonText',
                         'runs', 0, 'text'
                     ]).strip()
                     endpnt = nav(cat, [
                         'musicNavigationButtonRenderer', 'clickCommand',
                         'browseEndpoint', 'browseId'
                     ])
                     params = nav(cat, [
                         'musicNavigationButtonRenderer', 'clickCommand',
                         'browseEndpoint', 'params'
                     ])
                     moods[title] = {
                         'name': title,
                         'uri': 'youtubemusic:mood:' + params + ':' + endpnt
                     }
             return [
                 Ref.directory(uri=moods[a]['uri'], name=moods[a]['name'])
                 for a in sorted(moods.keys())
             ]
         except Exception:
             logger.exception(
                 'YoutubeMusic failed to load mood/genre playlists')
     elif uri.startswith("youtubemusic:mood:"):
         try:
             ret = []
             _, _, params, endpnt = uri.split(':')
             response = self.backend.api._send_request(
                 'browse', {
                     "browseId": endpnt,
                     "params": params
                 })
             for sect in nav(response, SINGLE_COLUMN_TAB + SECTION_LIST):
                 key = []
                 if 'gridRenderer' in sect:
                     key = ['gridRenderer', 'items']
                 elif 'musicCarouselShelfRenderer' in sect:
                     key = ['musicCarouselShelfRenderer', 'contents']
                 elif 'musicImmersiveCarouselShelfRenderer' in sect:
                     key = [
                         'musicImmersiveCarouselShelfRenderer', 'contents'
                     ]
                 if len(key):
                     for item in nav(sect, key):
                         title = nav(item, ['musicTwoRowItemRenderer'] +
                                     TITLE_TEXT).strip()
                         #                           if 'subtitle' in item['musicTwoRowItemRenderer']:
                         #                               title += ' ('
                         #                               for st in item['musicTwoRowItemRenderer']['subtitle']['runs']:
                         #                                   title += st['text']
                         #                               title += ')'
                         brId = nav(item, ['musicTwoRowItemRenderer'] +
                                    NAVIGATION_BROWSE_ID)
                         ret.append(
                             Ref.playlist(
                                 uri=f"youtubemusic:playlist:{brId}",
                                 name=title))
             return (ret)
         except Exception:
             logger.exception(
                 'YoutubeMusic failed getting mood/genre playlist "%s"',
                 uri)
     elif uri == "youtubemusic:auto" and self.backend._auto_playlist_refresh_rate:
         try:
             return [
                 Ref.directory(uri=a['uri'], name=a['name'])
                 for a in self.ytbrowse
             ]
         except Exception:
             logger.exception('YoutubeMusic failed getting auto playlists')
     elif uri.startswith("youtubemusic:auto:"
                         ) and self.backend._auto_playlist_refresh_rate:
         try:
             for a in self.ytbrowse:
                 if a['uri'] == uri:
                     ret = []
                     for i in a['items']:
                         if i['type'] == 'playlist':
                             ret.append(
                                 Ref.playlist(uri=i['uri'], name=i['name']))
                             logger.debug("playlist: %s - %s", i['name'],
                                          i['uri'])
                         elif i['type'] == 'artist':
                             ret.append(
                                 Ref.artist(uri=i['uri'], name=i['name']))
                             logger.debug("artist: %s - %s", i['name'],
                                          i['uri'])
                         elif i['type'] == 'album':
                             ret.append(
                                 Ref.album(uri=i['uri'], name=i['name']))
                             logger.debug("album: %s - %s", i['name'],
                                          i['uri'])
                     return (ret)
         except Exception:
             logger.exception(
                 'YoutubeMusic failed getting auto playlist "%s"', uri)
     elif uri.startswith("youtubemusic:artist:"):
         bId, upload = parse_uri(uri)
         if upload:
             try:
                 res = self.backend.api.get_library_upload_artist(bId)
                 tracks = self.uploadArtistToTracks(res)
                 logger.debug(
                     "YoutubeMusic found %d songs for uploaded artist \"%s\"",
                     len(res), res[0]["artist"]["name"])
                 return [Ref.track(uri=t.uri, name=t.name) for t in tracks]
             except Exception:
                 logger.exception(
                     "YoutubeMusic failed getting tracks for uploaded artist \"%s\"",
                     bId)
         else:
             try:
                 res = self.backend.api.get_artist(bId)
                 tracks = self.artistToTracks(res)
                 logger.debug(
                     "YoutubeMusic found %d songs for artist \"%s\" in library",
                     len(res["songs"]), res["name"])
                 return [Ref.track(uri=t.uri, name=t.name) for t in tracks]
             except Exception:
                 logger.exception(
                     "YoutubeMusic failed getting tracks for artist \"%s\"",
                     bId)
     elif uri.startswith("youtubemusic:album:"):
         bId, upload = parse_uri(uri)
         if upload:
             try:
                 res = self.backend.api.get_library_upload_album(bId)
                 tracks = self.uploadAlbumToTracks(res, bId)
                 logger.debug(
                     "YoutubeMusic found %d songs for uploaded album \"%s\"",
                     len(res["tracks"]), res["title"])
                 return [Ref.track(uri=t.uri, name=t.name) for t in tracks]
             except Exception:
                 logger.exception(
                     "YoutubeMusic failed getting tracks for uploaded album \"%s\"",
                     bId)
         else:
             try:
                 res = self.backend.api.get_album(bId)
                 tracks = self.albumToTracks(res, bId)
                 logger.debug(
                     "YoutubeMusic found %d songs for album \"%s\" in library",
                     len(res["tracks"]), res["title"])
                 return [Ref.track(uri=t.uri, name=t.name) for t in tracks]
             except Exception:
                 logger.exception(
                     "YoutubeMusic failed getting tracks for album \"%s\"",
                     bId)
     elif uri.startswith("youtubemusic:playlist:"):
         bId, upload = parse_uri(uri)
         try:
             res = self.backend.api.get_playlist(
                 bId, limit=self.backend.playlist_item_limit)
             tracks = self.playlistToTracks(res)
             return [Ref.track(uri=t.uri, name=t.name) for t in tracks]
         except Exception:
             logger.exception(
                 "YoutubeMusic failed to get tracks from playlist '%s'",
                 bId)
     return []
Exemple #40
0
 def test_album_constructor(self):
     ref = Ref.album(uri='foo', name='bar')
     self.assertEqual(ref.uri, 'foo')
     self.assertEqual(ref.name, 'bar')
     self.assertEqual(ref.type, Ref.ALBUM)
Exemple #41
0
 def test_album_constructor(self):
     ref = Ref.album(uri='foo', name='bar')
     self.assertEqual(ref.uri, 'foo')
     self.assertEqual(ref.name, 'bar')
     self.assertEqual(ref.type, Ref.ALBUM)
Exemple #42
0
 def test_album_constructor(self):
     ref = Ref.album(uri="foo", name="bar")
     assert ref.uri == "foo"
     assert ref.name == "bar"
     assert ref.type == Ref.ALBUM
 def browse(self, uri):
     if not uri:
         return []
     logger.debug('Bandcamp browse : "%s"', uri)
     if uri == "bandcamp:browse":
         dirs = []
         if self.pages:
             dirs += [
                 Ref.directory(uri="bandcamp:genres",
                               name="Discover by Genre"),
                 Ref.directory(uri="bandcamp:tags", name="Discover by Tag"),
             ]
         if self.backend.config["bandcamp"]["identity"]:
             dirs.append(
                 Ref.directory(uri="bandcamp:collection",
                               name="Collection"))
             dirs.append(
                 Ref.directory(uri="bandcamp:wishlist", name="Wishlist"))
         return dirs
     for colltype in ["collection", "wishlist"]:
         if uri.startswith("bandcamp:" + colltype):
             token = None
             if uri != "bandcamp:" + colltype:
                 token = uri.split(":", 2)[2]
             out = []
             try:
                 data = self.backend.bandcamp.get_collection(token=token,
                                                             ctype=colltype)
                 for i in data["items"]:
                     if "item_art" in i and "art_id" in i["item_art"]:
                         art = (f"a{i['item_art']['art_id']:010d}"
                                if i["item_art"]["art_id"] else None)
                     if i["tralbum_type"] == "a":
                         aId = f"{i['band_id']}-{i['album_id']}"
                         name = f"{i['band_name']} - {i['album_title']} (Album)"
                         if art:
                             self.images[aId] = art
                         if colltype == "collection":
                             out.append(
                                 Ref.album(uri=f"bandcamp:myalbum:{aId}",
                                           name=name))
                             self.scrape_urls[
                                 f"bandcamp:myalbum:{aId}"] = i["item_url"]
                         else:
                             out.append(
                                 Ref.album(uri=f"bandcamp:album:{aId}",
                                           name=name))
                     elif i["tralbum_type"] == "t":
                         aId = 0
                         if i["album_id"] is not None:
                             aId = i["album_id"]
                         tId = f"{i['band_id']}-{aId}-{i['item_id']}"
                         name = f"{i['item_title']} (Track)"
                         if art:
                             self.images[tId] = art
                         if colltype == "collection":
                             out.append(
                                 Ref.album(uri=f"bandcamp:mytrack:{tId}",
                                           name=name))
                             self.scrape_urls[
                                 f"bandcamp:mytrack:{tId}"] = i["item_url"]
                         else:
                             out.append(
                                 Ref.album(uri=f"bandcamp:track:{tId}",
                                           name=name))
                 if data["more_available"]:
                     out.append(
                         Ref.directory(
                             uri="bandcamp:" + colltype + ":" +
                             data["last_token"],
                             name="More...",
                         ))
             except Exception:
                 logger.exception("Failed to get collection")
             return out
     if uri == "bandcamp:genres" or uri == "bandcamp:tags":
         stype = uri.split(":")[1]
         return [
             Ref.directory(
                 uri="bandcamp:" +
                 ("tag:" if stype == "tags" else "genre:") +
                 re.sub(r",", "%2C", re.sub(r"[^a-z0-9,]", "-", d.lower())),
                 name=d,
             ) for d in (self.tags if stype == "tags" else self.genres)
         ]
     if re.match(r"^bandcamp:(genre|tag):", uri):
         component = uri.split(":")
         stype, sid = component[1:3]
         total = 0
         pagenum = int(component[3]) if (len(component) > 3) else 0
         out = []
         for page in range(self.pages):
             try:
                 if stype == "genre":
                     resp = self.backend.bandcamp.discover(genre=sid,
                                                           page=page +
                                                           pagenum)
                 else:
                     resp = self.backend.bandcamp.discover(tag=sid,
                                                           page=page +
                                                           pagenum)
             except Exception:
                 logger.exception('Bandcamp failed to discover genre "%s"',
                                  uri)
             total = resp["total_count"] if ("total_count" in resp) else 0
             for i in resp["items"] if ("items" in resp) else []:
                 art = f"a{i['art_id']:010d}" if ("art_id" in i) else None
                 if i["type"] == "a":
                     aId = f"{i['band_id']}-{i['id']}"
                     name = f"{i['secondary_text']} - {i['primary_text']} (Album)"
                     if art:
                         self.images[aId] = art
                     out.append(
                         Ref.album(uri="bandcamp:album:" + aId, name=name))
                 else:
                     # Only seen discover return album types.
                     logger.info("Found unknown type: '%s'", i["type"])
                     logger.info(i)
         if (pagenum +
                 self.pages) * self.backend.bandcamp.PAGE_ITEMS < total:
             pagenum += self.pages
             out.append(
                 Ref.directory(uri=f"bandcamp:{stype}:{sid}:{pagenum}",
                               name="More..."))
         return out
     elif re.match(r"^bandcamp:(my)?(track|album):", uri):
         tracks = self.lookup(uri)
         return [Ref.track(uri=t.uri, name=t.name) for t in tracks]