mirror of
https://github.com/beetbox/beets.git
synced 2026-01-30 12:02:41 +01:00
Merge pull request #958 from geigerzaehler/item-sync
Update database mtimes in modify and write commands
This commit is contained in:
commit
8ec4f8bc24
3 changed files with 72 additions and 14 deletions
|
|
@ -470,6 +470,21 @@ class Item(LibModel):
|
|||
log.error(exc)
|
||||
return False
|
||||
|
||||
def try_sync(self, write=None):
|
||||
"""Synchronizes the current state with the database and the
|
||||
media file tags.
|
||||
|
||||
If `write` is `None` or `True` the method tries to write the
|
||||
tags to `self.path`. If `write` is `False` it does not write
|
||||
tags. Otherwise it interprets `write` as a path and tries to
|
||||
write the tags to that file.
|
||||
"""
|
||||
if write is True:
|
||||
write = None
|
||||
if write is not False:
|
||||
self.try_write(path=write)
|
||||
self.store()
|
||||
|
||||
# Files themselves.
|
||||
|
||||
def move_file(self, dest, copy=False):
|
||||
|
|
@ -882,6 +897,18 @@ class Album(LibModel):
|
|||
item[key] = value
|
||||
item.store()
|
||||
|
||||
def try_sync(self, write=True):
|
||||
"""Synchronizes the current state with the database, propagates
|
||||
it to the items and synchronizes them with the database and
|
||||
their files.
|
||||
|
||||
The `write` parameter is a boolean indicating whether to write
|
||||
tags to the item files.
|
||||
"""
|
||||
self.store()
|
||||
for item in self.items():
|
||||
item.try_sync(bool(write))
|
||||
|
||||
|
||||
# Query construction helper.
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ from __future__ import print_function
|
|||
import logging
|
||||
import os
|
||||
import time
|
||||
import itertools
|
||||
import codecs
|
||||
import platform
|
||||
import re
|
||||
|
|
@ -1298,7 +1297,7 @@ def modify_items(lib, mods, dels, query, write, move, album, confirm):
|
|||
if not ui.input_yn('Really modify%s (Y/n)?' % extra):
|
||||
return
|
||||
|
||||
# Apply changes to database.
|
||||
# Apply changes to database and files
|
||||
with lib.transaction():
|
||||
for obj in changed:
|
||||
if move:
|
||||
|
|
@ -1307,16 +1306,7 @@ def modify_items(lib, mods, dels, query, write, move, album, confirm):
|
|||
log.debug('moving object %s' % cur_path)
|
||||
obj.move()
|
||||
|
||||
obj.store()
|
||||
|
||||
# Apply tags if requested.
|
||||
if write:
|
||||
if album:
|
||||
changed_items = itertools.chain(*(a.items() for a in changed))
|
||||
else:
|
||||
changed_items = changed
|
||||
for item in changed_items:
|
||||
item.try_write()
|
||||
obj.try_sync(write)
|
||||
|
||||
|
||||
def modify_parse_args(args):
|
||||
|
|
@ -1457,7 +1447,7 @@ def write_items(lib, query, pretend, force):
|
|||
changed = ui.show_model_changes(item, clean_item,
|
||||
library.Item._media_fields, force)
|
||||
if (changed or force) and not pretend:
|
||||
item.try_write()
|
||||
item.try_sync()
|
||||
|
||||
|
||||
def write_func(lib, opts, args):
|
||||
|
|
|
|||
|
|
@ -145,7 +145,8 @@ class ModifyTest(unittest.TestCase, TestHelper):
|
|||
|
||||
def setUp(self):
|
||||
self.setup_beets()
|
||||
self.add_album_fixture()
|
||||
self.album = self.add_album_fixture()
|
||||
[self.item] = self.album.items()
|
||||
|
||||
def tearDown(self):
|
||||
self.teardown_beets()
|
||||
|
|
@ -183,6 +184,22 @@ class ModifyTest(unittest.TestCase, TestHelper):
|
|||
item = self.lib.items().get()
|
||||
self.assertNotIn('newTitle', item.path)
|
||||
|
||||
def test_update_mtime(self):
|
||||
item = self.item
|
||||
old_mtime = item.mtime
|
||||
|
||||
self.modify("title=newTitle")
|
||||
item.load()
|
||||
self.assertNotEqual(old_mtime, item.mtime)
|
||||
self.assertEqual(item.current_mtime(), item.mtime)
|
||||
|
||||
def test_reset_mtime_with_no_write(self):
|
||||
item = self.item
|
||||
|
||||
self.modify("--nowrite", "title=newTitle")
|
||||
item.load()
|
||||
self.assertEqual(0, item.mtime)
|
||||
|
||||
# Album Tests
|
||||
|
||||
def test_modify_album(self):
|
||||
|
|
@ -275,6 +292,30 @@ class ModifyTest(unittest.TestCase, TestHelper):
|
|||
self.assertEqual(mods, {"title": "newTitle"})
|
||||
|
||||
|
||||
class WriteTest(unittest.TestCase, TestHelper):
|
||||
|
||||
def setUp(self):
|
||||
self.setup_beets()
|
||||
|
||||
def tearDown(self):
|
||||
self.teardown_beets()
|
||||
|
||||
def write_cmd(self, *args):
|
||||
ui._raw_main(['write'] + list(args), self.lib)
|
||||
|
||||
def test_update_mtime(self):
|
||||
item = self.add_item_fixture()
|
||||
item['title'] = 'a new title'
|
||||
item.store()
|
||||
|
||||
item = self.lib.items().get()
|
||||
self.assertEqual(item.mtime, 0)
|
||||
|
||||
self.write_cmd()
|
||||
item = self.lib.items().get()
|
||||
self.assertEqual(item.mtime, item.current_mtime())
|
||||
|
||||
|
||||
class MoveTest(_common.TestCase):
|
||||
def setUp(self):
|
||||
super(MoveTest, self).setUp()
|
||||
|
|
|
|||
Loading…
Reference in a new issue