2018-10-03 21:51:48 +02:00
|
|
|
from __future__ import unicode_literals
|
|
|
|
|
|
|
|
import collections
|
|
|
|
import logging
|
|
|
|
import re
|
2018-10-04 20:57:27 +02:00
|
|
|
import time
|
|
|
|
import urllib
|
2018-10-03 21:51:48 +02:00
|
|
|
|
|
|
|
from mopidy import backend, models
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
2018-10-04 20:57:27 +02:00
|
|
|
def generate_uri(path):
|
|
|
|
return "funkwhale:directory:%s" % path
|
|
|
|
|
|
|
|
|
|
|
|
def new_folder(name, path):
|
|
|
|
return models.Ref.directory(uri=generate_uri(path), name=name)
|
|
|
|
|
2018-10-03 21:51:48 +02:00
|
|
|
|
|
|
|
def simplify_search_query(query):
|
|
|
|
|
|
|
|
if isinstance(query, dict):
|
|
|
|
r = []
|
|
|
|
for v in query.values():
|
|
|
|
if isinstance(v, list):
|
|
|
|
r.extend(v)
|
|
|
|
else:
|
|
|
|
r.append(v)
|
2018-10-04 20:57:27 +02:00
|
|
|
return " ".join(r)
|
2018-10-03 21:51:48 +02:00
|
|
|
if isinstance(query, list):
|
2018-10-04 20:57:27 +02:00
|
|
|
return " ".join(query)
|
2018-10-03 21:51:48 +02:00
|
|
|
else:
|
|
|
|
return query
|
|
|
|
|
|
|
|
|
2018-10-04 20:57:27 +02:00
|
|
|
class Cache(collections.OrderedDict):
|
|
|
|
def __init__(self, max_age=0):
|
|
|
|
self.max_age = max_age
|
|
|
|
super(Cache, self).__init__()
|
|
|
|
|
|
|
|
def set(self, key, value):
|
2018-10-05 00:06:09 +02:00
|
|
|
if self.max_age is None:
|
|
|
|
return
|
2018-10-04 20:57:27 +02:00
|
|
|
now = time.time()
|
|
|
|
self[key] = (now, value)
|
|
|
|
|
|
|
|
def get(self, key):
|
2018-10-05 00:06:09 +02:00
|
|
|
if self.max_age is None:
|
|
|
|
return
|
2018-10-04 20:57:27 +02:00
|
|
|
value = super(Cache, self).get(key)
|
|
|
|
if value is None:
|
|
|
|
return
|
|
|
|
now = time.time()
|
|
|
|
t, v = value
|
|
|
|
if self.max_age and t + self.max_age < now:
|
|
|
|
# entry is too old, we delete it
|
|
|
|
del self[key]
|
|
|
|
return None
|
|
|
|
return v
|
|
|
|
|
|
|
|
|
2018-10-03 21:51:48 +02:00
|
|
|
class FunkwhaleLibraryProvider(backend.LibraryProvider):
|
2018-10-04 20:57:27 +02:00
|
|
|
root_directory = models.Ref.directory(uri="funkwhale:directory", name="Funkwhale")
|
2018-10-03 21:51:48 +02:00
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
super(FunkwhaleLibraryProvider, self).__init__(*args, **kwargs)
|
2018-10-04 20:57:27 +02:00
|
|
|
self.vfs = {"funkwhale:directory": collections.OrderedDict()}
|
|
|
|
self.add_to_vfs(new_folder("Favorites", "favorites"))
|
2018-10-05 00:06:09 +02:00
|
|
|
self.add_to_vfs(new_folder("Artists", "artists"))
|
2020-09-25 04:25:21 +02:00
|
|
|
self.add_to_vfs(new_folder("Albums", "albums"))
|
2020-07-01 20:55:30 +02:00
|
|
|
self.add_to_vfs(new_folder("Libraries", "libraries"))
|
2018-10-03 21:51:48 +02:00
|
|
|
# self.add_to_vfs(new_folder('Following', ['following']))
|
|
|
|
# self.add_to_vfs(new_folder('Sets', ['sets']))
|
|
|
|
# self.add_to_vfs(new_folder('Stream', ['stream']))
|
2018-10-05 00:06:09 +02:00
|
|
|
self.cache = Cache(max_age=self.backend.config["funkwhale"]["cache_duration"])
|
2018-10-03 21:51:48 +02:00
|
|
|
|
|
|
|
def add_to_vfs(self, _model):
|
2018-10-04 20:57:27 +02:00
|
|
|
self.vfs["funkwhale:directory"][_model.uri] = _model
|
2018-10-03 21:51:48 +02:00
|
|
|
|
|
|
|
def browse(self, uri):
|
2018-10-05 00:06:09 +02:00
|
|
|
cache_key = uri
|
|
|
|
from_cache = self.cache.get(cache_key)
|
|
|
|
if from_cache:
|
|
|
|
try:
|
|
|
|
len(from_cache)
|
|
|
|
return from_cache
|
|
|
|
except TypeError:
|
|
|
|
return [from_cache]
|
|
|
|
|
2018-10-03 21:51:48 +02:00
|
|
|
if not self.vfs.get(uri):
|
2018-10-04 20:57:27 +02:00
|
|
|
if uri.startswith("funkwhale:directory:"):
|
|
|
|
uri = uri.replace("funkwhale:directory:", "", 1)
|
|
|
|
parts = uri.split(":")
|
|
|
|
remaining = parts[1:] if len(parts) > 1 else []
|
|
|
|
handler = getattr(self, "browse_%s" % parts[0])
|
2018-10-05 00:06:09 +02:00
|
|
|
result, cache = handler(remaining)
|
|
|
|
if cache:
|
|
|
|
self.cache.set(cache_key, result)
|
|
|
|
return result
|
2018-10-03 21:51:48 +02:00
|
|
|
|
|
|
|
# root directory
|
2020-05-11 16:13:45 +02:00
|
|
|
return list(self.vfs.get(uri, {}).values())
|
2018-10-03 21:51:48 +02:00
|
|
|
|
2018-10-04 20:57:27 +02:00
|
|
|
def browse_favorites(self, remaining):
|
|
|
|
if remaining == []:
|
2018-10-05 00:06:09 +02:00
|
|
|
return (
|
|
|
|
[
|
|
|
|
new_folder("Recent", "favorites:recent"),
|
|
|
|
# new_folder("By artist", "favorites:by-artist"),
|
|
|
|
],
|
|
|
|
False,
|
|
|
|
)
|
2018-10-04 20:57:27 +02:00
|
|
|
|
|
|
|
if remaining == ["recent"]:
|
|
|
|
payload = self.backend.client.list_tracks(
|
2018-10-05 00:06:09 +02:00
|
|
|
{"favorites": "true", "ordering": "-creation_date", "page_size": 50}
|
|
|
|
)
|
|
|
|
tracks = [
|
|
|
|
convert_to_track(row, ref=True, cache=self.cache)
|
|
|
|
for row in self.backend.client.load_all(payload, max=10)
|
2018-10-04 20:57:27 +02:00
|
|
|
]
|
2018-10-05 00:06:09 +02:00
|
|
|
return tracks, True
|
|
|
|
return [], False
|
|
|
|
|
2020-09-25 04:25:21 +02:00
|
|
|
def browse_albums(self, remaining, uri_prefix=""):
|
2020-07-01 20:55:30 +02:00
|
|
|
logger.debug("Handling albums route: %s", remaining)
|
2020-09-25 04:25:21 +02:00
|
|
|
if remaining == []:
|
|
|
|
return (
|
|
|
|
[
|
|
|
|
new_folder("Recent", "albums:recent"),
|
|
|
|
new_folder("By name", "albums:by-name"),
|
|
|
|
new_folder("Own Content", "albums:scope-me"),
|
|
|
|
],
|
|
|
|
False,
|
|
|
|
)
|
|
|
|
|
|
|
|
if remaining == ["recent"]:
|
|
|
|
# list recent albums
|
|
|
|
payload = self.backend.client.list_albums(
|
|
|
|
{"ordering": "-creation_date", "page_size": 50, "playable": "true"}
|
|
|
|
)
|
|
|
|
|
|
|
|
uri_prefix = "funkwhale:directory:albums:recent"
|
|
|
|
albums = [
|
|
|
|
convert_to_album(row, uri_prefix=uri_prefix, ref=True)
|
|
|
|
for row in self.backend.client.load_all(payload, max=1)
|
|
|
|
]
|
|
|
|
|
|
|
|
return albums, True
|
|
|
|
|
|
|
|
if remaining == ["by-name"]:
|
|
|
|
# list all albums sorted by name
|
|
|
|
payload = self.backend.client.list_albums(
|
|
|
|
{"ordering": "title", "page_size": 50, "playable": "true"}
|
|
|
|
)
|
|
|
|
|
|
|
|
uri_prefix = "funkwhale:directory:albums:by-name"
|
|
|
|
albums = [
|
|
|
|
convert_to_album(row, uri_prefix=uri_prefix, ref=True)
|
|
|
|
for row in self.backend.client.load_all(payload)
|
|
|
|
]
|
|
|
|
|
|
|
|
return albums, True
|
|
|
|
|
|
|
|
if remaining == ["scope-me"]:
|
|
|
|
# list all albums self uploaded
|
|
|
|
payload = self.backend.client.list_albums(
|
|
|
|
{"ordering": "title", "page_size": 50, "scope": "me"}
|
|
|
|
)
|
|
|
|
|
|
|
|
uri_prefix = "funkwhale:directory:albums:scope-me"
|
|
|
|
albums = [
|
|
|
|
convert_to_album(row, uri_prefix=uri_prefix, ref=True)
|
|
|
|
for row in self.backend.client.load_all(payload)
|
|
|
|
]
|
|
|
|
|
|
|
|
return albums, True
|
|
|
|
|
2018-10-05 00:06:09 +02:00
|
|
|
if len(remaining) == 2:
|
|
|
|
album = remaining[1]
|
|
|
|
payload = self.backend.client.list_tracks(
|
|
|
|
{
|
|
|
|
"ordering": "position",
|
|
|
|
"page_size": 50,
|
|
|
|
"playable": "true",
|
|
|
|
"album": album,
|
|
|
|
}
|
|
|
|
)
|
|
|
|
tracks = [
|
|
|
|
convert_to_track(row, ref=True, cache=self.cache)
|
|
|
|
for row in self.backend.client.load_all(payload)
|
|
|
|
]
|
2020-09-25 04:25:21 +02:00
|
|
|
return tracks, True
|
2018-10-05 00:06:09 +02:00
|
|
|
else:
|
|
|
|
artist, album = remaining[0], None
|
|
|
|
payload = self.backend.client.list_albums(
|
|
|
|
{
|
|
|
|
"ordering": "title",
|
|
|
|
"page_size": 50,
|
|
|
|
"playable": "true",
|
|
|
|
"artist": artist,
|
|
|
|
}
|
|
|
|
)
|
|
|
|
albums = [
|
|
|
|
convert_to_album(row, uri_prefix=uri_prefix, ref=True)
|
|
|
|
for row in self.backend.client.load_all(payload)
|
|
|
|
]
|
2020-09-25 04:25:21 +02:00
|
|
|
return albums, True
|
2018-10-05 00:06:09 +02:00
|
|
|
|
|
|
|
def browse_artists(self, remaining):
|
|
|
|
logger.debug("Handling artist route: %s", remaining)
|
|
|
|
if remaining == []:
|
|
|
|
return (
|
|
|
|
[
|
|
|
|
new_folder("Recent", "artists:recent"),
|
|
|
|
new_folder("By name", "artists:by-name"),
|
2020-06-19 13:27:40 +02:00
|
|
|
new_folder("Own Content", "artists:scope-me"),
|
2018-10-05 00:06:09 +02:00
|
|
|
],
|
|
|
|
False,
|
|
|
|
)
|
|
|
|
|
|
|
|
root = remaining[0]
|
|
|
|
end = remaining[1:]
|
|
|
|
albums_uri_prefix = "funkwhale:directory:artists:" + ":".join(
|
|
|
|
[str(i) for i in remaining]
|
|
|
|
)
|
|
|
|
if root == "recent":
|
|
|
|
if end:
|
|
|
|
# list albums
|
2020-09-25 04:25:21 +02:00
|
|
|
return self.browse_albums(uri_prefix=albums_uri_prefix, remaining=end)
|
|
|
|
|
2018-10-05 00:06:09 +02:00
|
|
|
# list recent artists
|
|
|
|
payload = self.backend.client.list_artists(
|
|
|
|
{"ordering": "-creation_date", "page_size": 50, "playable": "true"}
|
|
|
|
)
|
|
|
|
uri_prefix = "funkwhale:directory:artists:recent"
|
|
|
|
|
|
|
|
artists = [
|
|
|
|
convert_to_artist(row, uri_prefix=uri_prefix, ref=True)
|
|
|
|
for row in self.backend.client.load_all(payload, max=1)
|
|
|
|
]
|
|
|
|
return artists, True
|
|
|
|
|
|
|
|
if root == "by-name":
|
|
|
|
if end:
|
|
|
|
# list albums
|
2020-09-25 04:25:21 +02:00
|
|
|
return self.browse_albums(uri_prefix=albums_uri_prefix, remaining=end)
|
|
|
|
|
2018-10-05 00:06:09 +02:00
|
|
|
# list recent artists
|
|
|
|
payload = self.backend.client.list_artists(
|
|
|
|
{"ordering": "name", "page_size": 50, "playable": "true"}
|
|
|
|
)
|
|
|
|
uri_prefix = "funkwhale:directory:artists:by-name"
|
|
|
|
artists = [
|
|
|
|
convert_to_artist(row, uri_prefix=uri_prefix, ref=True)
|
|
|
|
for row in self.backend.client.load_all(payload)
|
|
|
|
]
|
|
|
|
return artists, True
|
|
|
|
|
2020-06-19 13:27:40 +02:00
|
|
|
if root == "scope-me":
|
|
|
|
if end:
|
|
|
|
# list albums
|
2020-09-25 04:25:21 +02:00
|
|
|
return self.browse_albums(uri_prefix=albums_uri_prefix, remaining=end)
|
|
|
|
|
2020-06-19 13:27:40 +02:00
|
|
|
payload = self.backend.client.list_artists(
|
|
|
|
{"ordering": "name", "page_size": 50, "scope": "me"}
|
|
|
|
)
|
|
|
|
uri_prefix = "funkwhale:directory:artists:scope-me"
|
|
|
|
artists = [
|
|
|
|
convert_to_artist(row, uri_prefix=uri_prefix, ref=True)
|
|
|
|
for row in self.backend.client.load_all(payload)
|
|
|
|
]
|
|
|
|
return artists, True
|
|
|
|
|
2020-07-01 20:55:30 +02:00
|
|
|
if root == "by-library":
|
|
|
|
logger.debug("Handling artists by lib route: %s", end)
|
|
|
|
if len(end) == 1:
|
|
|
|
payload = self.backend.client.list_artists(
|
|
|
|
{"ordering": "name", "page_size": 50, "library": end}
|
|
|
|
)
|
|
|
|
uri_prefix = "funkwhale:directory:artists:by-name"
|
|
|
|
artists = [
|
|
|
|
convert_to_artist(row, uri_prefix=uri_prefix, ref=True)
|
|
|
|
for row in self.backend.client.load_all(payload)
|
|
|
|
]
|
|
|
|
return artists, True
|
|
|
|
|
2018-10-05 00:06:09 +02:00
|
|
|
return [], False
|
2018-10-04 20:57:27 +02:00
|
|
|
|
2020-07-01 20:55:30 +02:00
|
|
|
def browse_libraries(self, remaining):
|
|
|
|
logger.debug("Handling libraries route: %s", remaining)
|
|
|
|
|
|
|
|
payload = self.backend.client.list_libraries(
|
2022-02-06 11:59:20 +01:00
|
|
|
{"ordering": "name", "page_size": 50}
|
2020-07-01 20:55:30 +02:00
|
|
|
)
|
|
|
|
uri_prefix = "funkwhale:directory:artists:by-library"
|
|
|
|
libraries = [
|
|
|
|
convert_to_ref(row, uri_prefix=uri_prefix)
|
|
|
|
for row in self.backend.client.load_all(payload)
|
|
|
|
]
|
|
|
|
return libraries, True
|
|
|
|
|
2020-09-25 05:26:05 +02:00
|
|
|
def get_images(self, uris):
|
|
|
|
logger.debug("Handling get images: %s", uris)
|
|
|
|
result = {}
|
|
|
|
|
|
|
|
for uri in uris:
|
|
|
|
track_id = uri.split(":")[-1]
|
2020-09-25 05:40:56 +02:00
|
|
|
cache_key = "funkwhale:images:%s" % track_id
|
|
|
|
from_cache = self.cache.get(cache_key)
|
|
|
|
|
|
|
|
if from_cache:
|
|
|
|
result[uri] = from_cache
|
|
|
|
continue
|
2020-09-25 05:26:05 +02:00
|
|
|
|
2020-09-25 05:40:56 +02:00
|
|
|
payload = self.backend.client.get_track(track_id)
|
2020-09-25 05:26:05 +02:00
|
|
|
if not payload["album"]["cover"]:
|
|
|
|
continue
|
|
|
|
|
|
|
|
result[uri] = []
|
|
|
|
|
|
|
|
for type, cover_url in payload["album"]["cover"]["urls"].items():
|
|
|
|
if not cover_url:
|
|
|
|
continue
|
|
|
|
|
|
|
|
if type == "large_square_crop":
|
|
|
|
image = models.Image(uri=cover_url, width=600, height=600)
|
|
|
|
elif type == "medium_square_crop":
|
|
|
|
image = models.Image(uri=cover_url, width=200, height=200)
|
|
|
|
else:
|
|
|
|
image = models.Image(uri=cover_url)
|
|
|
|
|
|
|
|
result[uri].append(image)
|
|
|
|
|
2020-09-25 05:40:56 +02:00
|
|
|
self.cache.set(cache_key, result[uri])
|
|
|
|
|
2020-09-25 05:26:05 +02:00
|
|
|
return result
|
2020-07-01 20:55:30 +02:00
|
|
|
|
2018-10-03 21:51:48 +02:00
|
|
|
def search(self, query=None, uris=None, exact=False):
|
|
|
|
# TODO Support exact search
|
|
|
|
if not query:
|
|
|
|
return
|
|
|
|
|
|
|
|
else:
|
|
|
|
search_query = simplify_search_query(query)
|
2018-10-04 20:57:27 +02:00
|
|
|
logger.info("Searching Funkwhale for: %s", search_query)
|
|
|
|
raw_results = self.backend.client.search(search_query)
|
Add basic filtering on search results
Any mpd query was treated the same, whether it was an album, artist,
track, etc. query. With this commit, a basic filtering occurs, meaning
that 'album' queries will only return albums, 'track' queries will only
return tracks, 'artist' queries will only return artists, and 'any'
queries will return all of the above.
Limitation: any other query now won't return anything. This seems
logical, since Funkwhale search only distinguishes between artists, albums and
tracks.
2021-12-21 15:39:30 +01:00
|
|
|
|
|
|
|
artists = []
|
|
|
|
albums = []
|
|
|
|
tracks = []
|
|
|
|
if "artist" in query or "any" in query:
|
|
|
|
artists = [convert_to_artist(row) for row in raw_results["artists"]]
|
|
|
|
if "album" in query or "any" in query:
|
|
|
|
albums = [convert_to_album(row) for row in raw_results["albums"]]
|
|
|
|
if "track_no" in query or "any" in query:
|
|
|
|
tracks = [convert_to_track(row) for row in raw_results["tracks"]]
|
2018-10-03 21:51:48 +02:00
|
|
|
|
|
|
|
return models.SearchResult(
|
2018-10-04 20:57:27 +02:00
|
|
|
uri="funkwhale:search", tracks=tracks, albums=albums, artists=artists
|
2018-10-03 21:51:48 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
def lookup(self, uri):
|
2018-10-04 20:57:27 +02:00
|
|
|
from_cache = self.cache.get(uri)
|
|
|
|
if from_cache:
|
|
|
|
try:
|
|
|
|
len(from_cache)
|
|
|
|
return from_cache
|
|
|
|
except TypeError:
|
|
|
|
return [from_cache]
|
|
|
|
|
|
|
|
if "fw:" in uri:
|
|
|
|
uri = uri.replace("fw:", "")
|
2018-10-03 21:51:48 +02:00
|
|
|
return self.backend.remote.resolve_url(uri)
|
|
|
|
|
2018-10-04 20:57:27 +02:00
|
|
|
client = self.backend.client
|
2018-10-03 21:51:48 +02:00
|
|
|
config = {
|
2018-10-04 20:57:27 +02:00
|
|
|
"track": lambda id: [client.get_track(id)],
|
2022-02-06 11:59:20 +01:00
|
|
|
"album": lambda id: client.list_tracks(
|
|
|
|
{"album": id, "ordering": "position"}
|
|
|
|
)["results"],
|
2018-10-04 20:57:27 +02:00
|
|
|
"artist": lambda id: client.list_tracks({"artist": id})["results"],
|
2018-10-03 21:51:48 +02:00
|
|
|
}
|
2018-10-04 20:57:27 +02:00
|
|
|
|
2021-08-12 10:00:34 +02:00
|
|
|
try:
|
|
|
|
type, id = parse_uri(uri)
|
|
|
|
except (IndexError, ValueError):
|
|
|
|
logger.info(f"Lookup failed: invalid uri '{uri}'")
|
|
|
|
return []
|
|
|
|
else:
|
|
|
|
payload = config[type](id)
|
|
|
|
return [convert_to_track(row, cache=self.cache) for row in payload]
|
2018-10-03 21:51:48 +02:00
|
|
|
|
|
|
|
|
|
|
|
def parse_uri(uri):
|
2018-10-04 20:57:27 +02:00
|
|
|
uri = uri.replace("funkwhale:", "", 1)
|
|
|
|
parts = uri.split(":")
|
|
|
|
type = parts[0].rstrip("s")
|
2018-10-03 21:51:48 +02:00
|
|
|
id = int(parts[1])
|
|
|
|
return type, id
|
|
|
|
|
|
|
|
|
2018-10-04 20:57:27 +02:00
|
|
|
def cast_to_ref(f):
|
2018-10-05 00:06:09 +02:00
|
|
|
def inner(payload, *args, **kwargs):
|
|
|
|
ref = kwargs.pop("ref", False)
|
|
|
|
cache = kwargs.pop("cache", None)
|
|
|
|
result = f(payload, *args, **kwargs)
|
2018-10-04 20:57:27 +02:00
|
|
|
if cache is not None:
|
|
|
|
cache.set(result.uri, result)
|
|
|
|
if ref:
|
|
|
|
return to_ref(result)
|
|
|
|
return result
|
|
|
|
|
|
|
|
return inner
|
|
|
|
|
|
|
|
|
|
|
|
@cast_to_ref
|
2018-10-05 00:06:09 +02:00
|
|
|
def convert_to_artist(payload, uri_prefix="funkwhale:artists"):
|
2018-10-03 21:51:48 +02:00
|
|
|
return models.Artist(
|
2018-10-05 00:06:09 +02:00
|
|
|
uri=uri_prefix + ":%s" % payload["id"],
|
2018-10-04 20:57:27 +02:00
|
|
|
name=payload["name"],
|
|
|
|
sortname=payload["name"],
|
|
|
|
musicbrainz_id=payload["mbid"],
|
2018-10-03 21:51:48 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
|
2018-10-04 20:57:27 +02:00
|
|
|
@cast_to_ref
|
2018-10-05 00:06:09 +02:00
|
|
|
def convert_to_album(payload, uri_prefix="funkwhale:albums"):
|
2018-10-04 20:57:27 +02:00
|
|
|
artist = convert_to_artist(payload["artist"])
|
2018-10-03 21:51:48 +02:00
|
|
|
return models.Album(
|
2018-10-05 00:06:09 +02:00
|
|
|
uri=uri_prefix + ":%s" % payload["id"],
|
2018-10-04 20:57:27 +02:00
|
|
|
name=payload["title"],
|
|
|
|
musicbrainz_id=payload["mbid"],
|
2018-10-03 21:51:48 +02:00
|
|
|
artists=[artist],
|
2018-10-04 20:57:27 +02:00
|
|
|
date=payload["release_date"],
|
|
|
|
num_tracks=len(payload.get("tracks", [])),
|
2018-10-03 21:51:48 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
|
2018-10-04 20:57:27 +02:00
|
|
|
@cast_to_ref
|
2018-10-05 00:06:09 +02:00
|
|
|
def convert_to_track(payload, uri_prefix="funkwhale:tracks"):
|
2018-10-04 20:57:27 +02:00
|
|
|
artist = convert_to_artist(payload["artist"])
|
|
|
|
album = convert_to_album(payload["album"])
|
2020-09-25 05:26:05 +02:00
|
|
|
|
2019-01-27 10:18:54 +01:00
|
|
|
try:
|
|
|
|
upload = payload["uploads"][0]
|
|
|
|
except (KeyError, IndexError):
|
|
|
|
upload = {}
|
2018-10-03 21:51:48 +02:00
|
|
|
return models.Track(
|
2018-10-05 00:06:09 +02:00
|
|
|
uri=uri_prefix + ":%s" % payload["id"],
|
2018-10-04 20:57:27 +02:00
|
|
|
name=payload["title"],
|
|
|
|
musicbrainz_id=payload["mbid"],
|
2018-10-03 21:51:48 +02:00
|
|
|
artists=[artist],
|
|
|
|
album=album,
|
2018-10-04 20:57:27 +02:00
|
|
|
date=payload["album"]["release_date"],
|
2020-05-11 16:13:45 +02:00
|
|
|
bitrate=int((upload.get("bitrate") or 0) / 1000),
|
2019-01-27 10:18:54 +01:00
|
|
|
length=(upload.get("duration") or 0) * 1000,
|
2018-10-04 20:57:27 +02:00
|
|
|
track_no=payload["position"],
|
2018-10-03 21:51:48 +02:00
|
|
|
)
|
2018-10-04 20:57:27 +02:00
|
|
|
|
|
|
|
|
2020-07-01 20:55:30 +02:00
|
|
|
def convert_to_ref(payload, uri_prefix="funkwhale:libraries"):
|
|
|
|
try:
|
|
|
|
upload = payload["uploads"][0]
|
|
|
|
except (KeyError, IndexError):
|
|
|
|
upload = {}
|
|
|
|
return models.Ref(
|
|
|
|
uri=uri_prefix + ":%s" % payload["uuid"],
|
|
|
|
name=payload["name"],
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2018-10-04 20:57:27 +02:00
|
|
|
def to_ref(obj):
|
|
|
|
getter = getattr(models.Ref, obj.__class__.__name__.lower())
|
|
|
|
return getter(uri=obj.uri, name=obj.name)
|