Skip to content

Commit

Permalink
everything working
Browse files Browse the repository at this point in the history
  • Loading branch information
azuline committed Apr 26, 2024
1 parent e185605 commit 7965ebe
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 11 deletions.
13 changes: 8 additions & 5 deletions docs/METADATA_TOOLS.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ genres = [
"Dance-Pop",
"Future Bass",
]
secondary_genres = [
secondarygenres = [
"Electropop",
"Alternative R&B",
"Synthpop",
Expand Down Expand Up @@ -320,15 +320,18 @@ The rules engine supports matching and acting on the following tags:
- `originalyear`
- `compositionyear`
- `genre`
- `secondary_genre`
- `parentgenre`
- `secondarygenre`
- `parentsecondarygenre`
- `descriptor`
- `label`
- `catalognumber`
- `edition`

The `trackartist[*]`, `releaseartist[*]`, `genre`, `secondary_genre`, `descriptor`, and `label` tags
are _multi-value_ tags, which have a slightly different behavior from single-value tags for some of
the actions. We'll explore this difference in the [Actions](#actions) section.
The `trackartist[*]`, `releaseartist[*]`, `genre` (& parents), `secondarygenre` (& parents),
`descriptor`, and `label` tags are _multi-value_ tags, which have a slightly different behavior from
single-value tags for some of the actions. We'll explore this difference in the [Actions](#actions)
section.

For convenience, the rules parser also allows you to specify _tag aliases_ in
place of the above tags, which expand to multiple tags when matching. The
Expand Down
2 changes: 1 addition & 1 deletion docs/TAGGING_CONVENTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ world, Rosé will support reading from additional fields.
| Release Artists | `aART` | |
| Release Type | `----:com.apple.iTunes:RELEASETYPE` | `----:com.apple.iTunes:MusicBrainz Album Type` |
| Release Year | `\xa9day` | |
| Original Year | `----:net.sunsetglow.rose:ORIGINALDATE` | `----:com.apple.iTunes:ORIGINALDATE`, `----:com.apple.iTunes:ORIGINALYEAR` |
| Original Year | `----:net.sunsetglow.rose:ORIGINALDATE` | `----:com.apple.iTunes:ORIGINALDATE`, `----:com.apple.iTunes:ORIGINALYEAR` |
| Composition Year | `----:net.sunsetglow.rose:COMPOSITIONDATE` | |
| Genre | `\xa9gen` | |
| Secondary Genre | `----:net.sunsetglow.rose:SECONDARYGENRE` | |
Expand Down
18 changes: 18 additions & 0 deletions rose/rule_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,13 @@ def __str__(self) -> str:
"releaseartist[djmixer]",
"releasetype",
"releaseyear",
"originalyear",
"compositionyear",
"catalognumber",
"edition",
"genre",
"secondarygenre",
"descriptor",
"label",
]

Expand Down Expand Up @@ -115,9 +119,13 @@ def __str__(self) -> str:
"releaseartist[djmixer]": ["releaseartist[djmixer]"],
"releasetype": ["releasetype"],
"releaseyear": ["releaseyear"],
"originalyear": ["originalyear"],
"compositionyear": ["compositionyear"],
"edition": ["edition"],
"catalognumber": ["catalognumber"],
"genre": ["genre"],
"secondarygenre": ["secondarygenre"],
"descriptor": ["descriptor"],
"label": ["label"],
"artist": [
"trackartist[main]",
Expand Down Expand Up @@ -158,9 +166,13 @@ def __str__(self) -> str:
"releaseartist[djmixer]",
"releasetype",
"releaseyear",
"originalyear",
"compositionyear",
"edition",
"catalognumber",
"genre",
"secondarygenre",
"descriptor",
"label",
]

Expand All @@ -173,7 +185,9 @@ def __str__(self) -> str:
"releasetitle",
"releasetype",
"releaseyear",
"originalyear",
"compositionyear",
"edition",
"catalognumber",
]

Expand All @@ -189,9 +203,13 @@ def __str__(self) -> str:
"releasetype",
"releasetype",
"releaseyear",
"originalyear",
"compositionyear",
"edition",
"catalognumber",
"genre",
"secondarygenre",
"descriptor",
"label",
"disctotal",
]
Expand Down
6 changes: 3 additions & 3 deletions rose/rule_parser_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def test_err(rule: str, err: str) -> None:
tracknumber^Track$
^
Invalid tag: must be one of {tracktitle, trackartist, trackartist[main], trackartist[guest], trackartist[remixer], trackartist[producer], trackartist[composer], trackartist[conductor], trackartist[djmixer], tracknumber, tracktotal, discnumber, disctotal, releasetitle, releaseartist, releaseartist[main], releaseartist[guest], releaseartist[remixer], releaseartist[producer], releaseartist[composer], releaseartist[conductor], releaseartist[djmixer], releasetype, releaseyear, compositionyear, catalognumber, genre, label, artist}. The next character after a tag must be ':' or ','.
Invalid tag: must be one of {tracktitle, trackartist, trackartist[main], trackartist[guest], trackartist[remixer], trackartist[producer], trackartist[composer], trackartist[conductor], trackartist[djmixer], tracknumber, tracktotal, discnumber, disctotal, releasetitle, releaseartist, releaseartist[main], releaseartist[guest], releaseartist[remixer], releaseartist[producer], releaseartist[composer], releaseartist[conductor], releaseartist[djmixer], releasetype, releaseyear, originalyear, compositionyear, edition, catalognumber, genre, secondarygenre, descriptor, label, artist}. The next character after a tag must be ':' or ','.
""",
)

Expand Down Expand Up @@ -250,7 +250,7 @@ def test_err(rule: str, err: str, matcher: MetadataMatcher | None = None) -> Non
haha/delete
^
Invalid tag: must be one of {tracktitle, trackartist, trackartist[main], trackartist[guest], trackartist[remixer], trackartist[producer], trackartist[composer], trackartist[conductor], trackartist[djmixer], tracknumber, discnumber, releasetitle, releaseartist, releaseartist[main], releaseartist[guest], releaseartist[remixer], releaseartist[producer], releaseartist[composer], releaseartist[conductor], releaseartist[djmixer], releasetype, releaseyear, compositionyear, catalognumber, genre, label, artist}. The next character after a tag must be ':' or ','.
Invalid tag: must be one of {tracktitle, trackartist, trackartist[main], trackartist[guest], trackartist[remixer], trackartist[producer], trackartist[composer], trackartist[conductor], trackartist[djmixer], tracknumber, discnumber, releasetitle, releaseartist, releaseartist[main], releaseartist[guest], releaseartist[remixer], releaseartist[producer], releaseartist[composer], releaseartist[conductor], releaseartist[djmixer], releasetype, releaseyear, originalyear, compositionyear, edition, catalognumber, genre, secondarygenre, descriptor, label, artist}. The next character after a tag must be ':' or ','.
""",
)

Expand All @@ -261,7 +261,7 @@ def test_err(rule: str, err: str, matcher: MetadataMatcher | None = None) -> Non
tracktitler/delete
^
Invalid tag: must be one of {tracktitle, trackartist, trackartist[main], trackartist[guest], trackartist[remixer], trackartist[producer], trackartist[composer], trackartist[conductor], trackartist[djmixer], tracknumber, discnumber, releasetitle, releaseartist, releaseartist[main], releaseartist[guest], releaseartist[remixer], releaseartist[producer], releaseartist[composer], releaseartist[conductor], releaseartist[djmixer], releasetype, releaseyear, compositionyear, catalognumber, genre, label, artist}. The next character after a tag must be ':' or ','.
Invalid tag: must be one of {tracktitle, trackartist, trackartist[main], trackartist[guest], trackartist[remixer], trackartist[producer], trackartist[composer], trackartist[conductor], trackartist[djmixer], tracknumber, discnumber, releasetitle, releaseartist, releaseartist[main], releaseartist[guest], releaseartist[remixer], releaseartist[producer], releaseartist[composer], releaseartist[conductor], releaseartist[djmixer], releasetype, releaseyear, originalyear, compositionyear, edition, catalognumber, genre, secondarygenre, descriptor, label, artist}. The next character after a tag must be ':' or ','.
""",
)

Expand Down
34 changes: 34 additions & 0 deletions rose/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,9 @@ def filter_track_false_positives_using_tags(
# fmt: off
match = match or (field == "tracktitle" and matches_pattern(matcher.pattern, tags.tracktitle))
match = match or (field == "releaseyear" and matches_pattern(matcher.pattern, tags.releaseyear))
match = match or (field == "originalyear" and matches_pattern(matcher.pattern, tags.originalyear))
match = match or (field == "compositionyear" and matches_pattern(matcher.pattern, tags.compositionyear))
match = match or (field == "edition" and matches_pattern(matcher.pattern, tags.edition))
match = match or (field == "catalognumber" and matches_pattern(matcher.pattern, tags.catalognumber))
match = match or (field == "tracknumber" and matches_pattern(matcher.pattern, tags.tracknumber))
match = match or (field == "tracktotal" and matches_pattern(matcher.pattern, tags.tracktotal))
Expand All @@ -237,6 +239,8 @@ def filter_track_false_positives_using_tags(
match = match or (field == "releasetitle" and matches_pattern(matcher.pattern, tags.releasetitle))
match = match or (field == "releasetype" and matches_pattern(matcher.pattern, tags.releasetype))
match = match or (field == "genre" and any(matches_pattern(matcher.pattern, x) for x in tags.genre))
match = match or (field == "secondarygenre" and any(matches_pattern(matcher.pattern, x) for x in tags.secondarygenre))
match = match or (field == "descriptor" and any(matches_pattern(matcher.pattern, x) for x in tags.descriptor))
match = match or (field == "label" and any(matches_pattern(matcher.pattern, x) for x in tags.label))
match = match or (field == "trackartist[main]" and any(matches_pattern(matcher.pattern, x.name) for x in tags.releaseartists.main))
match = match or (field == "trackartist[guest]" and any(matches_pattern(matcher.pattern, x.name) for x in tags.releaseartists.guest))
Expand All @@ -262,7 +266,9 @@ def filter_track_false_positives_using_tags(
# fmt: off
skip = skip or (field == "tracktitle" and matches_pattern(i.pattern, tags.tracktitle))
skip = skip or (field == "releaseyear" and matches_pattern(i.pattern, tags.releaseyear))
skip = skip or (field == "originalyear" and matches_pattern(i.pattern, tags.originalyear))
skip = skip or (field == "compositionyear" and matches_pattern(i.pattern, tags.compositionyear))
skip = skip or (field == "edition" and matches_pattern(i.pattern, tags.edition))
skip = skip or (field == "catalognumber" and matches_pattern(i.pattern, tags.catalognumber))
skip = skip or (field == "tracknumber" and matches_pattern(i.pattern, tags.tracknumber))
skip = skip or (field == "tracktotal" and matches_pattern(i.pattern, tags.tracktotal))
Expand All @@ -271,6 +277,8 @@ def filter_track_false_positives_using_tags(
skip = skip or (field == "releasetitle" and matches_pattern(i.pattern, tags.releasetitle))
skip = skip or (field == "releasetype" and matches_pattern(i.pattern, tags.releasetype))
skip = skip or (field == "genre" and any(matches_pattern(i.pattern, x) for x in tags.genre))
skip = skip or (field == "secondarygenre" and any(matches_pattern(i.pattern, x) for x in tags.secondarygenre))
skip = skip or (field == "descriptor" and any(matches_pattern(i.pattern, x) for x in tags.descriptor))
skip = skip or (field == "label" and any(matches_pattern(i.pattern, x) for x in tags.label))
skip = skip or (field == "trackartist[main]" and any(matches_pattern(i.pattern, x.name) for x in tags.releaseartists.main))
skip = skip or (field == "trackartist[guest]" and any(matches_pattern(i.pattern, x.name) for x in tags.releaseartists.guest))
Expand Down Expand Up @@ -348,6 +356,15 @@ def artists(xs: list[str]) -> list[Artist]:
f"Failed to assign new value {v} to releaseyear: value must be integer"
) from e
potential_changes.append(("releaseyear", origtags.releaseyear, tags.releaseyear))
elif field == "originalyear":
v = execute_single_action(act, tags.originalyear)
try:
tags.originalyear = int(v) if v else None
except ValueError as e:
raise InvalidReplacementValueError(
f"Failed to assign new value {v} to originalyear: value must be integer"
) from e
potential_changes.append(("originalyear", origtags.originalyear, tags.originalyear))
elif field == "compositionyear":
v = execute_single_action(act, tags.compositionyear)
try:
Expand All @@ -357,6 +374,9 @@ def artists(xs: list[str]) -> list[Artist]:
f"Failed to assign new value {v} to compositionyear: value must be integer"
) from e
potential_changes.append(("compositionyear", origtags.compositionyear, tags.compositionyear))
elif field == "edition":
tags.edition = execute_single_action(act, tags.edition)
potential_changes.append(("edition", origtags.edition, tags.edition))
elif field == "catalognumber":
tags.catalognumber = execute_single_action(act, tags.catalognumber)
potential_changes.append(("catalognumber", origtags.catalognumber, tags.catalognumber))
Expand All @@ -375,6 +395,12 @@ def artists(xs: list[str]) -> list[Artist]:
elif field == "genre":
tags.genre = execute_multi_value_action(act, tags.genre)
potential_changes.append(("genre", origtags.genre, tags.genre))
elif field == "secondarygenre":
tags.secondarygenre = execute_multi_value_action(act, tags.secondarygenre)
potential_changes.append(("secondarygenre", origtags.secondarygenre, tags.secondarygenre))
elif field == "descriptor":
tags.descriptor = execute_multi_value_action(act, tags.descriptor)
potential_changes.append(("descriptor", origtags.descriptor, tags.descriptor))
elif field == "label":
tags.label = execute_multi_value_action(act, tags.label)
potential_changes.append(("label", origtags.label, tags.label))
Expand Down Expand Up @@ -659,7 +685,9 @@ def filter_track_false_positives_using_read_cache(
# fmt: off
match = match or (field == "tracktitle" and matches_pattern(matcher.pattern, t.tracktitle))
match = match or (field == "releaseyear" and matches_pattern(matcher.pattern, t.release.releaseyear))
match = match or (field == "originalyear" and matches_pattern(matcher.pattern, t.release.originalyear))
match = match or (field == "compositionyear" and matches_pattern(matcher.pattern, t.release.compositionyear))
match = match or (field == "edition" and matches_pattern(matcher.pattern, t.release.edition))
match = match or (field == "catalognumber" and matches_pattern(matcher.pattern, t.release.catalognumber))
match = match or (field == "tracknumber" and matches_pattern(matcher.pattern, t.tracknumber))
match = match or (field == "tracktotal" and matches_pattern(matcher.pattern, t.tracktotal))
Expand All @@ -668,6 +696,8 @@ def filter_track_false_positives_using_read_cache(
match = match or (field == "releasetitle" and matches_pattern(matcher.pattern, t.release.releasetitle))
match = match or (field == "releasetype" and matches_pattern(matcher.pattern, t.release.releasetype))
match = match or (field == "genre" and any(matches_pattern(matcher.pattern, x) for x in t.release.genres))
match = match or (field == "secondarygenre" and any(matches_pattern(matcher.pattern, x) for x in t.release.secondary_genres))
match = match or (field == "descriptor" and any(matches_pattern(matcher.pattern, x) for x in t.release.descriptors))
match = match or (field == "label" and any(matches_pattern(matcher.pattern, x) for x in t.release.labels))
match = match or (field == "trackartist[main]" and any(matches_pattern(matcher.pattern, x.name) for x in t.trackartists.main))
match = match or (field == "trackartist[guest]" and any(matches_pattern(matcher.pattern, x.name) for x in t.trackartists.guest))
Expand Down Expand Up @@ -705,11 +735,15 @@ def filter_release_false_positives_using_read_cache(
# Only attempt to match the release tags; ignore track tags.
# fmt: off
match = match or (field == "releaseyear" and matches_pattern(matcher.pattern, r.releaseyear))
match = match or (field == "originalyear" and matches_pattern(matcher.pattern, r.originalyear))
match = match or (field == "compositionyear" and matches_pattern(matcher.pattern, r.compositionyear))
match = match or (field == "edition" and matches_pattern(matcher.pattern, r.edition))
match = match or (field == "catalognumber" and matches_pattern(matcher.pattern, r.catalognumber))
match = match or (field == "releasetitle" and matches_pattern(matcher.pattern, r.releasetitle))
match = match or (field == "releasetype" and matches_pattern(matcher.pattern, r.releasetype))
match = match or (field == "genre" and any(matches_pattern(matcher.pattern, x) for x in r.genres))
match = match or (field == "secondarygenre" and any(matches_pattern(matcher.pattern, x) for x in r.secondary_genres))
match = match or (field == "descriptor" and any(matches_pattern(matcher.pattern, x) for x in r.descriptors))
match = match or (field == "label" and any(matches_pattern(matcher.pattern, x) for x in r.labels))
match = match or (field == "releaseartist[main]" and any(matches_pattern(matcher.pattern, x.name) for x in r.releaseartists.main))
match = match or (field == "releaseartist[guest]" and any(matches_pattern(matcher.pattern, x.name) for x in r.releaseartists.guest))
Expand Down
Loading

0 comments on commit 7965ebe

Please sign in to comment.