added bitrate and length to mediafile

--HG--
extra : convert_revision : svn%3A41726ec3-264d-0410-9c23-a9f1637257cc/trunk%40119
This commit is contained in:
adrian.sampson 2009-02-07 04:13:36 +00:00
parent 7ff7eabf7f
commit b1a45fda0b
5 changed files with 64 additions and 8 deletions

View file

@ -4,8 +4,10 @@ from string import Template
# Fields in the "items" 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.
metadata_fields = [
# accessible to the user. The fields are divided into read-write
# metadata, all metadata (inlcuding read-only attributes), and all
# fields (i.e., including non-metadata attributes).
metadata_rw_fields = [
('title', 'text'),
('artist', 'text'),
('album', 'text'),
@ -24,10 +26,15 @@ metadata_fields = [
('bpm', 'int'),
('comp', 'bool'),
]
metadata_fields = [
('length', 'real'),
('bitrate', 'int'),
] + metadata_rw_fields
item_fields = [
('id', 'integer primary key'),
('path', 'text'),
] + metadata_fields
metadata_rw_keys = map(operator.itemgetter(0), metadata_rw_fields)
metadata_keys = map(operator.itemgetter(0), metadata_fields)
item_keys = map(operator.itemgetter(0), item_fields)
@ -241,7 +248,7 @@ class Item(object):
def write(self):
"""Writes the item's metadata to the associated file."""
f = MediaFile(self.path)
for key in metadata_keys:
for key in metadata_rw_keys:
setattr(f, key, getattr(self, key))
f.save()
@ -262,7 +269,7 @@ class Item(object):
value = getattr(self, key)
# sanitize the value for inclusion in a path:
# replace / and leading . with _
if isinstance(value, str) or isinstance(value, unicode):
if isinstance(value, basestring):
value.replace(os.sep, '_')
re.sub(r'[' + os.sep + r']|^\.', '_', value)
elif key in ('track', 'tracktotal', 'disc', 'disctotal'):
@ -466,11 +473,11 @@ class CollectionQuery(Query):
return cls(subqueries)
class AnySubstringQuery(CollectionQuery):
"""A query that matches a substring in any item field. """
"""A query that matches a substring in any metadata field. """
def __init__(self, pattern):
subqueries = []
for field in item_keys:
for field in metadata_rw_keys:
subqueries.append(SubstringQuery(field, pattern))
super(AnySubstringQuery, self).__init__(subqueries)

View file

@ -505,4 +505,12 @@ class MediaFile(object):
as_type = bool),
flac = StorageStyle('compilation')
)
@property
def length(self):
return self.mgfile.info.length
@property
def bitrate(self):
return self.mgfile.info.bitrate

Binary file not shown.

View file

@ -30,6 +30,8 @@ def item(lib=None): return beets.library.Item({
'bpm': 8,
'comp': True,
'path': 'somepath',
'length': 60.0,
'bitrate': 128000,
}, lib)
np = beets.library._normpath
@ -173,4 +175,4 @@ def suite():
return unittest.TestLoader().loadTestsFromName(__name__)
if __name__ == '__main__':
unittest.main(defaultTest='suite')
unittest.main(defaultTest='suite')

View file

@ -21,6 +21,21 @@ def MakeReadingTest(path, correct_dict, field):
repr(got) + ') when testing ' + os.path.basename(path))
return ReadingTest
def MakeReadOnlyTest(path, field, value):
class ReadOnlyTest(unittest.TestCase):
def setUp(self):
self.f = beets.mediafile.MediaFile(path)
def runTest(self):
got = getattr(self.f, field)
fail_msg = field + ' incorrect (expected ' + \
repr(value) + ', got ' + repr(got) + \
') on ' + os.path.basename(path)
if field == 'length':
self.assertTrue(value-0.1 < got < value+0.1, fail_msg)
else:
self.assertEqual(got, value, fail_msg)
return ReadOnlyTest
def MakeWritingTest(path, correct_dict, field, testsuffix='_test'):
class WritingTest(unittest.TestCase):
@ -162,6 +177,24 @@ correct_dicts = {
}
read_only_correct_dicts = {
'full.mp3': {
'length': 1.0,
'bitrate': 80000,
},
'full.flac': {
'length': 1.0,
},
'full.m4a': {
'length': 1.0,
'bitrate': 64000,
},
}
def suite_for_file(path, correct_dict, writing=True):
s = unittest.TestSuite()
for field in correct_dict:
@ -191,6 +224,12 @@ def suite():
# Special test for advanced release date.
s.addTest(suite_for_file(os.path.join('rsrc', 'date.mp3'),
correct_dicts['date']))
# Read-only attribute tests.
for fname, correct_dict in read_only_correct_dicts.iteritems():
path = os.path.join('rsrc', fname)
for field, value in correct_dict.iteritems():
s.addTest(MakeReadOnlyTest(path, field, value)())
return s