Skip to content

Commit

Permalink
Fix error when replaceable field missing
Browse files Browse the repository at this point in the history
  • Loading branch information
edgars-supe committed Sep 9, 2021
1 parent 894681c commit 0f6e78b
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 22 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Changelog

### 0.1.1 (2021-09-09)

* Fixed issue when attempting to replace a missing field.

### 0.1 (2021-09-08)

* Initial release.
2 changes: 1 addition & 1 deletion beetsplug/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
__path__ = extend_path(__path__, __name__)
44 changes: 24 additions & 20 deletions beetsplug/importreplace.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,40 @@


class ImportReplace(BeetsPlugin):
item_fields = set()
album_fields = set()
replacements = []
_item_fields = set()
_album_fields = set()
_replacements = []

def __init__(self):
super(ImportReplace, self).__init__()
self.item_fields = self.config['item_fields'].as_str_seq()
self.album_fields = self.config['album_fields'].as_str_seq()
self._item_fields = self.config['item_fields'].as_str_seq()
self._album_fields = self.config['album_fields'].as_str_seq()
for pattern, repl in self.config['replace'].get(dict).items():
repl = repl or ''
self.replacements.append((re.compile(pattern), repl))
self.register_listener('trackinfo_received', self.trackinfo_received)
self.register_listener('albuminfo_received', self.albuminfo_received)
self._replacements.append((re.compile(pattern), repl))
self.register_listener('trackinfo_received', self._trackinfo_received)
self.register_listener('albuminfo_received', self._albuminfo_received)

def trackinfo_received(self, info: TrackInfo):
for field in self.item_fields:
def _trackinfo_received(self, info: TrackInfo):
for field in self._item_fields:
if field in info:
replaced = self.replace_field(info.__getattr__(field))
info.__setattr__(field, replaced)
value = info.__getattr__(field)
if value:
replaced = self._replace_field(value)
info.__setattr__(field, replaced)

def albuminfo_received(self, info: AlbumInfo):
for field in self.album_fields:
def _albuminfo_received(self, info: AlbumInfo):
for field in self._album_fields:
if field in info:
replaced = self.replace_field(info.__getattr__(field))
info.__setattr__(field, replaced)
value = info.__getattr__(field)
if value:
replaced = self._replace_field(value)
info.__setattr__(field, replaced)
for track in info.tracks:
self.trackinfo_received(track)
self._trackinfo_received(track)

def replace_field(self, text: str) -> str:
return reduce(self.replace, self.replacements, text)
def _replace_field(self, text: str) -> str:
return reduce(self._replace, self._replacements, text)

def replace(self, text: str, replacement: (Pattern, str)) -> str:
def _replace(self, text: str, replacement: (Pattern, str)) -> str:
return replacement[0].sub(repl=replacement[1], string=text)
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

setup(
name='beets-importreplace',
version='0.1',
version='0.1.1',
description='beets plugin to perform replacements on import metadata',
long_description=open('README.md').read(),
author='Edgars Supe',
Expand Down
56 changes: 56 additions & 0 deletions tests/test_importreplace.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import unittest

import beets as beets
from beets.autotag.hooks import AlbumInfo
from beets.autotag.hooks import TrackInfo
from beetsplug.importreplace import ImportReplace


class ImportReplaceTest(unittest.TestCase):

def _create_track_info(self, title: str = None, artist: str = None,
artist_sort: str = None, artist_credit: str = None):
return TrackInfo(title=title, artist=artist, artist_sort=artist_sort,
artist_credit=artist_credit)

def _create_album_info(self, tracks: [TrackInfo] = None, album: str = None,
artist: str = None, artist_sort: str = None,
artist_credit: str = None):
return AlbumInfo(tracks=tracks or [], album=album, artist=artist,
artist_sort=artist_sort, artist_credit=artist_credit)

def _set_config(self, item_fields: [str], album_fields: [str],
replace: {str: str}):
beets.config['importreplace']['item_fields'] = item_fields
beets.config['importreplace']['album_fields'] = album_fields
beets.config['importreplace']['replace'] = replace

def test_replaces_only_config_fields(self):
"""Check if plugin replaces text in only the specified fields"""
self._set_config(item_fields=['title'], album_fields=['album'],
replace={'a': 'x'})
tracks = [self._create_track_info(title='Fao', artist='Bar')]
album_info = self._create_album_info(tracks=tracks, album='albumTest',
artist='Bar')
subject = ImportReplace()
subject._albuminfo_received(album_info)
self.assertEqual(album_info.album, 'xlbumTest')
self.assertEqual(album_info.artist, 'Bar')
self.assertEqual(album_info.tracks[0].title, 'Fxo')
self.assertEqual(album_info.tracks[0].artist, 'Bar')

def test_handles_empty_fields(self):
"""Verify that plugin works when field marked for replacement
is absent"""
self._set_config(item_fields=['title', 'artist'],
album_fields=['album', 'artist'],
replace={'a': 'x'})
tracks = [self._create_track_info(title='Fao', artist=None)]
album_info = self._create_album_info(tracks=tracks, album='albumTest',
artist=None)
subject = ImportReplace()
subject._albuminfo_received(album_info)
self.assertEqual(album_info.album, 'xlbumTest')
self.assertEqual(album_info.artist, None)
self.assertEqual(album_info.tracks[0].title, 'Fxo')
self.assertEqual(album_info.tracks[0].artist, None)

0 comments on commit 0f6e78b

Please sign in to comment.