mirror of
https://github.com/beetbox/beets.git
synced 2025-12-06 16:42:42 +01:00
Improve logging management for plugins: fixes
Delete the remaining usages of BeetsPlugin.listen(). Since BeetsPlugin.listeners are wrapped by a loglevel-setting function, we cannot easily check their unicity anymore. BeetsPlugin._raw_listeners set holds the raw listeners. Legacy plugins that did not handle enough arguments in their listenings functions may break: dedicated code is now deleted for it would not work with the decorated listeners. Tests got fixed. Some modifications were done empirically: if it passes then it's okay.
This commit is contained in:
parent
4578c4f0e1
commit
327b62b610
5 changed files with 24 additions and 24 deletions
|
|
@ -18,7 +18,6 @@ from __future__ import (division, absolute_import, print_function,
|
|||
unicode_literals)
|
||||
|
||||
import traceback
|
||||
import inspect
|
||||
import re
|
||||
from collections import defaultdict
|
||||
from functools import wraps
|
||||
|
|
@ -180,17 +179,21 @@ class BeetsPlugin(object):
|
|||
mediafile.MediaFile.add_field(name, descriptor)
|
||||
library.Item._media_fields.add(name)
|
||||
|
||||
_raw_listeners = None
|
||||
listeners = None
|
||||
|
||||
def register_listener(self, event, func):
|
||||
"""Add a function as a listener for the specified event.
|
||||
"""
|
||||
func = self._set_log_level(logging.WARNING, func)
|
||||
wrapped_func = self._set_log_level(logging.WARNING, func)
|
||||
|
||||
if self.listeners is None:
|
||||
self.listeners = defaultdict(list)
|
||||
if func not in self.listeners[event]:
|
||||
self.listeners[event].append(func)
|
||||
cls = self.__class__
|
||||
if cls.listeners is None or cls._raw_listeners is None:
|
||||
cls._raw_listeners = defaultdict(list)
|
||||
cls.listeners = defaultdict(list)
|
||||
if func not in cls._raw_listeners[event]:
|
||||
cls._raw_listeners[event].append(func)
|
||||
cls.listeners[event].append(wrapped_func)
|
||||
|
||||
template_funcs = None
|
||||
template_fields = None
|
||||
|
|
@ -440,9 +443,7 @@ def send(event, **arguments):
|
|||
results = []
|
||||
for handler in event_handlers()[event]:
|
||||
# Don't break legacy plugins if we want to pass more arguments
|
||||
argspec = inspect.getargspec(handler).args
|
||||
args = dict((k, v) for k, v in arguments.items() if k in argspec)
|
||||
result = handler(**args)
|
||||
result = handler(**arguments)
|
||||
if result is not None:
|
||||
results.append(result)
|
||||
return results
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ class AcoustidPlugin(plugins.BeetsPlugin):
|
|||
|
||||
if self.config['auto']:
|
||||
self.register_listener('import_task_start', self.fingerprint_task)
|
||||
self.register_listener('import_task_apply', apply_acoustid_metadata)
|
||||
|
||||
def fingerprint_task(self, task, session):
|
||||
return fingerprint_task(self._log, task, session)
|
||||
|
|
@ -211,7 +212,6 @@ def fingerprint_task(log, task, session):
|
|||
acoustid_match(log, item.path)
|
||||
|
||||
|
||||
@AcoustidPlugin.listen('import_task_apply')
|
||||
def apply_acoustid_metadata(task, session):
|
||||
"""Apply Acoustid metadata (fingerprint and ID) to the task's items.
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -140,10 +140,11 @@ def apply_matches(d):
|
|||
# Plugin structure and hook into import process.
|
||||
|
||||
class FromFilenamePlugin(plugins.BeetsPlugin):
|
||||
pass
|
||||
def __init__(self):
|
||||
super(FromFilenamePlugin, self).__init__()
|
||||
self.register_listener('import_task_start', filename_task)
|
||||
|
||||
|
||||
@FromFilenamePlugin.listen('import_task_start')
|
||||
def filename_task(task, session):
|
||||
"""Examine each item in the task to see if we can extract a title
|
||||
from the filename. Try to match all filenames to a number of
|
||||
|
|
|
|||
|
|
@ -37,9 +37,10 @@ class Permissions(BeetsPlugin):
|
|||
u'file': 644
|
||||
})
|
||||
|
||||
self.register_listener('item_imported', permissions)
|
||||
self.register_listener('album_imported', permissions)
|
||||
|
||||
|
||||
@Permissions.listen('item_imported')
|
||||
@Permissions.listen('album_imported')
|
||||
def permissions(lib, item=None, album=None):
|
||||
"""Running the permission fixer.
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ class TestHelper(helper.TestHelper):
|
|||
def setup_plugin_loader(self):
|
||||
# FIXME the mocking code is horrific, but this is the lowest and
|
||||
# earliest level of the plugin mechanism we can hook into.
|
||||
self.load_plugins()
|
||||
self._plugin_loader_patch = patch('beets.plugins.load_plugins')
|
||||
self._plugin_classes = set()
|
||||
load_plugins = self._plugin_loader_patch.start()
|
||||
|
|
@ -95,7 +96,7 @@ class ItemWriteTest(unittest.TestCase, TestHelper):
|
|||
|
||||
class EventListenerPlugin(plugins.BeetsPlugin):
|
||||
pass
|
||||
self.event_listener_plugin = EventListenerPlugin
|
||||
self.event_listener_plugin = EventListenerPlugin()
|
||||
self.register_plugin(EventListenerPlugin)
|
||||
|
||||
def tearDown(self):
|
||||
|
|
@ -298,19 +299,15 @@ class ListenersTest(unittest.TestCase, TestHelper):
|
|||
pass
|
||||
|
||||
d = DummyPlugin()
|
||||
self.assertEqual(DummyPlugin.listeners['cli_exit'], [d.dummy])
|
||||
self.assertEqual(DummyPlugin._raw_listeners['cli_exit'], [d.dummy])
|
||||
|
||||
d2 = DummyPlugin()
|
||||
DummyPlugin.register_listener('cli_exit', d.dummy)
|
||||
self.assertEqual(DummyPlugin.listeners['cli_exit'],
|
||||
self.assertEqual(DummyPlugin._raw_listeners['cli_exit'],
|
||||
[d.dummy, d2.dummy])
|
||||
|
||||
@DummyPlugin.listen('cli_exit')
|
||||
def dummy(lib):
|
||||
pass
|
||||
|
||||
self.assertEqual(DummyPlugin.listeners['cli_exit'],
|
||||
[d.dummy, d2.dummy, dummy])
|
||||
d.register_listener('cli_exit', d2.dummy)
|
||||
self.assertEqual(DummyPlugin._raw_listeners['cli_exit'],
|
||||
[d.dummy, d2.dummy])
|
||||
|
||||
|
||||
def suite():
|
||||
|
|
|
|||
Loading…
Reference in a new issue