Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Web API playlists v3 #235

Merged
merged 15 commits into from
Dec 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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