Compare commits

..

No commits in common. "master" and "1.0.0" have entirely different histories.

7 changed files with 18 additions and 137 deletions

View file

@ -1,35 +0,0 @@
# Maintainer: Matthew Gamble <git@matthewgamble.net>
# Contributor: Frederick Gnodtke <fgnodtke at cronosx dot de>
pkgname=mopidy-subidy
pkgver=1.3.0
pkgrel=2
pkgdesc="Mopidy extension for playing music from Subsonic servers"
arch=("any")
url="https://git.hannover.ccc.de/lubiana/mopidy-subidy/releases"
license=('BSD')
depends=(
"mopidy"
"python"
"python-setuptools"
"python-pykka"
"python-pysonic"
)
source=("https://git.hannover.ccc.de/lubiana/mopidy-subidy/archive/1.0.0.tar.gz")
sha256sums=("ed78ce86da58fb42f6ddf9a8de72169d23521125b269b51054d69375b57c5b73")
build() {
cd "mopidy-subidy"
python setup.py build
}
package() {
cd "mopidy-subidy"
PYTHONHASHSEED=0 python setup.py install --root="${pkgdir}" --optimize=1 --skip-build
install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/mopidy-subidy/LICENSE"
install -Dm644 README.rst "${pkgdir}/usr/share/doc/mopidy-subidy/README.rst"
install -Dm644 CHANGELOG.rst "${pkgdir}/usr/share/doc/mopidy-subidy/CHANGELOG.rst"
}

View file

@ -14,8 +14,6 @@ Mopidy-Subidy
:target: https://codecov.io/gh/Prior99/mopidy-subidy :target: https://codecov.io/gh/Prior99/mopidy-subidy
:alt: Test coverage :alt: Test coverage
**This library is actively looking for maintainers to help out as I do not have the time or need to maintain this anymore. Please contact me if you feel that you could maintain this.**
A Subsonic backend for Mopidy using `py-sonic A Subsonic backend for Mopidy using `py-sonic
<https://github.com/crustymonkey/py-sonic>`_. <https://github.com/crustymonkey/py-sonic>`_.

View file

@ -14,7 +14,6 @@ class SubidyLibraryProvider(backend.LibraryProvider):
dict(id="artists", name="Artists"), dict(id="artists", name="Artists"),
dict(id="albums", name="Albums"), dict(id="albums", name="Albums"),
dict(id="rootdirs", name="Directories"), dict(id="rootdirs", name="Directories"),
dict(id="random", name="Random"),
] ]
# Create a dict with the keys being the `id`s in `vdir_templates` # Create a dict with the keys being the `id`s in `vdir_templates`
# and the values being objects containing the vdir `id`, # and the values being objects containing the vdir `id`,
@ -53,9 +52,6 @@ class SubidyLibraryProvider(backend.LibraryProvider):
def browse_rootdirs(self): def browse_rootdirs(self):
return self.subsonic_api.get_rootdirs_as_refs() return self.subsonic_api.get_rootdirs_as_refs()
def browse_random_songs(self):
return self.subsonic_api.get_random_songs_as_refs()
def browse_diritems(self, directory_id): def browse_diritems(self, directory_id):
return self.subsonic_api.get_diritems_as_refs(directory_id) return self.subsonic_api.get_diritems_as_refs(directory_id)
@ -86,7 +82,7 @@ class SubidyLibraryProvider(backend.LibraryProvider):
def browse(self, browse_uri): def browse(self, browse_uri):
if browse_uri == uri.get_vdir_uri("root"): if browse_uri == uri.get_vdir_uri("root"):
root_vdir_names = ["rootdirs", "artists", "albums", "random"] root_vdir_names = ["rootdirs", "artists", "albums"]
root_vdirs = [ root_vdirs = [
self._vdirs[vdir_name] for vdir_name in root_vdir_names self._vdirs[vdir_name] for vdir_name in root_vdir_names
] ]
@ -100,9 +96,6 @@ class SubidyLibraryProvider(backend.LibraryProvider):
return self.browse_artists() return self.browse_artists()
elif browse_uri == uri.get_vdir_uri("albums"): elif browse_uri == uri.get_vdir_uri("albums"):
return self.browse_albums() return self.browse_albums()
elif browse_uri == uri.get_vdir_uri("random"):
return self.browse_random_songs()
else: else:
uri_type = uri.get_type(browse_uri) uri_type = uri.get_type(browse_uri)
if uri_type == uri.DIRECTORY: if uri_type == uri.DIRECTORY:
@ -145,34 +138,15 @@ class SubidyLibraryProvider(backend.LibraryProvider):
return SearchResult(tracks=[track]) return SearchResult(tracks=[track])
def search_by_artist_and_album(self, artist_name, album_name): def search_by_artist_and_album(self, artist_name, album_name):
artists = self.subsonic_api.find_raw(artist_name).get("artist") artists = self.subsonic_api.get_raw_artists()
if artists is None: artist = next(
return None item for item in artists if artist_name in item.get("name")
tracks = [] )
for artist in artists: albums = self.subsonic_api.get_raw_albums(artist.get("id"))
for album in self.subsonic_api.get_raw_albums(artist.get("id")): album = next(item for item in albums if album_name in item.get("title"))
if album_name in album.get("name"): return SearchResult(
tracks.extend( tracks=self.subsonic_api.get_songs_as_tracks(album.get("id"))
self.subsonic_api.get_songs_as_tracks(album.get("id")) )
)
return SearchResult(tracks=tracks)
def search_by_artist(self, artist_name, exact):
result = self.subsonic_api.find_raw(artist_name)
if result is None:
return None
tracks = []
for artist in result.get("artist"):
if exact:
if not artist.get("name") == artist_name:
continue
tracks.extend(
self.subsonic_api.get_artist_as_songs_as_tracks_iter(
artist.get("id")
)
)
return SearchResult(uri=uri.get_search_uri(artist_name), tracks=tracks)
def get_distinct(self, field, query): def get_distinct(self, field, query):
search_result = self.search(query) search_result = self.search(query)
@ -199,12 +173,9 @@ class SubidyLibraryProvider(backend.LibraryProvider):
query.get("artist")[0], query.get("album")[0] query.get("artist")[0], query.get("album")[0]
) )
if "artist" in query: if "artist" in query:
return self.search_by_artist(query.get("artist")[0], exact) return self.subsonic_api.find_as_search_result(
if "comment" in query: query.get("artist")[0]
if query.get("comment")[0] == "random": )
return SearchResult(
tracks=self.subsonic_api.get_random_songs_as_tracks()
)
if "any" in query: if "any" in query:
return self.subsonic_api.find_as_search_result(query.get("any")[0]) return self.subsonic_api.find_as_search_result(query.get("any")[0])
return SearchResult(artists=self.subsonic_api.get_artists_as_artists()) return SearchResult(artists=self.subsonic_api.get_artists_as_artists())

View file

@ -16,6 +16,3 @@ class SubidyPlaybackProvider(backend.PlaybackProvider):
censored_url = self.subsonic_api.get_censored_song_stream_uri(song_id) censored_url = self.subsonic_api.get_censored_song_stream_uri(song_id)
logger.debug("Loading song from subsonic with url: '%s'" % censored_url) logger.debug("Loading song from subsonic with url: '%s'" % censored_url)
return self.subsonic_api.get_song_stream_uri(song_id) return self.subsonic_api.get_song_stream_uri(song_id)
def should_download(self, uri):
return True

View file

@ -101,7 +101,7 @@ class SubsonicApi:
exclude_songs=False, exclude_songs=False,
): ):
try: try:
response = self.connection.search3( response = self.connection.search2(
query.encode("utf-8"), query.encode("utf-8"),
MAX_SEARCH_RESULTS if not exclude_artists else 0, MAX_SEARCH_RESULTS if not exclude_artists else 0,
0, 0,
@ -119,7 +119,7 @@ class SubsonicApi:
% response.get("status") % response.get("status")
) )
return None return None
return response.get("searchResult3") return response.get("searchResult2")
def find_as_search_result( def find_as_search_result(
self, self,
@ -410,30 +410,9 @@ class SubsonicApi:
return songs return songs
return [] return []
def get_raw_random_song(self, size=MAX_LIST_RESULTS): def get_raw_album_list(self, ltype, size=MAX_LIST_RESULTS):
try: try:
response = self.connection.getRandomSongs(size) response = self.connection.getAlbumList2(ltype=ltype, size=size)
except Exception:
logger.warning(
"Connecting to subsonic failed when loading ramdom song list."
)
return []
if response.get("status") != RESPONSE_OK:
logger.warning(
"Got non-okay status code from subsonic: %s"
% response.get("status")
)
return []
songs = response.get("randomSongs").get("song")
if songs is not None:
return songs
return []
def get_more_albums(self, ltype, size=MAX_LIST_RESULTS, offset=0):
try:
response = self.connection.getAlbumList2(
ltype=ltype, size=size, offset=offset
)
except Exception: except Exception:
logger.warning( logger.warning(
"Connecting to subsonic failed when loading album list." "Connecting to subsonic failed when loading album list."
@ -450,24 +429,6 @@ class SubsonicApi:
return albums return albums
return [] return []
def get_raw_album_list(self, ltype, size=MAX_LIST_RESULTS):
"""
Subsonic servers don't offer any way to retrieve the total number
of albums to get, and the spec states that the max number returned
for `getAlbumList2` is 500. To get all the albums, we make a
`getAlbumList2` request each time the response contains 500 albums. If
it does not, we assume we have all the albums and return them.
"""
offset = 0
total = []
albums = self.get_more_albums(ltype, size, offset)
total = albums
while len(albums) == size:
offset = offset + size
albums = self.get_more_albums(ltype, size, offset)
total = total + albums
return total
def get_albums_as_refs(self, artist_id=None): def get_albums_as_refs(self, artist_id=None):
albums = ( albums = (
self.get_raw_album_list("alphabeticalByName") self.get_raw_album_list("alphabeticalByName")
@ -514,16 +475,6 @@ class SubsonicApi:
for diritem in self.get_raw_dir(directory_id) for diritem in self.get_raw_dir(directory_id)
] ]
def get_random_songs_as_refs(self):
return [
self.raw_song_to_ref(song) for song in self.get_raw_random_song(75)
]
def get_random_songs_as_tracks(self):
return [
self.raw_song_to_track(song) for song in self.get_raw_random_song()
]
def get_artists_as_artists(self): def get_artists_as_artists(self):
return [ return [
self.raw_artist_to_artist(artist) self.raw_artist_to_artist(artist)

View file

@ -8,7 +8,6 @@ DIRECTORY = "directory"
VDIR = "vdir" VDIR = "vdir"
PREFIX = "subidy" PREFIX = "subidy"
SEARCH = "search" SEARCH = "search"
RANDOM = "random"
regex = re.compile(r"(\w+?):(\w+?)(?::|$)(.+?)?$") regex = re.compile(r"(\w+?):(\w+?)(?::|$)(.+?)?$")

View file

@ -1,6 +1,6 @@
[metadata] [metadata]
name = Mopidy-Subidy name = Mopidy-Subidy
version = 1.1.0 version = 1.0.0
url = https://github.com/Prior99/mopidy-subidy url = https://github.com/Prior99/mopidy-subidy
author = prior99 author = prior99
author_email = fgnodtke@cronosx.de author_email = fgnodtke@cronosx.de