Add path argument to item.write()

Symmetrical to item.read(), this allows us to update the tags of files that are
not in the library. The motivation was this issue [1].

The commit also includes a nasty hack in the plugin code that prevents breaking
other plugins.

[1]: https://github.com/geigerzaehler/beets-check/issues/1
This commit is contained in:
Thomas Scholtes 2014-04-04 14:56:10 +02:00
parent ee2cf0df8e
commit 766c8b190b
3 changed files with 20 additions and 10 deletions

View file

@ -414,17 +414,23 @@ class Item(LibModel):
self.path = read_path
def write(self):
"""Write the item's metadata to the associated file.
def write(self, path=None):
"""Write the item's metadata to a media file.
``path`` defaults to the item's path property.
Can raise either a `ReadError` or a `WriteError`.
"""
if path is None:
path = self.path
else:
path = normpath(path)
try:
f = MediaFile(syspath(self.path))
f = MediaFile(syspath(path))
except (OSError, IOError) as exc:
raise ReadError(self.path, exc)
plugins.send('write', item=self)
plugins.send('write', item=self, path=path)
for key in ITEM_KEYS_WRITABLE:
setattr(f, key, self[key])

View file

@ -17,6 +17,7 @@
import logging
import traceback
from collections import defaultdict
import inspect
import beets
@ -339,4 +340,8 @@ def send(event, **arguments):
Returns a list of return values from the handlers.
"""
log.debug('Sending event: %s' % event)
return [handler(**arguments) for handler in event_handlers()[event]]
for handler in event_handlers()[event]:
# Don't break legacy plugins if we want to pass more arguments
argspec = inspect.getargspec(handler).args
args = dict((k, v) for k, v in arguments.items() if k in argspec)
handler(**args)

View file

@ -174,13 +174,12 @@ def convert_item(dest_dir, keep_new, path_formats):
encode(item.path, dest)
# Write tags from the database to the converted file.
if not keep_new:
item.path = dest
item.write()
item.write(path=dest)
# If we're keeping the transcoded file, read it again (after
# writing) to get new bitrate, duration, etc.
if keep_new:
# If we're keeping the transcoded file, read it again (after
# writing) to get new bitrate, duration, etc.
item.path = dest
item.read()
item.store() # Store new path and audio data.