20
20
from dataclasses import dataclass
21
21
from mimetypes import guess_type
22
22
from os .path import getsize , isfile
23
- from typing import Mapping
23
+ from typing import ClassVar , Mapping , Type
24
24
25
25
from flask import (
26
26
Blueprint ,
42
42
RegexpQuery ,
43
43
SlowFieldSort ,
44
44
)
45
- from beets .library import Album , Item , Library
45
+ from beets .library import Album , Item , LibModel , Library
46
46
from beets .plugins import BeetsPlugin
47
47
from beets .ui import Subcommand , _open_library
48
48
from beets .util import py3_path
124
124
class AURADocument :
125
125
"""Base class for building AURA documents."""
126
126
127
+ model_cls : ClassVar [Type [LibModel ]]
128
+
127
129
lib : Library
128
130
args : Mapping [str , str ]
129
131
@@ -147,6 +149,22 @@ def error(status, title, detail):
147
149
}
148
150
return make_response (document , status )
149
151
152
+ @classmethod
153
+ def get_attribute_converter (cls , beets_attr : str ) -> Type [SQLiteType ]:
154
+ """Work out what data type an attribute should be for beets.
155
+
156
+ Args:
157
+ beets_attr: The name of the beets attribute, e.g. "title".
158
+ """
159
+ try :
160
+ # Look for field in list of Album fields
161
+ # and get python type of database type.
162
+ # See beets.library.Album and beets.dbcore.types
163
+ return cls .model_cls ._fields [beets_attr ].model_type
164
+ except KeyError :
165
+ # Fall back to string (NOTE: probably not good)
166
+ return str
167
+
150
168
def translate_filters (self ):
151
169
"""Translate filters from request arguments to a beets Query."""
152
170
# The format of each filter key in the request parameter is:
@@ -339,6 +357,8 @@ def single_resource_document(self, resource_object):
339
357
class TrackDocument (AURADocument ):
340
358
"""Class for building documents for /tracks endpoints."""
341
359
360
+ model_cls = Item
361
+
342
362
attribute_map = TRACK_ATTR_MAP
343
363
344
364
def get_collection (self , query = None , sort = None ):
@@ -350,25 +370,18 @@ def get_collection(self, query=None, sort=None):
350
370
"""
351
371
return self .lib .items (query , sort )
352
372
353
- def get_attribute_converter (self , beets_attr ):
373
+ @classmethod
374
+ def get_attribute_converter (cls , beets_attr : str ) -> Type [SQLiteType ]:
354
375
"""Work out what data type an attribute should be for beets.
355
376
356
377
Args:
357
378
beets_attr: The name of the beets attribute, e.g. "title".
358
379
"""
359
380
# filesize is a special field (read from disk not db?)
360
381
if beets_attr == "filesize" :
361
- converter = int
362
- else :
363
- try :
364
- # Look for field in list of Item fields
365
- # and get python type of database type.
366
- # See beets.library.Item and beets.dbcore.types
367
- converter = Item ._fields [beets_attr ].model_type
368
- except KeyError :
369
- # Fall back to string (NOTE: probably not good)
370
- converter = str
371
- return converter
382
+ return int
383
+
384
+ return super ().get_attribute_converter (beets_attr )
372
385
373
386
@staticmethod
374
387
def get_resource_object (lib : Library , track ):
@@ -426,6 +439,8 @@ def single_resource(self, track_id):
426
439
class AlbumDocument (AURADocument ):
427
440
"""Class for building documents for /albums endpoints."""
428
441
442
+ model_cls = Album
443
+
429
444
attribute_map = ALBUM_ATTR_MAP
430
445
431
446
def get_collection (self , query = None , sort = None ):
@@ -437,22 +452,6 @@ def get_collection(self, query=None, sort=None):
437
452
"""
438
453
return self .lib .albums (query , sort )
439
454
440
- def get_attribute_converter (self , beets_attr ):
441
- """Work out what data type an attribute should be for beets.
442
-
443
- Args:
444
- beets_attr: The name of the beets attribute, e.g. "title".
445
- """
446
- try :
447
- # Look for field in list of Album fields
448
- # and get python type of database type.
449
- # See beets.library.Album and beets.dbcore.types
450
- converter = Album ._fields [beets_attr ].model_type
451
- except KeyError :
452
- # Fall back to string (NOTE: probably not good)
453
- converter = str
454
- return converter
455
-
456
455
@staticmethod
457
456
def get_resource_object (lib : Library , album ):
458
457
"""Construct a JSON:API resource object from a beets Album.
@@ -526,6 +525,8 @@ def single_resource(self, album_id):
526
525
class ArtistDocument (AURADocument ):
527
526
"""Class for building documents for /artists endpoints."""
528
527
528
+ model_cls = Item
529
+
529
530
attribute_map = ARTIST_ATTR_MAP
530
531
531
532
def get_collection (self , query = None , sort = None ):
@@ -544,22 +545,6 @@ def get_collection(self, query=None, sort=None):
544
545
collection .append (track .artist )
545
546
return collection
546
547
547
- def get_attribute_converter (self , beets_attr ):
548
- """Work out what data type an attribute should be for beets.
549
-
550
- Args:
551
- beets_attr: The name of the beets attribute, e.g. "artist".
552
- """
553
- try :
554
- # Look for field in list of Item fields
555
- # and get python type of database type.
556
- # See beets.library.Item and beets.dbcore.types
557
- converter = Item ._fields [beets_attr ].model_type
558
- except KeyError :
559
- # Fall back to string (NOTE: probably not good)
560
- converter = str
561
- return converter
562
-
563
548
@staticmethod
564
549
def get_resource_object (lib : Library , artist_id ):
565
550
"""Construct a JSON:API resource object for the given artist.
@@ -643,6 +628,8 @@ def safe_filename(fn):
643
628
class ImageDocument (AURADocument ):
644
629
"""Class for building documents for /images/(id) endpoints."""
645
630
631
+ model_cls = Album
632
+
646
633
@staticmethod
647
634
def get_image_path (lib : Library , image_id ):
648
635
"""Works out the full path to the image with the given id.
0 commit comments