Skip to content

Commit

Permalink
Merge branch 'issue/18-19-20'
Browse files Browse the repository at this point in the history
  • Loading branch information
snejus committed Sep 13, 2021
2 parents be48e05 + a80619c commit ea7ebeb
Show file tree
Hide file tree
Showing 11 changed files with 910 additions and 92 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,12 @@ jobs:
- name: Pytest
run: |
poetry run pytest
poetry run coverage xml
- name: Flake8
run: poetry run flake8 . --output-file flake.log --exit-zero
- name: Pylint
run: poetry run pylint --output pylint.log --exit-zero beetsplug/**/*.py
- name: SonarCloud Scan
uses: sonarsource/sonarcloud-github-action@master
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
## [0.10.1] 2021-09-13

### Fixed

- Fixed #18 by handling cases when a track duration is not given.
- Fixed #19 where artist names like **SUNN O)))** would get incorrectly mistreated by
the album name cleanup logic due to multiple consecutive parentheses. The fix involved
adding some rules around it: they are now deduped _only if_

- they are preceded with a space
- or they enclose remix / edit info and are the last characters in the album name

- Fixed #20 where dynamically obtained label names used in further REs caused `re.error`
since they were not appropriately escaped (for example, `label: /m\ records`).

Thanks @arogl for reporting each of the above!

- `album`: Keep label in the album name if it's immediately followed by an apostrophe. An
example scenario:
- `label: Mike`
- `album: Mike's Creations`

[0.10.1]: https://github.com/snejus/beetcamp/releases/tag/0.10.1

## [0.10.0] 2021-09-10

### Fixed
Expand Down Expand Up @@ -47,6 +71,7 @@
- Improved the way **Various Artists** are cleaned up when catalognum is available

- `albumartist`:

- If **various** is specified as the albumartist, make it **Various Artists**
- When the label have set their name as the albumartist in every field, and if the
actual albumartist could be inferred from the album name, use the inferred name.
Expand Down
4 changes: 2 additions & 2 deletions beetsplug/bandcamp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
from beets import __version__, config, library, plugins
from beets.autotag.hooks import AlbumInfo, TrackInfo
from beets.importer import ImportTask
from beetsplug import fetchart
from beetsplug import fetchart # type: ignore[attr-defined]

from ._metaguru import DATA_SOURCE, DEFAULT_MEDIA, Metaguru, urlify

Expand Down Expand Up @@ -266,7 +266,7 @@ def handle(self, guru: Metaguru, attr: str, _id: str) -> Any:
except (KeyError, ValueError, AttributeError):
self._info("Failed obtaining {}", _id)
return None
except Exception:
except Exception: # pylint: disable=broad-except
url = "https://github.com/snejus/beetcamp/issues/new"
self._exc("Unexpected error obtaining {}, please report at {}", _id, url)
return None
Expand Down
33 changes: 23 additions & 10 deletions beetsplug/bandcamp/_metaguru.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,10 @@ def parse_track_name(name: str, catalognum: str = "") -> Dict[str, Optional[str]
track["track_alt"] = track_alt
name = name.replace(track_alt, "")

# do not strip a period from the end since it could end with an abbrev
name = name.lstrip(".")
# in most cases that's the delimiter between the artist and the title
parts = re.split(r"\s-\s|\s?-\s|\s-\s?", name.strip(",.- "))
parts = re.split(r"\s-\s|\s?-\s|\s-\s?", name.strip(",- "))

# title is always given
track["title"] = parts.pop(-1)
Expand Down Expand Up @@ -134,28 +136,36 @@ def parse_catalognum(album: str, disctitle: str, description: str, label: str) -
3. Check whether label name is followed by numbers
4. Check album name and disctitle using more flexible rules.
"""
label_excl: Tuple[Optional[Pattern], Optional[str]] = (None, None)
if label:
escaped = re.escape(label)
label_excl = (re.compile(rf"({escaped}\s?[0-9]+)"), album)

for pattern, source in [
(PATTERNS["desc_catalognum"], description),
(PATTERNS["quick_catalognum"], album),
(rf"({label}\s?[0-9]+)", album) if label else (None, None),
label_excl,
(PATTERNS["catalognum"], album),
(PATTERNS["catalognum"], disctitle),
]:
if not pattern:
continue

match = re.search(pattern, re.sub(PATTERNS["catalognum_excl"], "", source))
match = pattern.search(PATTERNS["catalognum_excl"].sub("", source))
if match:
return match.groups()[0]
return ""

@staticmethod
def get_duration(source: JSONDict) -> int:
return [
floor(x.get("value", 0))
prop = [
x.get("value") or 0
for x in source.get("additionalProperty", [])
if x.get("name") == "duration_secs"
][0]
]
if len(prop) == 1:
return floor(prop[0])
return 0

@staticmethod
def clean_name(name: str, *args: str, remove_extra: bool = False) -> str:
Expand All @@ -167,13 +177,16 @@ def clean_name(name: str, *args: str, remove_extra: bool = False) -> str:
"""
# catalognum, album, albumartist
for arg in args:
name = name.replace(arg, "")
arg = re.escape(arg)
name = re.sub(rf"{arg}((?=[^'])|$)", "", name)

# redundant spaces, duoble quotes, parentheses
for pat, repl in [
(r"\s\s+", " "),
(r"\(\s+|(- )?\(+", "("),
(r"\s+\)|\)+", ")"),
# Remove duplicate closing parens if they follow a space
# or enclose mix/edit info and are at the end
(r" \)+|(?<=(?i:.mix|edit))\)+$", ")"),
(r'"', ""),
]:
name = re.sub(pat, repl, name)
Expand Down Expand Up @@ -206,7 +219,7 @@ def clean_name(name: str, *args: str, remove_extra: bool = False) -> str:
def clean(patstr: str, text: str) -> str:
return re.sub(patstr, "", text)

return clean(empty_parens, clean(rubbish, name)).strip("/-|([. ") or default
return clean(empty_parens, clean(rubbish, name)).strip("/-|([ ") or default

@staticmethod
def _get_media_index(meta: JSONDict) -> JSONDict:
Expand Down Expand Up @@ -393,7 +406,7 @@ def tracks(self) -> List[JSONDict]:
index=index,
medium_index=index,
track_id=raw_item.get("@id"),
length=self.get_duration(raw_item),
length=self.get_duration(raw_item) or None,
**self.parse_track_name(name, catalognum),
)
track["artist"] = self.get_track_artist(
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "beetcamp"
version = "0.10.0"
version = "0.10.1"
description = "Bandcamp autotagger source for beets (http://beets.io)."
authors = ["Šarūnas Nejus <[email protected]>"]
readme = "README.md"
Expand Down
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ addopts =

markers =
need_connection: end-to-end tests that require internet connection
jsons: tests that compare parsed releases with json fixtures
parsing: parsing tests

testpaths =
Expand Down
62 changes: 62 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -690,3 +690,65 @@ def edge_cases() -> ReleaseInfo:
mediums=1,
)
return info


@pytest.fixture
def issues_18() -> ReleaseInfo:
albumartist = "General Dicon"
info = ReleaseInfo(
artist_id="https://54thregiment.bandcamp.com",
album_id="https://54thregiment.bandcamp.com/album/fall-in",
media="Digital Media",
disctitle=None,
)
tracks = [
("54-regi", albumartist, "54 regi", None, None),
("54-regi-2", albumartist, "54 regi", 227, None),
(
"mile-high-monsta-ft-nation",
albumartist,
"Mile high monsta ft.nation",
157,
None,
),
("pure-entertainment", albumartist, "Pure entertainment", 166, None),
("smoke-interlude", albumartist, "Smoke interlude", 69, None),
(
"ganja-tune-ft-spellbinder",
albumartist,
"Ganja tune ft.spellbinder",
235,
None,
),
("war-ft-spellbinder", albumartist, "War ft.spellbinder", 203, None),
(
"w-m-m-a-where-my-money-ft-spellbinder",
albumartist,
"w.m.m.a(where my money @) ft.Spellbinder",
147,
None,
),
("due-time", albumartist, "Due time", 257, None),
("hustle-aint-no-game", albumartist, "Hustle Ain't no game", 197, None),
(
"its-ova-ft-scrilla-scratch",
albumartist,
"It's ova ft. scrilla scratch",
201,
None,
),
("dont-stop-ft-spellbinder", albumartist, "Don't stop ft.Spellbinder", 244, None),
]
info.set_albuminfo(
tracks,
album="FALL IN",
albumartist=albumartist,
albumtype="album",
catalognum="",
label="54th Regiment",
release_date=date(2011, 4, 20),
va=False,
country="US",
mediums=1,
)
return info
Loading

0 comments on commit ea7ebeb

Please sign in to comment.