Skip to content

Commit

Permalink
Merge pull request mopidy#235 from kingosticks/fix/web-api-playlists-v3
Browse files Browse the repository at this point in the history
Web API playlists v3
  • Loading branch information
jodal committed Dec 12, 2019
2 parents 36bf330 + 0a78635 commit f52babd
Show file tree
Hide file tree
Showing 25 changed files with 1,321 additions and 527 deletions.
10 changes: 9 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,16 @@ Changelog
*********


v4.0.0a2 (UNRELEASED)
=====================

Alpha release.

- Use the Spotify Web API for playlists. (#182, #122, PR: #235)


v4.0.0a1 (2019-11-18)
======================
=====================

Alpha release.

Expand Down
9 changes: 3 additions & 6 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,6 @@ way for us to provide some Spotify features.
Limitations and/or bugs in ``libspotify`` currently result in missing/broken
Mopidy-Spotify support for the following:

- Playlists (`#182 <https://github.com/mopidy/mopidy-spotify/issues/182>`_,
`#122 <https://github.com/mopidy/mopidy-spotify/issues/122>`_) - available
via web API using
`#228 <https://github.com/mopidy/mopidy-spotify/pull/228>`_

- My Music (`#16 <https://github.com/mopidy/mopidy-spotify/issues/16>`_,
`#108 <https://github.com/mopidy/mopidy-spotify/issues/108>`_) - available via
web API
Expand All @@ -61,7 +56,9 @@ Working support for the following features is currently available:

- Search

- Lookup by URI (except playlists)
- Playlists

- Lookup by URI


Dependencies
Expand Down
1 change: 0 additions & 1 deletion mopidy_spotify/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import pathlib

import pkg_resources

from mopidy import config, ext

__version__ = pkg_resources.get_distribution("Mopidy-Spotify").version
Expand Down
29 changes: 7 additions & 22 deletions mopidy_spotify/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import threading

import pykka
import spotify

from mopidy import backend, httpclient

import spotify
from mopidy_spotify import Extension, library, playback, playlists, web

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -57,13 +57,15 @@ def on_start(self):
self._config["spotify"]["password"],
)

self._web_client = web.OAuthClient(
base_url="https://api.spotify.com/v1",
refresh_url="https://auth.mopidy.com/spotify/token",
self._web_client = web.SpotifyOAuthClient(
client_id=self._config["spotify"]["client_id"],
client_secret=self._config["spotify"]["client_secret"],
proxy_config=self._config["proxy"],
)
self._web_client.login()

if self.playlists is not None:
self.playlists.refresh()

def on_stop(self):
logger.debug("Logging out of Spotify")
Expand Down Expand Up @@ -126,23 +128,6 @@ def on_logged_in(self):
logger.info("Spotify private session activated")
self._session.social.private_session = True

self._session.playlist_container.on(
spotify.PlaylistContainerEvent.CONTAINER_LOADED,
playlists.on_container_loaded,
)
self._session.playlist_container.on(
spotify.PlaylistContainerEvent.PLAYLIST_ADDED,
playlists.on_playlist_added,
)
self._session.playlist_container.on(
spotify.PlaylistContainerEvent.PLAYLIST_REMOVED,
playlists.on_playlist_removed,
)
self._session.playlist_container.on(
spotify.PlaylistContainerEvent.PLAYLIST_MOVED,
playlists.on_playlist_moved,
)

def on_play_token_lost(self):
if self._session.player.state == spotify.PlayerState.PLAYING:
self.playback.pause()
Expand Down
4 changes: 2 additions & 2 deletions mopidy_spotify/browse.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import logging

import spotify

from mopidy import models

import spotify
from mopidy_spotify import countries, translator

logger = logging.getLogger(__name__)
Expand Down
1 change: 0 additions & 1 deletion mopidy_spotify/distinct.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import logging

import spotify

from mopidy_spotify import search

logger = logging.getLogger(__name__)
Expand Down
5 changes: 4 additions & 1 deletion mopidy_spotify/library.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging

from mopidy import backend

from mopidy_spotify import browse, distinct, images, lookup, search

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -29,7 +30,9 @@ def get_images(self, uris):
return images.get_images(self._backend._web_client, uris)

def lookup(self, uri):
return lookup.lookup(self._config, self._backend._session, uri)
return lookup.lookup(
self._config, self._backend._session, self._backend._web_client, uri
)

def search(self, query=None, uris=None, exact=False):
return search.search(
Expand Down
38 changes: 18 additions & 20 deletions mopidy_spotify/lookup.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import logging

import spotify

from mopidy_spotify import translator, utils
from mopidy_spotify import playlists, translator, utils, web

logger = logging.getLogger(__name__)

Expand All @@ -11,32 +10,32 @@
]


def lookup(config, session, uri):
def lookup(config, session, web_client, uri):
try:
sp_link = session.get_link(uri)
web_link = web.WebLink.from_uri(uri)
if web_link.type != web.LinkType.PLAYLIST:
sp_link = session.get_link(uri)
except ValueError as exc:
logger.info(f'Failed to lookup "{uri}": {exc}')
logger.info(f"Failed to lookup {uri!r}: {exc}")
return []

try:
if sp_link.type is spotify.LinkType.TRACK:
if web_link.type == web.LinkType.PLAYLIST:
return _lookup_playlist(config, session, web_client, uri)
elif sp_link.type is spotify.LinkType.TRACK:
return list(_lookup_track(config, sp_link))
elif sp_link.type is spotify.LinkType.ALBUM:
return list(_lookup_album(config, sp_link))
elif sp_link.type is spotify.LinkType.ARTIST:
with utils.time_logger("Artist lookup"):
return list(_lookup_artist(config, sp_link))
elif sp_link.type is spotify.LinkType.PLAYLIST:
return list(_lookup_playlist(config, sp_link))
elif sp_link.type is spotify.LinkType.STARRED:
return list(reversed(list(_lookup_playlist(config, sp_link))))
else:
logger.info(
f'Failed to lookup "{uri}": Cannot handle {repr(sp_link.type)}'
f"Failed to lookup {uri!r}: Cannot handle {sp_link.type!r}"
)
return []
except spotify.Error as exc:
logger.info(f'Failed to lookup "{uri}": {exc}')
logger.info(f"Failed to lookup {uri!r}: {exc}")
return []


Expand Down Expand Up @@ -86,11 +85,10 @@ def _lookup_artist(config, sp_link):
yield track


def _lookup_playlist(config, sp_link):
sp_playlist = sp_link.as_playlist()
sp_playlist.load(config["timeout"])
for sp_track in sp_playlist.tracks:
sp_track.load(config["timeout"])
track = translator.to_track(sp_track, bitrate=config["bitrate"])
if track is not None:
yield track
def _lookup_playlist(config, session, web_client, uri):
playlist = playlists.playlist_lookup(
session, web_client, uri, config["bitrate"]
)
if playlist is None:
raise spotify.Error("Playlist Web API lookup failed")
return playlist.tracks
4 changes: 2 additions & 2 deletions mopidy_spotify/playback.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
import logging
import threading

import spotify

from mopidy import audio, backend

import spotify

logger = logging.getLogger(__name__)


Expand Down
Loading

0 comments on commit f52babd

Please sign in to comment.