forked from encukou/picard-plugins
-
Notifications
You must be signed in to change notification settings - Fork 0
/
autosave.py
88 lines (72 loc) · 2.93 KB
/
autosave.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# -*- coding: utf-8 -*-
PLUGIN_NAME = u"Save well-identified albums"
PLUGIN_AUTHOR = u"Petr Viktorin, bainz34"
PLUGIN_DESCRIPTION = """
<p>
Save only those albums that were very confidently identified, and
remove them from the list.
</p>
<p>
Perfect when tagging a giant collection for the first time: cluster
everything, look everything up, then use this to save the albums that
were looked up with confidence.
</p>
<p>
Only saves & removes albums with 4 tracks or more, where each
track has more than 90% similarity to the original metadata.
</p>
<p>
<em>Usage:</em> Select all albums in the right pane, then choose
Plugins/Save and remove well-identified albums from the context menu.
</p>
"""
PLUGIN_VERSION = "0.2"
PLUGIN_API_VERSIONS = ["0.15", "1.1.0"]
from picard.album import Album
from picard.ui.itemviews import BaseAction, register_album_action
class SaveMatches(BaseAction):
NAME = "Save and remove well-identified albums"
def callback(self, objs):
for obj in objs:
if self.is_well_identified(obj):
self.save_album_files(obj)
def is_well_identified(self, album):
# We want albums only
if not isinstance(album, Album):
return False
self.log.debug('Looking at album %s', album.metadata['album'])
# The album has to be Complete
if not album.is_complete():
self.log.debug('Incomplete album %s', album.metadata['album'])
return False
if len(album.tracks) < 4:
# Too few tracks to be really confident
self.log.debug('Too few tracks for %s', album.metadata['album'])
return False
# All tracks have to have similarity >= 90%
for track in album.tracks:
if track.linked_files[0].similarity < 0.9:
self.log.debug('Track %s not similar enough', track.metadata['title'])
return False
return True
def save_album_files(self, album):
def next_action(result=None, error=None):
if error is not None:
self.log.info("Error! %s", self.error)
return
file, old_filename, new_filename = result
# mimic tagger._file_saved for the case the album will not
# be removed at last
del self.tagger.files[old_filename]
self.tagger.files[new_filename] = file
# Remove processed file from the file. When the list is
# empty, we are done with the album and it can be removed.
files_to_save.remove(file)
if not files_to_save:
self.tagger.remove_album(album)
self.log.info('Album complete: %s', album.metadata['album'])
files_to_save = list(album.iterfiles(save=True))
# Work on a copy of `files_to_save` to be thread-safe.
for file in files_to_save[:]:
file.save(next_action, self.config.setting)
register_album_action(SaveMatches())