Skip to content

Commit

Permalink
add album_save_post_processors to plug-in API.
Browse files Browse the repository at this point in the history
I wanted to extend the M3U playlist plugin to automatically generate an .m3u8
when Albums get saved.

To be able to do so, I needed to add album_save_post_processors so that I could
get access to an album on save.

File save is done in a thread, so I needed to implement a way to wait for those
threads to finish by using the file_save_post_processors hook.
  • Loading branch information
Thomas Vander Stichele committed Jun 21, 2020
1 parent b2faec8 commit b4b1743
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 4 deletions.
17 changes: 17 additions & 0 deletions picard/album.py
Original file line number Diff line number Diff line change
Expand Up @@ -753,3 +753,20 @@ def register_album_post_removal_processor(function, priority=PluginPriority.NORM

def run_album_post_removal_processors(album_object):
_album_post_removal_processors.run(album_object)

_album_post_save_processors = PluginFunctions(label='album_post_save_processors')


def register_album_post_save_processor(function, priority=PluginPriority.NORMAL):
"""Registers an album-removed processor.
Args:
function: function to call after album save, it will be passed the album object
priority: optional, PluginPriority.NORMAL by default
Returns:
None
"""
_album_post_save_processors.register(function.__module__, function, priority)


def run_album_post_save_processors(album_object):
_album_post_save_processors.run(album_object)
29 changes: 25 additions & 4 deletions picard/tagger.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
Album,
NatAlbum,
run_album_post_removal_processors,
run_album_post_save_processors,
)
from picard.browser.browser import BrowserIntegration
from picard.browser.filelookup import FileLookup
Expand All @@ -98,7 +99,7 @@
)
from picard.dataobj import DataObject
from picard.disc import Disc
from picard.file import File
from picard.file import File, register_file_post_save_processor
from picard.formats import open_ as open_file
from picard.i18n import setup_gettext
from picard.pluginmanager import PluginManager
Expand Down Expand Up @@ -294,6 +295,10 @@ def __init__(self, picard_args, unparsed_args, localedir, autoupdate):
if self.autoupdate_enabled:
self.updatecheckmanager = UpdateCheckManager(parent=self.window)

# track all file save completions for album save
self._album_saves = []
register_file_post_save_processor(self._file_post_save)

def register_cleanup(self, func):
self.exit_cleanup.append(func)

Expand Down Expand Up @@ -658,9 +663,14 @@ def get_files_from_objects(self, objects, save=False):

def save(self, objects):
"""Save the specified objects."""
files = self.get_files_from_objects(objects, save=True)
for file in files:
file.save()
for o in objects:
log.debug('save object %r', o)
files = self.get_files_from_objects([o, ], save=True)
for file in files:
file.save()
if isinstance(o, Album):
# track the album and its files pending save
self._album_saves.append((o, files))

def load_album(self, album_id, discid=None):
album_id = self.mbid_redirects.get(album_id, album_id)
Expand Down Expand Up @@ -773,6 +783,17 @@ def remove(self, objects):
if files:
self.remove_files(files)

# run album_save hooks when the last file is saved
def _file_post_save(self, file):
for album, files in self._album_saves:
if file in files:
files.remove(file)
if not files:
log.debug("Album %r saved, running post_save_processors", album)
run_album_post_save_processors(album)
self._album_saves.remove((album, files))
return

def _lookup_disc(self, disc, result=None, error=None):
self.restore_cursor()
if error is not None:
Expand Down

0 comments on commit b4b1743

Please sign in to comment.