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