plugin the: ver 1.1 - singleton mode, code cleanup

This commit is contained in:
Blemjhoo Tezoulbr 2012-10-05 02:04:51 +03:00
parent a4033faf3b
commit c9fafb8379
3 changed files with 114 additions and 119 deletions

View file

@ -14,76 +14,70 @@
"""Moves patterns in path formats (suitable for moving articles).""" """Moves patterns in path formats (suitable for moving articles)."""
from __future__ import print_function
import sys
import re import re
import logging
from beets.plugins import BeetsPlugin from beets.plugins import BeetsPlugin
from beets import ui from beets import ui
__author__ = 'baobab@heresiarch.info' __author__ = 'baobab@heresiarch.info'
__version__ = '1.0' __version__ = '1.1'
PATTERN_THE = u'^[the]{3}\s' PATTERN_THE = u'^[the]{3}\s'
PATTERN_A = u'^[a][n]?\s' PATTERN_A = u'^[a][n]?\s'
FORMAT = u'{0}, {1}' FORMAT = u'{0}, {1}'
the_options = {
'debug': False,
'the': True,
'a': True,
'format': FORMAT,
'strip': False,
'silent': False,
'patterns': [PATTERN_THE, PATTERN_A],
}
class ThePlugin(BeetsPlugin): class ThePlugin(BeetsPlugin):
_instance = None
_log = logging.getLogger('beets')
the = True
a = True
format = u''
strip = False
patterns = []
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super(ThePlugin,
cls).__new__(cls, *args, **kwargs)
return cls._instance
def __str__(self):
return ('[the]\n the = {0}\n a = {1}\n format = {2}\n'
' strip = {3}\n patterns = {4}'
.format(self.the, self.a, self.format, self.strip,
self.patterns))
def configure(self, config): def configure(self, config):
if not config.has_section('the'): if not config.has_section('the'):
print('[the] plugin is not configured, using defaults', self._log.warn(u'[the] plugin is not configured, using defaults')
file=sys.stderr)
return return
self.in_config = True self.the = ui.config_val(config, 'the', 'the', True, bool)
the_options['debug'] = ui.config_val(config, 'the', 'debug', False, self.a = ui.config_val(config, 'the', 'a', True, bool)
bool) self.format = ui.config_val(config, 'the', 'format', FORMAT)
the_options['the'] = ui.config_val(config, 'the', 'the', True, bool) self.strip = ui.config_val(config, 'the', 'strip', False, bool)
the_options['a'] = ui.config_val(config, 'the', 'a', True, bool) self.patterns = ui.config_val(config, 'the', 'patterns', '').split()
the_options['format'] = ui.config_val(config, 'the', 'format', for p in self.patterns:
FORMAT)
the_options['strip'] = ui.config_val(config, 'the', 'strip', False,
bool)
the_options['silent'] = ui.config_val(config, 'the', 'silent', False,
bool)
the_options['patterns'] = ui.config_val(config, 'the', 'patterns',
'').split()
for p in the_options['patterns']:
if p: if p:
try: try:
re.compile(p) re.compile(p)
except re.error: except re.error:
print(u'[the] invalid pattern: {0}'.format(p), self._log.error(u'[the] invalid pattern: {0}'.format(p))
file=sys.stderr)
else: else:
if not (p.startswith('^') or p.endswith('$')): if not (p.startswith('^') or p.endswith('$')):
if not the_options['silent']: self._log.warn(u'[the] warning: \"{0}\" will not '
print(u'[the] warning: pattern \"{0}\" will not ' 'match string start/end'.format(p))
'match string start/end'.format(p), if self.a:
file=sys.stderr) self.patterns = [PATTERN_A] + self.patterns
if the_options['a']: if self.the:
the_options['patterns'] = [PATTERN_A] + the_options['patterns'] self.patterns = [PATTERN_THE] + self.patterns
if the_options['the']: if not self.patterns:
the_options['patterns'] = [PATTERN_THE] + the_options['patterns'] self._log.warn(u'[the] no patterns defined!')
if not the_options['patterns'] and not the_options['silent']:
print('[the] no patterns defined!')
if the_options['debug']:
print(u'[the] patterns: {0}'
.format(' '.join(the_options['patterns'])), file=sys.stderr)
def unthe(text, pattern, strip=False): def unthe(self, text, pattern):
"""Moves pattern in the path format string or strips it """Moves pattern in the path format string or strips it
text -- text to handle text -- text to handle
@ -99,33 +93,27 @@ def unthe(text, pattern, strip=False):
return text return text
else: else:
r = re.sub(r, '', text).strip() r = re.sub(r, '', text).strip()
if strip: if self.strip:
return r return r
else: else:
return the_options['format'].format(r, t.strip()).strip() return self.format.format(r, t.strip()).strip()
else: else:
return u'' return u''
def the_template_func(self, text):
if not self.patterns:
return text
if text:
for p in self.patterns:
r = self.unthe(text, p)
if r != text:
break
self._log.debug(u'[the] \"{0}\" -> \"{1}\"'.format(text, r))
return r
else:
return u''
@ThePlugin.template_func('the') @ThePlugin.template_func('the')
def func_the(text): def func_the(text):
"""Provides beets template function %the""" """Provides beets template function %the"""
if not the_options['patterns']: return ThePlugin().the_template_func(text)
return text
if text:
for p in the_options['patterns']:
r = unthe(text, p, the_options['strip'])
if r != text:
break
if the_options['debug']:
print(u'[the] \"{0}\" -> \"{1}\"'.format(text, r), file=sys.stderr)
return r
else:
return u''
# simple tests
if __name__ == '__main__':
print(unthe('The The', PATTERN_THE))
print(unthe('An Apple', PATTERN_A))
print(unthe('A Girl', PATTERN_A, strip=True))

View file

@ -36,8 +36,6 @@ can add plugin section into config file::
format={0}, {1} format={0}, {1}
# strip instead of moving to the end, default is off # strip instead of moving to the end, default is off
strip=no strip=no
# do not print warnings, default is off
silent=no
# custom regexp patterns, separated by space # custom regexp patterns, separated by space
patterns= patterns=

View file

@ -1,48 +1,57 @@
"""Tests for the 'the' plugin""" """Tests for the 'the' plugin"""
from _common import unittest from _common import unittest
from beetsplug import the from beetsplug.the import ThePlugin, PATTERN_A, PATTERN_THE, FORMAT
class ThePluginTest(unittest.TestCase): class ThePluginTest(unittest.TestCase):
def test_unthe_with_default_patterns(self): def test_unthe_with_default_patterns(self):
self.assertEqual(the.unthe('', the.PATTERN_THE), '') self.assertEqual(ThePlugin().unthe('', PATTERN_THE), '')
self.assertEqual(the.unthe('The Something', the.PATTERN_THE), self.assertEqual(ThePlugin().unthe('The Something', PATTERN_THE),
'Something, The') 'Something, The')
self.assertEqual(the.unthe('The The', the.PATTERN_THE), 'The, The') self.assertEqual(ThePlugin().unthe('The The', PATTERN_THE),
self.assertEqual(the.unthe('The The', the.PATTERN_THE), 'The, The') 'The, The')
self.assertEqual(the.unthe('The The X', the.PATTERN_THE), self.assertEqual(ThePlugin().unthe('The The', PATTERN_THE),
u'The X, The') 'The, The')
self.assertEqual(the.unthe('the The', the.PATTERN_THE), 'The, the') self.assertEqual(ThePlugin().unthe('The The X', PATTERN_THE),
self.assertEqual(the.unthe('Protected The', the.PATTERN_THE), 'The X, The')
self.assertEqual(ThePlugin().unthe('the The', PATTERN_THE),
'The, the')
self.assertEqual(ThePlugin().unthe('Protected The', PATTERN_THE),
'Protected The') 'Protected The')
self.assertEqual(the.unthe('A Boy', the.PATTERN_A), 'Boy, A') self.assertEqual(ThePlugin().unthe('A Boy', PATTERN_A),
self.assertEqual(the.unthe('a girl', the.PATTERN_A), 'girl, a') 'Boy, A')
self.assertEqual(the.unthe('An Apple', the.PATTERN_A), 'Apple, An') self.assertEqual(ThePlugin().unthe('a girl', PATTERN_A),
self.assertEqual(the.unthe('An A Thing', the.PATTERN_A), 'A Thing, An') 'girl, a')
self.assertEqual(the.unthe('the An Arse', the.PATTERN_A), self.assertEqual(ThePlugin().unthe('An Apple', PATTERN_A),
'Apple, An')
self.assertEqual(ThePlugin().unthe('An A Thing', PATTERN_A),
'A Thing, An')
self.assertEqual(ThePlugin().unthe('the An Arse', PATTERN_A),
'the An Arse') 'the An Arse')
self.assertEqual(the.unthe('The Something', the.PATTERN_THE, ThePlugin().strip = True
strip=True), 'Something') self.assertEqual(ThePlugin().unthe('The Something', PATTERN_THE),
self.assertEqual(the.unthe('An A', the.PATTERN_A, strip=True), 'A') 'Something')
self.assertEqual(ThePlugin().unthe('An A', PATTERN_A), 'A')
ThePlugin().strip = False
def test_template_function_with_defaults(self): def test_template_function_with_defaults(self):
the.the_options['patterns'] = [the.PATTERN_THE, the.PATTERN_A] ThePlugin().patterns = [PATTERN_THE, PATTERN_A]
the.the_options['format'] = the.FORMAT ThePlugin().format = FORMAT
self.assertEqual(the.func_the('The The'), 'The, The') self.assertEqual(ThePlugin().the_template_func('The The'), 'The, The')
self.assertEqual(the.func_the('An A'), 'A, An') self.assertEqual(ThePlugin().the_template_func('An A'), 'A, An')
def test_custom_pattern(self): def test_custom_pattern(self):
the.the_options['patterns'] = [ u'^test\s'] ThePlugin().patterns = [ u'^test\s']
the.the_options['format'] = the.FORMAT ThePlugin().format = FORMAT
self.assertEqual(the.func_the('test passed'), 'passed, test') self.assertEqual(ThePlugin().the_template_func('test passed'),
'passed, test')
def test_custom_format(self): def test_custom_format(self):
the.the_options['patterns'] = [the.PATTERN_THE, the.PATTERN_A] ThePlugin().patterns = [PATTERN_THE, PATTERN_A]
the.the_options['format'] = '{1} ({0})' ThePlugin().format = '{1} ({0})'
self.assertEqual(the.func_the('The A'), 'The (A)') self.assertEqual(ThePlugin().the_template_func('The A'), 'The (A)')
def suite(): def suite():