mirror of
https://github.com/beetbox/beets.git
synced 2026-02-17 04:43:40 +01:00
Refactory discovery and add basename prop
This commit is contained in:
parent
1a630908c9
commit
db6e32b3e4
2 changed files with 82 additions and 40 deletions
|
|
@ -148,6 +148,19 @@ class Attachment(dbcore.db.Model):
|
|||
def path(self, value):
|
||||
self['path'] = normpath(value)
|
||||
|
||||
@property
|
||||
def basename(self):
|
||||
# TODO doc
|
||||
if self.ref_type == 'item':
|
||||
prefix = os.path.splitext(self.entity.path)[0]
|
||||
# FIXME circular dependency
|
||||
from beets import config
|
||||
for sep in config['attachment']['track separators'].get(list):
|
||||
if self.path.startswith(prefix + sep):
|
||||
return self.path[(len(prefix) + len(sep)):]
|
||||
|
||||
return os.path.basename(self.path)
|
||||
|
||||
@property
|
||||
def destination(self):
|
||||
template = self._destination_template()
|
||||
|
|
@ -224,7 +237,10 @@ class DestinationTemplateMapping(collections.Mapping):
|
|||
if self.attachment.ref_type == 'album':
|
||||
return self['entity_dir']
|
||||
elif self.attachment.ref_type == 'item':
|
||||
return self['track_base'] + ' - '
|
||||
# FIXME circular dependency
|
||||
from beets import config
|
||||
separator = config['attachment']['track separators'].get(list)[0]
|
||||
return self['track_base'] + separator
|
||||
|
||||
@property
|
||||
def ext_prefix(self):
|
||||
|
|
@ -263,9 +279,9 @@ class DestinationTemplateMapping(collections.Mapping):
|
|||
|
||||
@property
|
||||
def basename(self):
|
||||
"""Filename of the attachment's path in its parent directory.
|
||||
"""See `attachment.basename`
|
||||
"""
|
||||
return os.path.basename(self.attachment.path)
|
||||
return self.attachment.basename
|
||||
|
||||
@property
|
||||
def ext(self):
|
||||
|
|
@ -351,7 +367,7 @@ class AttachmentFactory(object):
|
|||
for type in self._detect_types(path):
|
||||
yield self.create(path, type, entity)
|
||||
|
||||
def discover(self, entity, local=None):
|
||||
def discover(self, entity_or_prefix, local=None):
|
||||
"""Return a list of non-audio files whose path start with the
|
||||
entity prefix.
|
||||
|
||||
|
|
@ -364,45 +380,55 @@ class AttachmentFactory(object):
|
|||
type. For albums the only separator is the directory separator.
|
||||
For items the separtors are configured by `attachments.item_sep`
|
||||
"""
|
||||
prefix, dir = self.path_prefix(entity_or_prefix)
|
||||
if local is None:
|
||||
return self._discover_full(entity)
|
||||
return self._discover_full(prefix, dir)
|
||||
else:
|
||||
return self._discover_local(entity, local)
|
||||
return self._discover_local(prefix, local)
|
||||
|
||||
def _discover_full(self, entity):
|
||||
if ref_type(entity) == 'album':
|
||||
entity_dir = entity.item_dir()
|
||||
entity_prefix = entity_dir
|
||||
else:
|
||||
entity_dir = os.path.dirname(entity.path)
|
||||
entity_prefix = os.path.splitext(entity.path)[0]
|
||||
def path_prefix(self, entity_or_prefix):
|
||||
# TODO doc
|
||||
if isinstance(entity_or_prefix, basestring):
|
||||
if os.path.isdir(entity_or_prefix):
|
||||
dir = entity_or_prefix
|
||||
prefix = dir
|
||||
else:
|
||||
prefix = os.path.splitext(entity_or_prefix)[0]
|
||||
dir = os.path.dirname(prefix)
|
||||
elif ref_type(entity_or_prefix) == 'album':
|
||||
dir = entity_or_prefix.item_dir()
|
||||
prefix = dir
|
||||
else: # entity is track
|
||||
prefix = os.path.splitext(entity_or_prefix.path)[0]
|
||||
dir = os.path.dirname(prefix)
|
||||
return (prefix, dir)
|
||||
|
||||
def _discover_full(self, prefix, dir):
|
||||
discovered = []
|
||||
for dirpath, dirnames, filenames in os.walk(entity_dir):
|
||||
for dirpath, dirnames, filenames in os.walk(dir):
|
||||
for dirname in dirnames:
|
||||
path = os.path.join(dirpath, dirname)
|
||||
if not path.startswith(entity_prefix):
|
||||
if not path.startswith(prefix):
|
||||
dirnames.remove(dirname)
|
||||
|
||||
for filename in filenames:
|
||||
path = os.path.join(dirpath, filename)
|
||||
ext = os.path.splitext(path)[1].lower()
|
||||
if path.startswith(entity_prefix) \
|
||||
and ext not in AUDIO_EXTENSIONS:
|
||||
if path.startswith(prefix) and ext not in AUDIO_EXTENSIONS:
|
||||
discovered.append(path)
|
||||
return discovered
|
||||
|
||||
def _discover_local(self, entity, local):
|
||||
if ref_type(entity) == 'album':
|
||||
seps = [os.sep]
|
||||
entity_prefix = entity.item_dir()
|
||||
else:
|
||||
# TODO make this configurable
|
||||
seps = [os.sep, ' - ', '', ' ', '-', '_', '.']
|
||||
entity_prefix = os.path.splitext(entity.path)[0]
|
||||
|
||||
def _discover_local(self, prefix, local):
|
||||
# FIXME circular dependency
|
||||
from beets import config
|
||||
# TODO add this to config_default.yaml
|
||||
# config['attachment']['track separators'] = \
|
||||
# [os.sep, ' - ', '', ' ', '-', '_', '.']
|
||||
seps = config['attachment']['track separators'].get(list)
|
||||
if local[0] == '.':
|
||||
seps.append('')
|
||||
for sep in seps:
|
||||
path = entity_prefix + sep + local
|
||||
path = prefix + sep + local
|
||||
if os.path.isfile(path):
|
||||
return [path]
|
||||
return []
|
||||
|
|
|
|||
|
|
@ -28,7 +28,10 @@ class AttachmentTestHelper(TestHelper):
|
|||
|
||||
def setup_beets(self):
|
||||
super(AttachmentTestHelper, self).setup_beets()
|
||||
# TODO this comes into default config
|
||||
self.config['attachment']['paths'] = ['${entity_prefix}${basename}']
|
||||
self.config['attachment']['track separators'] = \
|
||||
[' - ', ' ', '-', '_', '.', os.sep]
|
||||
|
||||
@property
|
||||
def factory(self):
|
||||
|
|
@ -87,6 +90,21 @@ class AttachmentTestHelper(TestHelper):
|
|||
self.lib.add(attachment)
|
||||
return attachment
|
||||
|
||||
def add_attachment_plugin(self, ext, meta={}):
|
||||
def ext_detector(path):
|
||||
if path.endswith('.' + ext):
|
||||
return ext
|
||||
def collector(type, path):
|
||||
if type == ext:
|
||||
return meta
|
||||
log_plugin = BeetsPlugin()
|
||||
log_plugin.attachment_detector = ext_detector
|
||||
log_plugin.attachment_collector = collector
|
||||
self.add_plugin(log_plugin)
|
||||
|
||||
def runcli(self, *args):
|
||||
beets.ui._raw_main(list(args), self.lib)
|
||||
|
||||
|
||||
class AttachmentDestinationTest(unittest.TestCase, AttachmentTestHelper):
|
||||
"""Test the `attachment.destination` property.
|
||||
|
|
@ -187,6 +205,17 @@ class AttachmentDestinationTest(unittest.TestCase, AttachmentTestHelper):
|
|||
self.assertEqual(attachment.destination,
|
||||
'/the/track/path.jpg')
|
||||
|
||||
def test_item_basename(self):
|
||||
self.set_path_template('$basename')
|
||||
self.config['attachment']['track separators'] = ['--']
|
||||
attachment = self.create_item_attachment(
|
||||
'/a.ext',
|
||||
track_path='/track.mp3'
|
||||
)
|
||||
self.assertEqual('/track--a.ext', attachment.destination)
|
||||
attachment.path = attachment.destination
|
||||
self.assertEqual('/track--a.ext', attachment.destination)
|
||||
|
||||
# Helper
|
||||
|
||||
def set_path_template(self, *templates):
|
||||
|
|
@ -594,19 +623,6 @@ class AttachCommandTest(unittest.TestCase, AttachmentTestHelper):
|
|||
def test_interactive_type(self):
|
||||
self.skipTest('not implemented yet')
|
||||
|
||||
# Helpers
|
||||
|
||||
def runcli(self, *args):
|
||||
beets.ui._raw_main(list(args), self.lib)
|
||||
|
||||
def add_attachment_plugin(self, ext):
|
||||
def ext_detector(path):
|
||||
if path.endswith('.' + ext):
|
||||
return ext
|
||||
log_plugin = BeetsPlugin()
|
||||
log_plugin.attachment_detector = ext_detector
|
||||
self.add_plugin(log_plugin)
|
||||
|
||||
|
||||
def suite():
|
||||
return unittest.TestLoader().loadTestsFromName(__name__)
|
||||
|
|
|
|||
Loading…
Reference in a new issue