diff --git a/beetsplug/convert.py b/beetsplug/convert.py index 671435c6c..75a16eb0f 100644 --- a/beetsplug/convert.py +++ b/beetsplug/convert.py @@ -28,17 +28,6 @@ log = logging.getLogger('beets') DEVNULL = open(os.devnull, 'wb') _fs_lock = threading.Lock() -config.add({ - 'convert': { - u'dest': None, - u'threads': util.cpu_count(), - u'ffmpeg': u'ffmpeg', - u'opts': u'-aq 2', - u'max_bitrate': 500, - u'embed': True, - } -}) - def encode(source, dest): log.info(u'Started encoding {0}'.format(util.displayable_path(source))) @@ -117,6 +106,17 @@ def convert_func(lib, opts, args): class ConvertPlugin(BeetsPlugin): + def __init__(self): + super(ConvertPlugin, self).__init__() + self.config.add({ + u'dest': None, + u'threads': util.cpu_count(), + u'ffmpeg': u'ffmpeg', + u'opts': u'-aq 2', + u'max_bitrate': 500, + u'embed': True, + }) + def commands(self): cmd = ui.Subcommand('convert', help='convert to external location') cmd.parser.add_option('-a', '--album', action='store_true', diff --git a/beetsplug/echonest_tempo.py b/beetsplug/echonest_tempo.py index 9406ae0ef..bdfc8ac21 100644 --- a/beetsplug/echonest_tempo.py +++ b/beetsplug/echonest_tempo.py @@ -26,13 +26,6 @@ import pyechonest.song # Global logger. log = logging.getLogger('beets') -config.add({ - 'echonest_tempo': { - 'apikey': u'NY2KTZHQ0QDSHBAP6', - 'auto': True, - } -}) - def fetch_item_tempo(lib, loglevel, item, write): """Fetch and store tempo for a single item. If ``write``, then the tempo will also be written to the file itself in the bpm field. The @@ -76,9 +69,13 @@ class EchoNestTempoPlugin(BeetsPlugin): def __init__(self): super(EchoNestTempoPlugin, self).__init__() self.import_stages = [self.imported] + self.config.add({ + 'apikey': u'NY2KTZHQ0QDSHBAP6', + 'auto': True, + }) pyechonest.config.ECHO_NEST_API_KEY = \ - config['echonest_tempo']['apikey'].get(unicode) + self.config['apikey'].get(unicode) def commands(self): cmd = ui.Subcommand('tempo', help='fetch song tempo (bpm)') @@ -99,6 +96,6 @@ class EchoNestTempoPlugin(BeetsPlugin): # Auto-fetch tempo on import. def imported(self, config, task): - if config['echonest_tempo']['auto']: + if self.config['auto']: for item in task.imported_items(): fetch_item_tempo(config.lib, logging.DEBUG, item, False) diff --git a/beetsplug/embedart.py b/beetsplug/embedart.py index c5625bb2e..c2a6bc18a 100644 --- a/beetsplug/embedart.py +++ b/beetsplug/embedart.py @@ -26,13 +26,6 @@ from beets import config log = logging.getLogger('beets') -config.add({ - 'embedart': { - 'maxwidth': 0, - 'auto': True, - } -}) - def _embed(path, items): """Embed an image file, located at `path`, into each item. """ @@ -65,9 +58,13 @@ class EmbedCoverArtPlugin(BeetsPlugin): """ def __init__(self): super(EmbedCoverArtPlugin, self).__init__() - if config['embedart']['maxwidth'].get(int) and \ + self.config.add({ + 'maxwidth': 0, + 'auto': True, + }) + if self.config['maxwidth'].get(int) and \ not ArtResizer.shared.local: - config['embedart']['maxwidth'] = 0 + self.config['maxwidth'] = 0 log.warn("embedart: ImageMagick or PIL not found; " "'maxwidth' option ignored") diff --git a/beetsplug/fetchart.py b/beetsplug/fetchart.py index 9c8185f53..2eb2b5103 100644 --- a/beetsplug/fetchart.py +++ b/beetsplug/fetchart.py @@ -34,13 +34,6 @@ DOWNLOAD_EXTENSION = '.jpg' log = logging.getLogger('beets') -config.add({ - 'fetchart': { - 'auto': True, - 'maxwidth': 0, - } -}) - def _fetch_image(url): """Downloads an image from a URL and checks whether it seems to @@ -216,15 +209,17 @@ class FetchArtPlugin(BeetsPlugin): def __init__(self): super(FetchArtPlugin, self).__init__() - self.autofetch = True - self.maxwidth = 0 + self.config.add({ + 'auto': True, + 'maxwidth': 0, + }) + # Holds paths to downloaded images between fetching them and # placing them in the filesystem. self.art_paths = {} - self.autofetch = config['fetchart']['auto'].get(bool) - self.maxwidth = config['fetchart']['maxwidth'].get(int) - if self.autofetch: + self.maxwidth = self.config['maxwidth'].get(int) + if self.config['auto']: # Enable two import hooks when fetching is enabled. self.import_stages = [self.fetch_art] self.register_listener('import_task_files', self.assign_art) diff --git a/beetsplug/fuzzy_search.py b/beetsplug/fuzzy_search.py index 3531a832c..4957462ef 100644 --- a/beetsplug/fuzzy_search.py +++ b/beetsplug/fuzzy_search.py @@ -20,15 +20,6 @@ from beets.util.functemplate import Template from beets import config import difflib -config.add({ - 'fuzzy': { - 'threshold': 0.7, - } -}) - - -# THRESHOLD = 0.7 - def fuzzy_score(queryMatcher, item): queryMatcher.set_seq1(item) @@ -96,5 +87,11 @@ fuzzy_cmd.func = fuzzy_list class Fuzzy(BeetsPlugin): + def __init__(self): + super(Fuzzy, self).__init__('fuzzy') + self.config.add({ + 'threshold': 0.7, + }) + def commands(self): return [fuzzy_cmd] diff --git a/beetsplug/ihate.py b/beetsplug/ihate.py index a0231b8d0..81f2d6464 100644 --- a/beetsplug/ihate.py +++ b/beetsplug/ihate.py @@ -25,20 +25,6 @@ __author__ = 'baobab@heresiarch.info' __version__ = '1.0' -config.add({ - 'ihate': { - 'warn_genre': [], - 'warn_artist': [], - 'warn_album': [], - 'warn_whitelist': [], - 'skip_genre': [], - 'skip_artist': [], - 'skip_album': [], - 'skip_whitelist': [], - } -}) - - class IHatePlugin(BeetsPlugin): _instance = None @@ -58,6 +44,20 @@ class IHatePlugin(BeetsPlugin): cls._instance = super(IHatePlugin, cls).__new__(cls, *args, **kwargs) return cls._instance + + def __init__(self): + super(IHatePlugin, self).__init__() + self.config.add({ + 'warn_genre': [], + 'warn_artist': [], + 'warn_album': [], + 'warn_whitelist': [], + 'skip_genre': [], + 'skip_artist': [], + 'skip_album': [], + 'skip_whitelist': [], + }) + @classmethod def match_patterns(cls, s, patterns): @@ -94,28 +94,28 @@ class IHatePlugin(BeetsPlugin): def job_to_do(self): """Return True if at least one pattern is defined.""" - return any(config['ihate'][l].get(list) for l in + return any(self.config[l].get(list) for l in ('warn_genre', 'warn_artist', 'warn_album', 'skip_genre', 'skip_artist', 'skip_album')) - def import_task_choice_event(self, task, config): + def import_task_choice_event(self, task): if task.choice_flag == action.APPLY: if self.job_to_do(): self._log.debug('[ihate] processing your hate') if self.do_i_hate_this(task, - config['ihate']['skip_genre'].get(list), - config['ihate']['skip_artist'].get(list), - config['ihate']['skip_album'].get(list), - config['ihate']['skip_whitelist'].get(list)): + self.config['skip_genre'].get(list), + self.config['skip_artist'].get(list), + self.config['skip_album'].get(list), + self.config['skip_whitelist'].get(list)): task.choice_flag = action.SKIP self._log.info(u'[ihate] skipped: {0} - {1}' .format(task.cur_artist, task.cur_album)) return if self.do_i_hate_this(task, - config['ihate']['warn_genre'].get(list), - config['ihate']['warn_artist'].get(list), - config['ihate']['warn_album'].get(list), - config['ihate']['warn_whitelist'].get(list)): + self.config['warn_genre'].get(list), + self.config['warn_artist'].get(list), + self.config['warn_album'].get(list), + self.config['warn_whitelist'].get(list)): self._log.info(u'[ihate] you maybe hate this: {0} - {1}' .format(task.cur_artist, task.cur_album)) else: @@ -126,4 +126,4 @@ class IHatePlugin(BeetsPlugin): @IHatePlugin.listen('import_task_choice') def ihate_import_task_choice(task, session): - IHatePlugin().import_task_choice_event(task, config) + IHatePlugin().import_task_choice_event(task) diff --git a/beetsplug/importfeeds.py b/beetsplug/importfeeds.py index 8c7429cdf..97697480c 100644 --- a/beetsplug/importfeeds.py +++ b/beetsplug/importfeeds.py @@ -25,22 +25,19 @@ from beets import config M3U_DEFAULT_NAME = 'imported.m3u' -config.add({ - 'importfeeds': { - 'formats': [], - 'm3u_name': u'imported.m3u', - 'dir': None, - } -}) - class ImportFeedsPlugin(BeetsPlugin): def __init__(self): super(ImportFeedsPlugin, self).__init__() + + self.config.add({ + 'formats': [], + 'm3u_name': u'imported.m3u', + 'dir': None, + }) - feeds_dir = config['importfeeds']['dir'].get() + feeds_dir = self.config['dir'].get() if feeds_dir: - config['importfeeds']['dir'] = \ - os.path.expanduser(bytestring_path(feeds_dir)) + self.config['dir'] = os.path.expanduser(bytestring_path(feeds_dir)) if not os.path.exists(syspath(feeds_dir)): os.makedirs(syspath(feeds_dir)) diff --git a/beetsplug/inline.py b/beetsplug/inline.py index 2daaf068c..5ac746651 100644 --- a/beetsplug/inline.py +++ b/beetsplug/inline.py @@ -20,10 +20,6 @@ import traceback from beets.plugins import BeetsPlugin from beets import config -config.add({ - 'pathfields': [], -}) - log = logging.getLogger('beets') class InlineError(Exception): @@ -62,6 +58,10 @@ class InlinePlugin(BeetsPlugin): def __init__(self): super(InlinePlugin, self).__init__() + config.add({ + 'pathfields': [], + }) + # Add field expressions. for key, view in config['pathfields'].items(): log.debug(u'adding template field %s' % key) diff --git a/beetsplug/lastgenre/__init__.py b/beetsplug/lastgenre/__init__.py index 890e0f1ba..213e1715f 100644 --- a/beetsplug/lastgenre/__init__.py +++ b/beetsplug/lastgenre/__init__.py @@ -34,14 +34,6 @@ from beets import ui from beets.util import normpath from beets import config -config.add({ - 'lastgenre': { - 'whitelist': os.path.join(os.path.dirname(__file__), 'genres.txt'), - 'fallback': None, - 'canonical': None, - } -}) - log = logging.getLogger('beets') LASTFM = pylast.LastFMNetwork(api_key=plugins.LASTFM_KEY) @@ -138,8 +130,15 @@ class LastGenrePlugin(plugins.BeetsPlugin): super(LastGenrePlugin, self).__init__() self.import_stages = [self.imported] + self.config.add({ + 'whitelist': os.path.join(os.path.dirname(__file__), 'genres.txt'), + 'fallback': None, + 'canonical': None, + }) + + # Read the whitelist file. - wl_filename = config['lastgenre']['whitelist'].as_filename() + wl_filename = self.config['whitelist'].as_filename() whitelist = set() with open(wl_filename) as f: for line in f: @@ -149,7 +148,7 @@ class LastGenrePlugin(plugins.BeetsPlugin): options['whitelist'] = whitelist # Read the genres tree for canonicalization if enabled. - c14n_filename = config['lastgenre']['canonical'].get() + c14n_filename = self.config['canonical'].get() if c14n_filename is not None: c14n_filename = c14n_filename.strip() if not c14n_filename: @@ -164,7 +163,7 @@ class LastGenrePlugin(plugins.BeetsPlugin): def commands(self): lastgenre_cmd = ui.Subcommand('lastgenre', help='fetch genres') - def lastgenre_func(lib, config, opts, args): + def lastgenre_func(lib, opts, args): # The "write to files" option corresponds to the # import_write config value. write = config['import']['write'].get(bool) @@ -177,7 +176,7 @@ class LastGenrePlugin(plugins.BeetsPlugin): tags.extend(_tags_for(lastfm_obj)) genre = _tags_to_genre(tags) - fallback_str = config['lastgenre']['fallback'].get() + fallback_str = self.config['fallback'].get() if not genre and fallback_str != None: genre = fallback_str log.debug(u'no last.fm genre found: fallback to %s' % genre) @@ -207,7 +206,7 @@ class LastGenrePlugin(plugins.BeetsPlugin): tags.extend(_tags_for(lastfm_obj)) genre = _tags_to_genre(tags) - fallback_str = config['lastgenre']['fallback'].get() + fallback_str = self.config['fallback'].get() if not genre and fallback_str != None: genre = fallback_str log.debug(u'no last.fm genre found: fallback to %s' % genre) diff --git a/beetsplug/lyrics.py b/beetsplug/lyrics.py index 1fc7e1572..2ff54d20c 100644 --- a/beetsplug/lyrics.py +++ b/beetsplug/lyrics.py @@ -24,12 +24,6 @@ from beets.plugins import BeetsPlugin from beets import ui from beets import config -config.add({ - 'lyrics': { - 'auto': True, - } -}) - # Global logger. @@ -203,6 +197,9 @@ class LyricsPlugin(BeetsPlugin): def __init__(self): super(LyricsPlugin, self).__init__() self.import_stages = [self.imported] + self.config.add({ + 'auto': True, + }) def commands(self): cmd = ui.Subcommand('lyrics', help='fetch song lyrics') @@ -222,6 +219,6 @@ class LyricsPlugin(BeetsPlugin): # Auto-fetch lyrics on import. def imported(self, session, task): - if config['lyrics']['auto']: + if self.config['auto']: for item in task.imported_items(): fetch_item_lyrics(session.lib, logging.DEBUG, item, False) diff --git a/beetsplug/mpdupdate.py b/beetsplug/mpdupdate.py index 95d828596..5fec9ed35 100644 --- a/beetsplug/mpdupdate.py +++ b/beetsplug/mpdupdate.py @@ -26,14 +26,6 @@ from beets.plugins import BeetsPlugin import socket from beets import config -config.add({ - 'mpdupdate': { - 'host': u'localhost', - 'port': 6600, - 'password': u'', - } -}) - # No need to introduce a dependency on an MPD library for such a # simple use case. Here's a simple socket abstraction to make things # easier. @@ -97,7 +89,13 @@ def update_mpd(host='localhost', port=6600, password=None): print('... updated.') class MPDUpdatePlugin(BeetsPlugin): - pass + def __init__(self): + super(MPDUpdatePlugin, self).__init__() + self.config.add({ + 'host': u'localhost', + 'port': 6600, + 'password': u'', + }) @MPDUpdatePlugin.listen('import') def update(lib=None, paths=None): diff --git a/beetsplug/replaygain.py b/beetsplug/replaygain.py index 2625ec42d..b6b358c2c 100644 --- a/beetsplug/replaygain.py +++ b/beetsplug/replaygain.py @@ -21,18 +21,6 @@ from beets.plugins import BeetsPlugin from beets.util import syspath, command_output from beets import config -config.add({ - 'replaygain': { - 'overwrite': False, - 'albumgain': False, - 'noclip': True, - 'apply_gain': False, - 'targetlevel': 89, - 'auto': True, - 'command': u'', - } -}) - log = logging.getLogger('beets') SAMPLE_MAX = 1 << 15 @@ -79,14 +67,24 @@ class ReplayGainPlugin(BeetsPlugin): super(ReplayGainPlugin, self).__init__() self.import_stages = [self.imported] - self.overwrite = config['replaygain']['overwrite'].get(bool) - self.albumgain = config['replaygain']['albumgain'].get(bool) - self.noclip = config['replaygain']['noclip'].get(bool) - self.apply_gain = config['replaygain']['apply_gain'].get(bool) - target_level = config['replaygain']['targetlevel'].as_number() + self.config.add({ + 'overwrite': False, + 'albumgain': False, + 'noclip': True, + 'apply_gain': False, + 'targetlevel': 89, + 'auto': True, + 'command': u'', + }) + + self.overwrite = self.config['overwrite'].get(bool) + self.albumgain = self.config['albumgain'].get(bool) + self.noclip = self.config['noclip'].get(bool) + self.apply_gain = self.config['apply_gain'].get(bool) + target_level = self.config['targetlevel'].as_number() self.gain_offset = int(target_level - 89) - self.automatic = config['replaygain']['auto'].get(bool) - self.command = config['replaygain']['command'].get(unicode) + self.automatic = self.config['auto'].get(bool) + self.command = self.config['command'].get(unicode) if self.command: # Explicit executable path. diff --git a/beetsplug/rewrite.py b/beetsplug/rewrite.py index 9bbce86dc..ad789ac9b 100644 --- a/beetsplug/rewrite.py +++ b/beetsplug/rewrite.py @@ -24,10 +24,6 @@ from beets import ui from beets import library from beets import config -config.add({ - 'rewrite': {}, -}) - log = logging.getLogger('beets') def rewriter(field, rules): @@ -50,9 +46,11 @@ class RewritePlugin(BeetsPlugin): super(BeetsPlugin, self).__init__() BeetsPlugin.template_fields = {} + self.config.add({}) + # Gather all the rewrite rules for each field. rules = defaultdict(list) - for key, value in config['rewrite'].items(): + for key, value in self.config.items(): try: fieldname, pattern = key.split(None, 1) except ValueError: diff --git a/beetsplug/scrub.py b/beetsplug/scrub.py index 70f639631..7793e8bf6 100644 --- a/beetsplug/scrub.py +++ b/beetsplug/scrub.py @@ -22,12 +22,6 @@ from beets import ui from beets import util from beets import config -config.add({ - 'scrub': { - 'auto': True, - } -}) - log = logging.getLogger('beets') _MUTAGEN_FORMATS = { @@ -50,6 +44,12 @@ scrubbing = False class ScrubPlugin(BeetsPlugin): """Removes extraneous metadata from files' tags.""" + def __init__(self): + super(ScrubPlugin, self).__init__() + self.config.add({ + 'auto': True, + }) + def commands(self): def scrub_func(lib, opts, args): # This is a little bit hacky, but we set a global flag to diff --git a/beetsplug/the.py b/beetsplug/the.py index d26692f7c..dc32e1aa4 100644 --- a/beetsplug/the.py +++ b/beetsplug/the.py @@ -17,18 +17,6 @@ import re import logging from beets.plugins import BeetsPlugin -from beets import config - -config.add({ - 'the': { - 'the': True, - 'a': True, - 'format': u'{0}, {1}', - 'strip': False, - 'patterns': [], - } -}) - __author__ = 'baobab@heresiarch.info' __version__ = '1.1' @@ -57,7 +45,15 @@ class ThePlugin(BeetsPlugin): def __init__(self): super(ThePlugin, self).__init__() - self.patterns = config['the']['patterns'].get(list) + self.config.add({ + 'the': True, + 'a': True, + 'format': u'{0}, {1}', + 'strip': False, + 'patterns': [], + }) + + self.patterns = self.config['patterns'].get(list) for p in self.patterns: if p: try: @@ -68,9 +64,9 @@ class ThePlugin(BeetsPlugin): if not (p.startswith('^') or p.endswith('$')): self._log.warn(u'[the] warning: \"{0}\" will not ' 'match string start/end'.format(p)) - if config['the']['a']: + if self.config['a']: self.patterns = [PATTERN_A] + self.patterns - if config['the']['the']: + if self.config['the']: self.patterns = [PATTERN_THE] + self.patterns if not self.patterns: self._log.warn(u'[the] no patterns defined!') @@ -92,10 +88,10 @@ class ThePlugin(BeetsPlugin): return text else: r = re.sub(r, '', text).strip() - if config['the']['strip']: + if self.config['strip']: return r else: - fmt = config['the']['format'].get(unicode) + fmt = self.config['format'].get(unicode) return fmt.format(r, t.strip()).strip() else: return u'' diff --git a/beetsplug/web/__init__.py b/beetsplug/web/__init__.py index 58fe2191a..04d1fa29b 100644 --- a/beetsplug/web/__init__.py +++ b/beetsplug/web/__init__.py @@ -16,19 +16,11 @@ from beets.plugins import BeetsPlugin from beets import ui from beets import util -from beets import config import beets.library import flask from flask import g import os -config.add({ - 'web': { - 'host': u'', - 'port': 8337, - } -}) - # Utilities. @@ -127,19 +119,26 @@ def home(): # Plugin hook. class WebPlugin(BeetsPlugin): + def __init__(self): + super(WebPlugin, self).__init__() + self.config.add({ + 'host': u'', + 'port': 8337, + }) + def commands(self): cmd = ui.Subcommand('web', help='start a Web interface') cmd.parser.add_option('-d', '--debug', action='store_true', default=False, help='debug mode') def func(lib, opts, args): if args: - config['web']['host'] = args.pop(0) + self.config['host'] = args.pop(0) if args: - config['web']['port'] = int(args.pop(0)) + self.config['port'] = int(args.pop(0)) app.config['lib'] = lib - app.run(host=config['web']['host'].get(unicode), - port=config['web']['port'].get(int), + app.run(host=self.config['host'].get(unicode), + port=self.config['port'].get(int), debug=opts.debug, threaded=True) cmd.func = func return [cmd] diff --git a/beetsplug/zero.py b/beetsplug/zero.py index e3d00f0de..0dc5e228e 100644 --- a/beetsplug/zero.py +++ b/beetsplug/zero.py @@ -19,16 +19,8 @@ import logging from beets.plugins import BeetsPlugin from beets.library import ITEM_KEYS from beets.importer import action -from beets import config from beets.util import confit -config.add({ - 'zero': { - 'fields': [], - } -}) - - __author__ = 'baobab@heresiarch.info' __version__ = '0.10' @@ -47,17 +39,21 @@ class ZeroPlugin(BeetsPlugin): def __init__(self): super(ZeroPlugin, self).__init__() + self.config.add({ + 'fields': [], + }) + self.fields = [] self.patterns = {} self.warned = False - for f in config['zero']['fields'].get(list): + for f in self.config['fields'].get(list): if f not in ITEM_KEYS: self._log.error('[zero] invalid field: {0}'.format(f)) else: self.fields.append(f) try: - self.patterns[f] = config['zero'][f].get(list) + self.patterns[f] = self.config[f].get(list) except confit.NotFoundError: self.patterns[f] = [u'']