write: Do not try to write non-writable fields

Fix #1268.
This commit is contained in:
Adrian Sampson 2015-01-27 15:03:19 -08:00
parent 84b42b6f1e
commit 790c41a73d
4 changed files with 42 additions and 1 deletions

View file

@ -402,6 +402,14 @@ class Item(LibModel):
`write`.
"""
_media_tag_fields = set(MediaFile.fields()).intersection(_fields.keys())
"""Set of item fields that are backed by *writable* `MediaFile` tag
fields.
This excludes fields that represent audio data, such as `bitrate` or
`length`.
"""
_formatter = FormattedItemMapping
_sorts = {'artist': SmartArtistSort}

View file

@ -1428,7 +1428,7 @@ def write_items(lib, query, pretend, force):
# Check for and display changes.
changed = ui.show_model_changes(item, clean_item,
library.Item._media_fields, force)
library.Item._media_tag_fields, force)
if (changed or force) and not pretend:
item.try_sync()

View file

@ -75,6 +75,8 @@ Fixes:
* :doc:`/plugins/importfeeds` and :doc:`/plugins/smartplaylist`: Automatically
create parent directories for playlist files (instead of crashing when the
parent directory does not exist). :bug:`1266`
* The :ref:`write-cmd` command no longer tries to "write" non-writable fields
like the bitrate. :bug:`1268`
For developers:

View file

@ -318,6 +318,37 @@ class WriteTest(unittest.TestCase, TestHelper):
item = self.lib.items().get()
self.assertEqual(item.mtime, item.current_mtime())
def test_non_metadata_field_unchanged(self):
"""Changing a non-"tag" field like `bitrate` and writing should
have no effect.
"""
# An item that starts out "clean".
item = self.add_item_fixture()
item.read()
# ... but with a mismatched bitrate.
item.bitrate = 123
item.store()
with capture_stdout() as stdout:
self.write_cmd()
self.assertEqual(stdout.getvalue(), '')
def test_write_metadata_field(self):
item = self.add_item_fixture()
item.read()
old_title = item.title
item.title = 'new title'
item.store()
with capture_stdout() as stdout:
self.write_cmd()
self.assertTrue('{0} -> new title'.format(old_title)
in stdout.getvalue())
class MoveTest(_common.TestCase):
def setUp(self):