Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 22 additions & 7 deletions picard/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -676,8 +676,16 @@ def _rename(self, old_filename, metadata, settings):
new_dirname = os.path.dirname(new_filename)
if not os.path.isdir(new_dirname):
os.makedirs(new_dirname)
if not settings['move_overwrite_existing_files']:
new_filename = get_available_filename(new_filename, old_filename)
config = get_config()
strategy = config.setting.get('move_conflict_strategy', 'rename')
if os.path.exists(new_filename):
if strategy == "skip":
log.warning("Destination exists, skipping move of %r", old_filename)
return old_filename
elif strategy == "rename":
new_filename = get_available_filename(new_filename, old_filename)
elif strategy == "overwrite":
pass
log.debug("Moving file %r => %r", old_filename, new_filename)
move_ensure_casing(old_filename, new_filename)
return new_filename
Expand Down Expand Up @@ -708,7 +716,7 @@ def _move_additional_files(self, old_filename, new_filename, config):
patterns = self._compile_move_additional_files_pattern(patterns_string)
try:
moves = self._get_additional_files_moves(old_path, new_path, patterns)
self._apply_additional_files_moves(moves, config.setting['move_overwrite_existing_files'])
self._apply_additional_files_moves(moves)
except OSError as why:
log.error("Failed to scan %r: %s", old_path, why)

Expand All @@ -732,15 +740,22 @@ def _get_additional_files_moves(self, old_path, new_path, patterns):
yield (entry.path, new_file_path)
break # we are done with this file

def _apply_additional_files_moves(self, moves, overwrite_existing_files=False):
def _apply_additional_files_moves(self, moves):
config = get_config()
strategy = config.setting.get('move_conflict_strategy', 'rename')
for old_file_path, new_file_path in moves:
# FIXME we shouldn't do this from a thread!
if self.tagger.files.get(decode_filename(old_file_path)):
log.debug("File loaded in the tagger, not moving %r", old_file_path)
continue
if not overwrite_existing_files and os.path.exists(new_file_path):
log.warning("File %r already exists, not moving %r", new_file_path, old_file_path)
continue
if os.path.exists(new_file_path):
if strategy == "skip":
log.warning("File %r exists, skipping %r", new_file_path, old_file_path)
continue
elif strategy == "rename":
new_file_path = get_available_filename(new_file_path)
elif strategy == "overwrite":
pass
log.debug("Moving %r to %r", old_file_path, new_file_path)
try:
shutil.move(old_file_path, new_file_path)
Expand Down
2 changes: 1 addition & 1 deletion picard/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,6 @@ def make_default_toolbar_layout():
TextOption('setting', 'move_additional_files_pattern', "*.jpg *.png", title=N_("Additional file patterns"))
BoolOption('setting', 'move_files', False, title=N_("Move files"))
TextOption('setting', 'move_files_to', DEFAULT_MUSIC_DIR, title=N_("Destination directory"))
BoolOption('setting', 'move_overwrite_existing_files', False, title=N_("Overwrite existing files"))
BoolOption('setting', 'rename_files', False, title=N_("Rename files"))

# picard/ui/options/renaming_compat.py
Expand Down Expand Up @@ -540,6 +539,7 @@ def make_default_toolbar_layout():
'',
title=N_("Sessions directory"),
)
TextOption('setting', 'move_conflict_strategy', 'rename', title=N_("File conflict handling strategy"))

# picard/ui/searchdialog/album.py
#
Expand Down
14 changes: 11 additions & 3 deletions picard/ui/options/renaming.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ class RenamingOptionsPage(OptionsPage):
OPTIONS = (
('move_files', ['move_files']),
('move_files_to', ['move_files_to']),
('move_overwrite_existing_files', ['move_overwrite_existing_files']),
('move_additional_files', ['move_additional_files']),
('move_additional_files_pattern', ['move_additional_files_pattern']),
('move_conflict_strategy', ['move_conflict_strategy']),
('delete_empty_dirs', ['delete_empty_dirs']),
('rename_files', ['rename_files']),
('selected_file_naming_script_id', ['naming_script_selector']),
Expand Down Expand Up @@ -250,8 +250,11 @@ def load(self):
self.ui.move_files_to.setCursorPosition(0)
self.ui.move_additional_files.setChecked(config.setting['move_additional_files'])
self.ui.move_additional_files_pattern.setText(config.setting['move_additional_files_pattern'])
strategy = config.setting['move_conflict_strategy']
self.ui.move_conflict_skip.setChecked(strategy == "skip")
self.ui.move_conflict_rename.setChecked(strategy == "rename")
self.ui.move_conflict_overwrite.setChecked(strategy == "overwrite")
self.ui.delete_empty_dirs.setChecked(config.setting['delete_empty_dirs'])
self.ui.move_overwrite_existing_files.setChecked(config.setting['move_overwrite_existing_files'])
self.naming_scripts = config.setting['file_renaming_scripts']
self.selected_naming_script_id = config.setting['selected_file_naming_script_id']
if self.script_editor_dialog:
Expand Down Expand Up @@ -285,9 +288,14 @@ def save(self):
config.setting['move_files'] = self.ui.move_files.isChecked()
config.setting['move_files_to'] = os.path.normpath(self.ui.move_files_to.text())
config.setting['move_additional_files'] = self.ui.move_additional_files.isChecked()
if self.ui.move_conflict_skip.isChecked():
config.setting['move_conflict_strategy'] = "skip"
elif self.ui.move_conflict_rename.isChecked():
config.setting['move_conflict_strategy'] = "rename"
elif self.ui.move_conflict_overwrite.isChecked():
config.setting['move_conflict_strategy'] = "overwrite"
config.setting['move_additional_files_pattern'] = self.ui.move_additional_files_pattern.text()
config.setting['delete_empty_dirs'] = self.ui.delete_empty_dirs.isChecked()
config.setting['move_overwrite_existing_files'] = self.ui.move_overwrite_existing_files.isChecked()
config.setting['selected_file_naming_script_id'] = self.selected_naming_script_id

def display_error(self, error):
Expand Down
22 changes: 19 additions & 3 deletions ui/options_renaming.ui
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,23 @@
</widget>
</item>
<item>
<widget class="QCheckBox" name="move_overwrite_existing_files">
<widget class="QRadioButton" name="move_conflict_skip">
<property name="text">
<string>Overwrite existing files</string>
<string>Do not move duplicate files</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="move_conflict_rename">
<property name="text">
<string>Move and rename file with numeric suffix</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="move_conflict_overwrite">
<property name="text">
<string>Move and overwrite existing files</string>
</property>
</widget>
</item>
Expand Down Expand Up @@ -298,7 +312,9 @@
<tabstop>move_additional_files</tabstop>
<tabstop>move_additional_files_pattern</tabstop>
<tabstop>delete_empty_dirs</tabstop>
<tabstop>move_overwrite_existing_files</tabstop>
<tabstop>move_conflict_skip</tabstop>
<tabstop>move_conflict_rename</tabstop>
<tabstop>move_conflict_overwrite</tabstop>
<tabstop>rename_files</tabstop>
<tabstop>naming_script_selector</tabstop>
<tabstop>open_script_editor</tabstop>
Expand Down
Loading