mirror of
https://github.com/beetbox/beets.git
synced 2025-12-06 16:42:42 +01:00
plugin the: ver 1.1 - singleton mode, code cleanup
This commit is contained in:
parent
a4033faf3b
commit
c9fafb8379
3 changed files with 114 additions and 119 deletions
122
beetsplug/the.py
122
beetsplug/the.py
|
|
@ -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))
|
|
||||||
|
|
|
||||||
|
|
@ -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=
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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():
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue