Skip to content

Commit

Permalink
Fix #1 Support sub-tracks
Browse files Browse the repository at this point in the history
  • Loading branch information
infojunkie committed Jul 20, 2024
1 parent b77b763 commit 8abee84
Show file tree
Hide file tree
Showing 6 changed files with 603 additions and 28 deletions.
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ An audio tagger based on Discogs metadata.

[![PyPI Version](https://img.shields.io/pypi/v/discogs-tag.svg)](https://pypi.org/project/discogs-tag/)

# Development
- Install [`poetry`](https://python-poetry.org/docs/#installation)
- `poetry install && poetry build && pip install .`

# Usage
```shell
NAME
Expand Down Expand Up @@ -46,6 +42,8 @@ DESCRIPTION
The SKIP flag can take one or more of the following values, comma-separated:
artist, composer, title, position, date, subtrack, album, genre, albumartist

If subtracks are skipped, subtrack titles get appended to their parent track.

POSITIONAL ARGUMENTS
RELEASE

Expand Down Expand Up @@ -75,6 +73,8 @@ DESCRIPTION
The SKIP flag can take one or more of the following values, comma-separated:
artist, composer, title, position, date, subtrack, album, genre, albumartist

If subtracks are skipped, subtrack titles get appended to their parent track.

POSITIONAL ARGUMENTS
SRC

Expand Down Expand Up @@ -128,3 +128,7 @@ FLAGS
NOTES
You can also use flags syntax for POSITIONAL ARGUMENTS
```
# Development
- Install [`poetry`](https://python-poetry.org/docs/#installation)
- `poetry install && poetry build && pip install .`

6 changes: 3 additions & 3 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

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 = "discogs-tag"
version = "1.1.1"
version = "1.2.0"
description = "An audio tagger based on Discogs metadata."
authors = ["infojunkie <[email protected]>"]
repository = "https://github.com/infojunkie/discogs-tag.py"
Expand Down
41 changes: 28 additions & 13 deletions src/discogs_tag/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
'title',
'position',
'date',
'subtrack',
'subtracks',
'album',
'genre',
'albumartist'
Expand All @@ -32,6 +32,10 @@

AUDIO_EXTENSIONS = ['flac', 'mp3']

VARIOUS_ARTISTS = [
'Various Artists'
]

def tag(
release,
dir='./',
Expand All @@ -47,7 +51,9 @@ def tag(
- A local file URI pointing to a release JSON file
The SKIP flag can take one or more of the following values, comma-separated:
artist, composer, title, position, date, subtrack, album, genre, albumartist
artist, composer, title, position, date, subtracks, album, genre, albumartist
If subtracks are skipped, subtrack titles get appended to their parent track.
"""
options = parse_options(locals())
Expand All @@ -66,7 +72,9 @@ def copy(
"""Copy the audio tags from source to destination folders.
The SKIP flag can take one or more of the following values, comma-separated:
artist, composer, title, position, date, subtrack, album, genre, albumartist
artist, composer, title, position, date, subtracks, album, genre, albumartist
If subtracks are skipped, subtrack titles get appended to their parent track.
"""
options = parse_options(locals())
Expand Down Expand Up @@ -210,7 +218,9 @@ def get_tracks(tracklist):
def reduce_track(tracks, track):
if track['type_'] == 'track':
tracks.append(track)
if not options['skip_subtrack'] and 'sub_tracks' in track:
elif options['skip_subtracks'] and 'sub_tracks' in track:
tracks.append(track)
if not options['skip_subtracks'] and 'sub_tracks' in track:
tracks = tracks + get_tracks(track['sub_tracks'])
return tracks
return reduce(reduce_track, tracklist, [])
Expand All @@ -225,7 +235,7 @@ def reduce_track(tracks, track):
for n, track in enumerate(tracks):
try:
audio = mutagen.File(files[n], easy=True)
audio = merge_metadata(release, track, audio, options)
audio = apply_metadata_track(release, track, audio, n+1, options)
if options['dry']:
pprint(audio)
else:
Expand Down Expand Up @@ -332,11 +342,13 @@ def parse_options(options):
for skip in SKIP_KEYS:
options['skip_' + skip.lower()] = False
if 'skip' in options and options['skip'] is not None:
if isinstance(options['skip'], str):
options['skip'] = [options['skip']]
for skip in options['skip']:
options['skip_' + skip.lower()] = True
return options

def merge_metadata(release, track, audio, options):
def apply_metadata_track(release, track, audio, n, options):
def artist_name(artist):
name = None
if 'anv' in artist and artist['anv']:
Expand All @@ -346,7 +358,11 @@ def artist_name(artist):
return re.sub(r"\s+\(\d+\)$", '', name) if name else None

if not options['skip_title']:
audio['title'] = track['title']
title = track['title']
if options['skip_subtracks'] and 'sub_tracks' in track:
title += ': ' + ' / '.join([subtrack['title'] for subtrack in track['sub_tracks'] if subtrack['type_'] == 'track'])
if title:
audio['title'] = title

if not options['skip_artist']:
artists = []
Expand Down Expand Up @@ -377,20 +393,19 @@ def artist_name(artist):
if 'title' in release:
audio['album'] = release['title']

if not options['skip_composer']:
composers = [artist_name(composer) for composer in filter(lambda a: a['role'].casefold() in [(lambda c: c.casefold())(c) for c in COMPOSER_TAGS], track['extraartists'])] if 'extraartists' in track else None
if not options['skip_composer'] and 'extraartists' in track:
composers = [artist_name(composer) for composer in track['extraartists'] if composer['role'].casefold() in [(lambda c: c.casefold())(c) for c in COMPOSER_TAGS]]
if composers:
audio['composer'] = ', '.join(composers)

if not options['skip_position']:
positions = track['position'].split('-')
audio['tracknumber'] = positions[-1]
audio['tracknumber'] = positions[-1] or str(n)
if len(positions) > 1:
audio['discnumber'] = positions[0]

if not options['skip_date']:
if 'year' in release and release['year']:
audio['date'] = str(release['year'])
if not options['skip_date'] and 'year' in release:
audio['date'] = str(release['year'])

return audio

Expand Down
Loading

0 comments on commit 8abee84

Please sign in to comment.