mirror of
https://github.com/beetbox/beets.git
synced 2026-02-22 23:33:50 +01:00
Remove ITEM_* constants
We might consider renaming `Item._fields` to `Item.fields` since other parts of beets use it as a replacement for `ITEM_KEYS`. See also #650.
This commit is contained in:
parent
883e3b3bc7
commit
f6f974ec87
5 changed files with 78 additions and 91 deletions
151
beets/library.py
151
beets/library.py
|
|
@ -110,84 +110,6 @@ class PathType(types.Type):
|
|||
return normpath(bytestring_path(string))
|
||||
|
||||
|
||||
|
||||
# Model field lists.
|
||||
|
||||
|
||||
# Fields in the "items" database table; all the metadata available for
|
||||
# items in the library. These are used directly in SQL; they are
|
||||
# vulnerable to injection if accessible to the user.
|
||||
# Each tuple has the following values:
|
||||
# - The name of the field.
|
||||
# - The (Python) type of the field.
|
||||
# - Is the field writable?
|
||||
# - Does the field reflect an attribute of a MediaFile?
|
||||
ITEM_FIELDS = [
|
||||
('id', types.Id(True)),
|
||||
('path', PathType()),
|
||||
('album_id', types.Id(False)),
|
||||
|
||||
('title', types.String()),
|
||||
('artist', types.String()),
|
||||
('artist_sort', types.String()),
|
||||
('artist_credit', types.String()),
|
||||
('album', types.String()),
|
||||
('albumartist', types.String()),
|
||||
('albumartist_sort', types.String()),
|
||||
('albumartist_credit', types.String()),
|
||||
('genre', types.String()),
|
||||
('composer', types.String()),
|
||||
('grouping', types.String()),
|
||||
('year', types.PaddedInt(4)),
|
||||
('month', types.PaddedInt(2)),
|
||||
('day', types.PaddedInt(2)),
|
||||
('track', types.PaddedInt(2)),
|
||||
('tracktotal', types.PaddedInt(2)),
|
||||
('disc', types.PaddedInt(2)),
|
||||
('disctotal', types.PaddedInt(2)),
|
||||
('lyrics', types.String()),
|
||||
('comments', types.String()),
|
||||
('bpm', types.Integer()),
|
||||
('comp', types.Boolean()),
|
||||
('mb_trackid', types.String()),
|
||||
('mb_albumid', types.String()),
|
||||
('mb_artistid', types.String()),
|
||||
('mb_albumartistid', types.String()),
|
||||
('albumtype', types.String()),
|
||||
('label', types.String()),
|
||||
('acoustid_fingerprint', types.String()),
|
||||
('acoustid_id', types.String()),
|
||||
('mb_releasegroupid', types.String()),
|
||||
('asin', types.String()),
|
||||
('catalognum', types.String()),
|
||||
('script', types.String()),
|
||||
('language', types.String()),
|
||||
('country', types.String()),
|
||||
('albumstatus', types.String()),
|
||||
('media', types.String()),
|
||||
('albumdisambig', types.String()),
|
||||
('disctitle', types.String()),
|
||||
('encoder', types.String()),
|
||||
('rg_track_gain', types.Float()),
|
||||
('rg_track_peak', types.Float()),
|
||||
('rg_album_gain', types.Float()),
|
||||
('rg_album_peak', types.Float()),
|
||||
('original_year', types.PaddedInt(4)),
|
||||
('original_month', types.PaddedInt(2)),
|
||||
('original_day', types.PaddedInt(2)),
|
||||
|
||||
('length', types.Float()),
|
||||
('bitrate', types.ScaledInt(1000, u'kbps')),
|
||||
('format', types.String()),
|
||||
('samplerate', types.ScaledInt(1000, u'kHz')),
|
||||
('bitdepth', types.Integer()),
|
||||
('channels', types.Integer()),
|
||||
('mtime', DateType()),
|
||||
('added', DateType()),
|
||||
]
|
||||
ITEM_KEYS = [f[0] for f in ITEM_FIELDS]
|
||||
|
||||
|
||||
# Database fields for the "albums" table.
|
||||
# The third entry in each tuple indicates whether the field reflects an
|
||||
# identically-named field in the items table.
|
||||
|
|
@ -232,7 +154,6 @@ ALBUM_KEYS_ITEM = [f[0] for f in ALBUM_FIELDS if f[2]]
|
|||
|
||||
# Default search fields for each model.
|
||||
ALBUM_DEFAULT_FIELDS = ('album', 'albumartist', 'genre')
|
||||
ITEM_DEFAULT_FIELDS = ALBUM_DEFAULT_FIELDS + ('artist', 'title', 'comments')
|
||||
|
||||
|
||||
# Special path format key.
|
||||
|
|
@ -328,12 +249,76 @@ class LibModel(dbcore.Model):
|
|||
|
||||
|
||||
class Item(LibModel):
|
||||
_fields = dict((name, typ) for (name, typ) in ITEM_FIELDS)
|
||||
_table = 'items'
|
||||
_flex_table = 'item_attributes'
|
||||
_search_fields = ITEM_DEFAULT_FIELDS
|
||||
_fields = {
|
||||
'id': types.Id(True),
|
||||
'path': PathType(),
|
||||
'album_id': types.Id(False),
|
||||
|
||||
_media_fields = set(MediaFile.readable_fields()).intersection(ITEM_KEYS)
|
||||
'title': types.String(),
|
||||
'artist': types.String(),
|
||||
'artist_sort': types.String(),
|
||||
'artist_credit': types.String(),
|
||||
'album': types.String(),
|
||||
'albumartist': types.String(),
|
||||
'albumartist_sort': types.String(),
|
||||
'albumartist_credit': types.String(),
|
||||
'genre': types.String(),
|
||||
'composer': types.String(),
|
||||
'grouping': types.String(),
|
||||
'year': types.PaddedInt(4),
|
||||
'month': types.PaddedInt(2),
|
||||
'day': types.PaddedInt(2),
|
||||
'track': types.PaddedInt(2),
|
||||
'tracktotal': types.PaddedInt(2),
|
||||
'disc': types.PaddedInt(2),
|
||||
'disctotal': types.PaddedInt(2),
|
||||
'lyrics': types.String(),
|
||||
'comments': types.String(),
|
||||
'bpm': types.Integer(),
|
||||
'comp': types.Boolean(),
|
||||
'mb_trackid': types.String(),
|
||||
'mb_albumid': types.String(),
|
||||
'mb_artistid': types.String(),
|
||||
'mb_albumartistid': types.String(),
|
||||
'albumtype': types.String(),
|
||||
'label': types.String(),
|
||||
'acoustid_fingerprint': types.String(),
|
||||
'acoustid_id': types.String(),
|
||||
'mb_releasegroupid': types.String(),
|
||||
'asin': types.String(),
|
||||
'catalognum': types.String(),
|
||||
'script': types.String(),
|
||||
'language': types.String(),
|
||||
'country': types.String(),
|
||||
'albumstatus': types.String(),
|
||||
'media': types.String(),
|
||||
'albumdisambig': types.String(),
|
||||
'disctitle': types.String(),
|
||||
'encoder': types.String(),
|
||||
'rg_track_gain': types.Float(),
|
||||
'rg_track_peak': types.Float(),
|
||||
'rg_album_gain': types.Float(),
|
||||
'rg_album_peak': types.Float(),
|
||||
'original_year': types.PaddedInt(4),
|
||||
'original_month': types.PaddedInt(2),
|
||||
'original_day': types.PaddedInt(2),
|
||||
|
||||
'length': types.Float(),
|
||||
'bitrate': types.ScaledInt(1000, u'kbps'),
|
||||
'format': types.String(),
|
||||
'samplerate': types.ScaledInt(1000, u'kHz'),
|
||||
'bitdepth': types.Integer(),
|
||||
'channels': types.Integer(),
|
||||
'mtime': DateType(),
|
||||
'added': DateType(),
|
||||
}
|
||||
|
||||
_search_fields = ALBUM_DEFAULT_FIELDS + ('artist', 'title', 'comments')
|
||||
|
||||
_media_fields = set(MediaFile.readable_fields()) \
|
||||
.intersection(_fields.keys())
|
||||
"""Set of item fields that are backed by `MediaFile` fields.
|
||||
|
||||
Any kind of field (fixed, flexible, and computed) may be a media
|
||||
|
|
@ -563,7 +548,7 @@ class Item(LibModel):
|
|||
album = self.get_album()
|
||||
if album:
|
||||
for key in album.keys(True):
|
||||
if key in ALBUM_KEYS_ITEM or key not in ITEM_KEYS:
|
||||
if key in ALBUM_KEYS_ITEM or key not in self._fields.keys():
|
||||
mapping[key] = album._get_formatted(key, for_path)
|
||||
|
||||
# Use the album artist if the track artist is not set and
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ def fields_func(lib, opts, args):
|
|||
_print_rows(plugin_fields)
|
||||
|
||||
print("Item fields:")
|
||||
_print_rows(library.ITEM_KEYS)
|
||||
_print_rows(library.Item._fields.keys())
|
||||
_show_plugin_fields(False)
|
||||
|
||||
print("\nAlbum fields:")
|
||||
|
|
@ -1401,7 +1401,7 @@ def completion_script(commands):
|
|||
|
||||
# Fields
|
||||
yield " fields='%s'\n" % ' '.join(
|
||||
set(library.ITEM_KEYS + library.ALBUM_KEYS))
|
||||
set(library.Item._fields.keys() + library.ALBUM_KEYS))
|
||||
|
||||
# Command options
|
||||
for cmd, opts in options.items():
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ from beets.plugins import BeetsPlugin
|
|||
import beets.ui
|
||||
from beets import vfs
|
||||
from beets.util import bluelet
|
||||
from beets.library import ITEM_KEYS
|
||||
from beets.library import Item
|
||||
from beets import dbcore
|
||||
from beets.mediafile import MediaFile
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ SAFE_COMMANDS = (
|
|||
u'close', u'commands', u'notcommands', u'password', u'ping',
|
||||
)
|
||||
|
||||
ITEM_KEYS_WRITABLE = set(MediaFile.fields()).intersection(ITEM_KEYS)
|
||||
ITEM_KEYS_WRITABLE = set(MediaFile.fields()).intersection(Item._fields.keys())
|
||||
|
||||
# Loggers.
|
||||
log = logging.getLogger('beets.bpd')
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
import re
|
||||
import logging
|
||||
from beets.plugins import BeetsPlugin
|
||||
from beets.library import ITEM_KEYS
|
||||
from beets.library import Item
|
||||
from beets.importer import action
|
||||
from beets.util import confit
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ class ZeroPlugin(BeetsPlugin):
|
|||
self.warned = False
|
||||
|
||||
for f in self.config['fields'].as_str_seq():
|
||||
if f not in ITEM_KEYS:
|
||||
if f not in Item._fields.keys():
|
||||
self._log.error(u'[zero] invalid field: {0}'.format(f))
|
||||
else:
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -81,8 +81,10 @@ class QueryParseTest(_common.TestCase):
|
|||
|
||||
class AnyFieldQueryTest(_common.LibTestCase):
|
||||
def test_no_restriction(self):
|
||||
q = dbcore.query.AnyFieldQuery('title', beets.library.ITEM_KEYS,
|
||||
dbcore.query.SubstringQuery)
|
||||
q = dbcore.query.AnyFieldQuery(
|
||||
'title', beets.library.Item._fields.keys(),
|
||||
dbcore.query.SubstringQuery
|
||||
)
|
||||
self.assertEqual(self.lib.items(q).get().title, 'the title')
|
||||
|
||||
def test_restriction_completeness(self):
|
||||
|
|
|
|||
Loading…
Reference in a new issue