diff --git a/beets/config_default.yaml b/beets/config_default.yaml index b42594f87..3490370e0 100644 --- a/beets/config_default.yaml +++ b/beets/config_default.yaml @@ -98,3 +98,5 @@ match: ignored: [] track_length_grace: 10 track_length_max: 30 + +dont_write_if_unchanged: no diff --git a/beets/ui/commands.py b/beets/ui/commands.py index 2c2df0e01..5a0826c61 100644 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -74,6 +74,15 @@ def _do_query(lib, query, album, also_items=True): return items, albums FLOAT_EPSILON = 0.01 +def _different(val1, val2): + if (val1 == val2) or \ + ( isinstance(val1, float) and isinstance(val2, float) and \ + abs(val1 - val2) < FLOAT_EPSILON ): + return False + + return True + + def _showdiff(field, oldval, newval): """Prints out a human-readable field difference line.""" # Considering floats incomparable for perfect equality, introduce @@ -1128,15 +1137,24 @@ def modify_items(lib, mods, query, write, move, album, confirm): items, albums = _do_query(lib, query, album, False) objs = albums if album else items + unchanged = [] + # Preview change. print_('Modifying %i %ss.' % (len(objs), 'album' if album else 'item')) for obj in objs: # Identify the changed object. ui.print_obj(obj, lib) + changed = False + # Show each change. for field, value in fsets.iteritems(): _showdiff(field, obj.get(field), value) + if _different(obj.get(field), value): + changed = True + + if not changed: + unchanged.append(obj) # Confirm. if confirm: @@ -1161,9 +1179,19 @@ def modify_items(lib, mods, query, write, move, album, confirm): # Apply tags if requested. if write: if album: - items = itertools.chain(*(a.items() for a in albums)) - for item in items: - item.write() + for a in albums: + if config['dont_write_if_unchanged'].get(bool) and \ + a in unchanged: + continue + for item in a.items(): + item.write() + + else: + for item in items: + if config['dont_write_if_unchanged'].get(bool) and \ + item in unchanged: + continue + item.write() modify_cmd = ui.Subcommand('modify', help='change metadata fields', aliases=('mod',))