Colin Powell 3 veckor sedan
förälder
incheckning
14d755dd36

+ 3 - 6
mopidy_smartplaylists/__init__.py

@@ -1,16 +1,13 @@
+import pathlib
+
 from mopidy import config, ext
 from importlib.metadata import version, PackageNotFoundError
 
-try:
-    __version__ = version("mopidy-smartplaylists")
-except PackageNotFoundError:
-    __version__ = "0.0.0"
-
 class Extension(ext.Extension):
 
     dist_name = "Mopidy-SmartPlaylists"
     ext_name = "smartplaylists"
-    version = __version__
+    version = "0.1.0"
 
     def get_default_config(self):
         return config.read(pathlib.Path(__file__).parent / "ext.conf")

+ 6 - 13
mopidy_smartplaylists/backend.py

@@ -1,17 +1,10 @@
-import pykka
+import mopidy.backend
+from .library import SmartLibrary
 
-import logging
-from mopidy.core import CoreListener
-from .playlists import SmartPlaylistsProvider
+class SmartPlaylistsBackend(mopidy.backend.Backend):
+    uri_schemes = ["smart"]
 
-
-logger = logging.getLogger(__name__)
-
-
-class SmartPlaylistsBackend(pykka.ThreadingActor, CoreListener):
     def __init__(self, config, audio):
-        super(SmartPlaylistsBackend, self).__init__()
+        super().__init__(audio=audio)
         self.config = config["smartplaylists"]
-
-        # Initialize playlist provider
-        self.playlists = SmartPlaylistsProvider(backend=self, config=self.config)
+        self.library = SmartLibrary(backend=self, config=self.config)

+ 32 - 0
mopidy_smartplaylists/extension.py

@@ -0,0 +1,32 @@
+from mopidy import ext, config
+
+
+class Extension(ext.Extension):
+    dist_name = "mopidy-smartplaylists"
+    ext_name = "smartplaylists"
+    version = "0.3.0"
+
+
+def get_default_config(self):
+    return config.read("""
+        [smartplaylists]
+        # Comma-separated popular genres to expose as top-level folders
+        genres = rock,jazz,blues,pop,electronic,hiphop
+        # Maximum number of tracks to return per genre
+        max_tracks = 50
+        # Use case-insensitive matching for genres
+        case_insensitive = true
+    """)
+
+
+def get_config_schema(self):
+    schema = super().get_config_schema()
+    schema["genres"] = config.String(optional=True)
+    schema["max_tracks"] = config.Integer(optional=True)
+    schema["case_insensitive"] = config.Boolean(optional=True)
+    return schema
+
+
+def setup(self, registry):
+    from .backend import SmartPlaylistsBackend
+    registry.add("backend", SmartPlaylistsBackend)

+ 49 - 0
mopidy_smartplaylists/library.py

@@ -0,0 +1,49 @@
+from mopidy.backend import LibraryProvider
+from mopidy.models import Ref
+
+class SmartLibrary(LibraryProvider):
+    def __init__(self, backend, config):
+        super().__init__(backend)
+        self.config = config
+
+    def browse(self, uri):
+        if uri == "smart:":
+            return [
+                Ref.directory(uri="smart:genres", name="Genres"),
+                Ref.directory(uri="smart:artists", name="Artists"),
+            ]
+
+        if uri == "smart:genres":
+            return [
+                Ref.directory(uri=f"smart:genre:{g}", name=g.title())
+                for g in ["rock", "jazz", "blues"]
+            ]
+
+        if uri.startswith("smart:genre:"):
+            genre = uri.split(":", 2)[2]
+            tracks = self._tracks_for_genre(genre)
+            return [
+                Ref.track(uri=t.uri, name=t.name)
+                for t in tracks
+            ]
+
+        return []
+
+    def lookup(self, uri):
+        # return full Track models for playback
+        if uri.startswith("smart:genre:"):
+            genre = uri.split(":", 2)[2]
+            return self._tracks_for_genre(genre)
+
+        return []
+
+    def _tracks_for_genre(self, genre):
+        # WORKS: Use Mopidy’s global search API
+        results = self.backend.actor.root.actor.library.search(
+            {"genre": [genre]}
+        )
+        tracks = []
+        for r in results:
+            if r.tracks:
+                tracks.extend(r.tracks)
+        return tracks[:50]   # enforce max