Expired Cleaner: rename the safety toggle to dry_run (default ON), matching Re-tag
The destructive job's findings-vs-auto toggle was 'auto_delete: False'. Renamed to 'dry_run: True' to match the Re-tag job's convention and make the safe default unmistakable: dry run ON (default) = findings only, deletes nothing; dry run OFF = hands-off auto-delete. Behaviour-identical to the previous default — just clearer + consistent. Help text + tests updated.
This commit is contained in:
parent
696119d5ac
commit
46730d1661
2 changed files with 19 additions and 10 deletions
|
|
@ -69,12 +69,13 @@ class ExpiredDownloadCleanerJob(RepairJob):
|
||||||
'fewer than the keep-threshold (default: played more than once is kept). '
|
'fewer than the keep-threshold (default: played more than once is kept). '
|
||||||
'It only touches downloads recorded from the Download Origins feature '
|
'It only touches downloads recorded from the Download Origins feature '
|
||||||
'forward — never your pre-existing or manually-added library.\n\n'
|
'forward — never your pre-existing or manually-added library.\n\n'
|
||||||
'By default it creates findings for you to review and delete. Set '
|
'Dry run is ON by default: it only creates findings for you to review '
|
||||||
'Auto-delete to true for hands-off cleanup.\n\n'
|
'and delete — nothing is deleted automatically. Turn Dry run OFF for '
|
||||||
|
'hands-off auto-cleanup.\n\n'
|
||||||
'Settings:\n'
|
'Settings:\n'
|
||||||
'- Watchlist retention / Playlist retention: off, or a window\n'
|
'- Watchlist retention / Playlist retention: off, or a window\n'
|
||||||
'- Keep if played at least: play count that protects a track (default 2)\n'
|
'- Keep if played at least: play count that protects a track (default 2)\n'
|
||||||
'- Auto-delete: delete automatically instead of creating findings'
|
'- Dry run: ON = findings only (default); OFF = delete automatically'
|
||||||
)
|
)
|
||||||
icon = 'repair-icon-cleanup'
|
icon = 'repair-icon-cleanup'
|
||||||
default_enabled = False
|
default_enabled = False
|
||||||
|
|
@ -83,12 +84,12 @@ class ExpiredDownloadCleanerJob(RepairJob):
|
||||||
'watchlist_retention': 'off',
|
'watchlist_retention': 'off',
|
||||||
'playlist_retention': 'off',
|
'playlist_retention': 'off',
|
||||||
'keep_if_played_at_least': 2,
|
'keep_if_played_at_least': 2,
|
||||||
'auto_delete': False,
|
'dry_run': True,
|
||||||
}
|
}
|
||||||
setting_options = {
|
setting_options = {
|
||||||
'watchlist_retention': RETENTION_OPTIONS,
|
'watchlist_retention': RETENTION_OPTIONS,
|
||||||
'playlist_retention': RETENTION_OPTIONS,
|
'playlist_retention': RETENTION_OPTIONS,
|
||||||
'auto_delete': [False, True],
|
'dry_run': [True, False],
|
||||||
}
|
}
|
||||||
auto_fix = False
|
auto_fix = False
|
||||||
|
|
||||||
|
|
@ -110,7 +111,7 @@ class ExpiredDownloadCleanerJob(RepairJob):
|
||||||
min_plays = int(settings.get('keep_if_played_at_least', 2))
|
min_plays = int(settings.get('keep_if_played_at_least', 2))
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
min_plays = 2
|
min_plays = 2
|
||||||
auto_delete = bool(settings.get('auto_delete', False))
|
dry_run = bool(settings.get('dry_run', True))
|
||||||
|
|
||||||
candidates = context.db.get_origin_cleanup_candidates()
|
candidates = context.db.get_origin_cleanup_candidates()
|
||||||
if not candidates:
|
if not candidates:
|
||||||
|
|
@ -150,7 +151,7 @@ class ExpiredDownloadCleanerJob(RepairJob):
|
||||||
for i, entry in enumerate(expired):
|
for i, entry in enumerate(expired):
|
||||||
if context.check_stop():
|
if context.check_stop():
|
||||||
return result
|
return result
|
||||||
if auto_delete:
|
if not dry_run:
|
||||||
try:
|
try:
|
||||||
res = delete_origin_download(context.db, entry, context.config_manager)
|
res = delete_origin_download(context.db, entry, context.config_manager)
|
||||||
if res.get('removed') or res.get('file_deleted'):
|
if res.get('removed') or res.get('file_deleted'):
|
||||||
|
|
@ -191,7 +192,7 @@ class ExpiredDownloadCleanerJob(RepairJob):
|
||||||
|
|
||||||
logger.info("[Expired Cleaner] %d candidates, %d expired (%s)",
|
logger.info("[Expired Cleaner] %d candidates, %d expired (%s)",
|
||||||
len(candidates), len(expired),
|
len(candidates), len(expired),
|
||||||
"auto-deleted" if auto_delete else "findings created")
|
"findings created (dry run)" if dry_run else "auto-deleted")
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def estimate_scope(self, context: JobContext) -> int:
|
def estimate_scope(self, context: JobContext) -> int:
|
||||||
|
|
|
||||||
|
|
@ -104,11 +104,19 @@ def test_scan_protects_watched_artist():
|
||||||
assert findings == [] # still watched → protected
|
assert findings == [] # still watched → protected
|
||||||
|
|
||||||
|
|
||||||
def test_scan_auto_delete_mode():
|
def test_scan_dry_run_default_is_findings_only():
|
||||||
|
# No dry_run in settings → defaults to True → findings, never deletes.
|
||||||
|
db = _DB([_cand(1, created=OLD, path="/music/x.flac")])
|
||||||
|
findings = []
|
||||||
|
res = ExpiredDownloadCleanerJob().scan(_ctx(db, {'playlist_retention': '2mo'}, findings))
|
||||||
|
assert res.findings_created == 1 and db.deleted_history == [] # nothing deleted
|
||||||
|
|
||||||
|
|
||||||
|
def test_scan_auto_delete_when_dry_run_off():
|
||||||
db = _DB([_cand(1, created=OLD, path="/music/x.flac")])
|
db = _DB([_cand(1, created=OLD, path="/music/x.flac")])
|
||||||
findings = []
|
findings = []
|
||||||
res = ExpiredDownloadCleanerJob().scan(_ctx(
|
res = ExpiredDownloadCleanerJob().scan(_ctx(
|
||||||
db, {'playlist_retention': '2mo', 'auto_delete': True}, findings))
|
db, {'playlist_retention': '2mo', 'dry_run': False}, findings))
|
||||||
assert findings == [] # no findings in auto mode
|
assert findings == [] # no findings in auto mode
|
||||||
assert res.auto_fixed == 1
|
assert res.auto_fixed == 1
|
||||||
assert 1 in db.deleted_history # history row removed
|
assert 1 in db.deleted_history # history row removed
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue