Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add requested template variables #536

Merged
merged 8 commits into from
May 16, 2021
10 changes: 9 additions & 1 deletion man/whipper-cd-rip.rst
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,15 @@ Template schemes

| - %A: release artist
| - %S: release sort name
| - %d: disc title
| - %B: release barcode
| - %C: release catalog number
| - %c: release disambiguation comment
| - %d: release title (with disambiguation)
| - %D: disc title (without disambiguation)
| - %I: MusicBrainz Disc ID
| - %M: total number of discs in the chosen release
| - %N: number of current disc
| - %T: medium title
| - %y: release year
| - %r: release type, lowercase
| - %R: release type, normal case
Expand Down
12 changes: 10 additions & 2 deletions whipper/command/cd.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,15 @@
disc and track template are:
- %A: release artist
- %S: release sort name
- %d: disc title
- %B: release barcode
- %C: release catalog number
- %c: release disambiguation comment
- %d: release title (with disambiguation)
- %D: disc title (without disambiguation)
- %I: MusicBrainz Disc ID
- %M: total number of discs in the chosen release
- %N: number of current disc
- %T: medium title
- %y: release year
- %r: release type, lowercase
- %R: release type, normal case
Expand Down Expand Up @@ -185,7 +193,7 @@ def do(self):
and self.program.metadata.artist \
or 'Unknown Artist'
self.program.result.title = self.program.metadata \
and self.program.metadata.title \
and self.program.metadata.releaseTitle \
or 'Unknown Title'
_, self.program.result.vendor, self.program.result.model, \
self.program.result.release = \
Expand Down
2 changes: 1 addition & 1 deletion whipper/command/mblookup.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def _printMetadata(self, md):
:type md: `DiscMetadata`
"""
print(' Artist: %s' % md.artist.encode('utf-8'))
print(' Title: %s' % md.title.encode('utf-8'))
print(' Title: %s' % md.releaseTitle.encode('utf-8'))
print(' Type: %s' % str(md.releaseType).encode('utf-8'))
print(' URL: %s' % md.url)
print(' Tracks: %d' % len(md.tracks))
Expand Down
4 changes: 2 additions & 2 deletions whipper/common/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,9 +277,9 @@ def getRelativePath(targetPath, collectionPath):
def validate_template(template, kind):
"""Raise exception if disc/track template includes invalid variables."""
if kind == 'disc':
matches = re.findall(r'%[^ARSXdrxy]', template)
matches = re.findall(r'%[^ABCDIMNRSTXcdrxy]', template)
elif kind == 'track':
matches = re.findall(r'%[^ARSXadnrstxy]', template)
matches = re.findall(r'%[^ABCDIMNRSTXacdnrstxy]', template)
if '%' in template and matches:
raise ValueError(kind + ' template string contains invalid '
'variable(s): {}'.format(', '.join(matches)))
Expand Down
43 changes: 32 additions & 11 deletions whipper/common/mbngs.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,25 @@ class DiscMetadata:
:cvar sortName: release artist sort name
:cvar release: earliest release date, in YYYY-MM-DD
:vartype release: str
:cvar title: title of the disc (with disambiguation)
:cvar releaseTitle: title of the release (without disambiguation)
:cvar title: title of the disc (without disambiguation)
:vartype title: str or None
:cvar releaseTitle: title of the release (with disambiguation)
:vartype releasetitle: str or None
:cvar releaseDisambCmt: release disambiguation comment
:vartype releaseDisambCmt: str or None
:cvar mediumTitle: title of the medium
:vartype mediumTitle: str or None
:vartype tracks: list of :any:`TrackMetadata`
:cvar countries: MusicBrainz release countries
:vartype countries: list or None
:cvar discNumber: number of current disc
:vartype discNumber: int or None
:cvar discTotal: total number of discs in the chosen release
:vartype discTotal: int or None
:cvar catalogNumber: release catalog number
:vartype catalogNumber: str or None
:cvar barcode: release barcode
:vartype barcode: str or None
"""

artist = None
Expand All @@ -81,6 +95,7 @@ class DiscMetadata:
release = None

releaseTitle = None
releaseDisambCmt = None
releaseType = None

mbid = None
Expand All @@ -91,6 +106,9 @@ class DiscMetadata:
catalogNumber = None
barcode = None
countries = None
discNumber = None
discTotal = None
mediumTitle = None

def __init__(self):
self.tracks = []
Expand Down Expand Up @@ -281,17 +299,20 @@ def _getMetadata(release, discid=None, country=None):
for medium in release['medium-list']:
for disc in medium['disc-list']:
if discid is None or disc['id'] == discid:
title = release['title']
discMD.releaseTitle = title
discMD.title = release['title']
discMD.releaseTitle = releaseTitle = discMD.title
if 'disambiguation' in release:
title += " (%s)" % release['disambiguation']
count = len(release['medium-list'])
if count > 1:
title += ' (Disc %d of %d)' % (
int(medium['position']), count)
discMD.releaseDisambCmt = release['disambiguation']
releaseTitle += " (%s)" % release['disambiguation']
discMD.discNumber = int(medium['position'])
discMD.discTotal = len(release['medium-list'])
if discMD.discTotal > 1:
releaseTitle += ' (Disc %d of %d)' % (
discMD.discNumber, discMD.discTotal)
if 'title' in medium:
title += ": %s" % medium['title']
discMD.title = title
discMD.mediumTitle = medium['title']
releaseTitle += ": %s" % medium['title']
discMD.releaseTitle = releaseTitle
for t in medium['track-list']:
track = TrackMetadata()
trackCredit = _Credit(
Expand Down
43 changes: 31 additions & 12 deletions whipper/common/program.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,15 @@ def getPath(self, outdir, template, mbdiscid, metadata, track_number=None):

* ``%A``: release artist
* ``%S``: release artist sort name
* ``%d``: disc title
* ``%B``: release barcode
* ``%C``: release catalog number
* ``%c``: release disambiguation comment
* ``%d``: release title (with disambiguation)
* ``%D``: disc title (without disambiguation)
* ``%I``: MusicBrainz Disc ID
* ``%M``: total number of discs in the chosen release
* ``%N``: number of current disc
* ``%T``: medium title
* ``%y``: release year
* ``%r``: release type, lowercase
* ``%R``: release type, normal case
Expand All @@ -187,7 +195,7 @@ def getPath(self, outdir, template, mbdiscid, metadata, track_number=None):
assert isinstance(template, str), "%r is not str" % template
v = {}
v['A'] = 'Unknown Artist'
v['d'] = mbdiscid # fallback for title
v['I'] = v['d'] = v['D'] = mbdiscid # fallback for title
v['r'] = 'unknown'
v['R'] = 'Unknown'
v['B'] = '' # barcode
Expand All @@ -208,9 +216,14 @@ def getPath(self, outdir, template, mbdiscid, metadata, track_number=None):
v['y'] = release[:4]
v['A'] = metadata.artist
v['S'] = metadata.sortName
v['d'] = metadata.title
v['d'] = metadata.releaseTitle
v['D'] = metadata.title
v['B'] = metadata.barcode
v['C'] = metadata.catalogNumber
v['c'] = metadata.releaseDisambCmt
v['M'] = metadata.discTotal
v['N'] = metadata.discNumber
v['T'] = metadata.mediumTitle
if metadata.releaseType:
v['R'] = metadata.releaseType
v['r'] = metadata.releaseType.lower()
Expand Down Expand Up @@ -316,7 +329,7 @@ def getMusicBrainz(self, ittoc, mbdiscid, release=None, country=None,

for metadata in metadatas:
print('\nArtist : %s' % metadata.artist)
print('Title : %s' % metadata.title)
print('Title : %s' % metadata.releaseTitle)
print('Duration: %s' % common.formatTime(
metadata.duration / 1000.0))
print('URL : %s' % metadata.url)
Expand Down Expand Up @@ -356,7 +369,7 @@ def getMusicBrainz(self, ittoc, mbdiscid, release=None, country=None,
if len(metadatas) == 1:
logger.info('picked requested release id %s', release)
print('Artist: %s' % metadatas[0].artist)
print('Title : %s' % metadatas[0].title)
print('Title : %s' % metadatas[0].releaseTitle)
elif not metadatas:
logger.warning("requested release id '%s', but none of "
"the found releases match", release)
Expand All @@ -368,16 +381,16 @@ def getMusicBrainz(self, ittoc, mbdiscid, release=None, country=None,
# If we have multiple, make sure they match
if len(metadatas) > 1:
artist = metadatas[0].artist
releaseTitle = metadatas[0].releaseTitle
discTitle = metadatas[0].title
for i, metadata in enumerate(metadatas):
if not artist == metadata.artist:
logger.warning("artist 0: %r and artist %d: %r are "
"not the same", artist, i,
metadata.artist)
if not releaseTitle == metadata.releaseTitle:
if not discTitle == metadata.title:
logger.warning("title 0: %r and title %d: %r are "
"not the same", releaseTitle, i,
metadata.releaseTitle)
"not the same", discTitle, i,
metadata.title)

if not release and len(list(deltas)) > 1:
logger.warning('picked closest match in duration. '
Expand Down Expand Up @@ -407,13 +420,13 @@ def getTagList(self, number, mbdiscid):
"""
trackArtist = 'Unknown Artist'
releaseArtist = 'Unknown Artist'
disc = 'Unknown Disc'
album = 'Unknown Album'
title = 'Unknown Track'

if self.metadata:
trackArtist = self.metadata.artist
releaseArtist = self.metadata.artist
disc = self.metadata.title
album = self.metadata.title # No disambiguation is proper here
mbidRelease = self.metadata.mbid
mbidReleaseGroup = self.metadata.mbidReleaseGroup
mbidReleaseArtist = self.metadata.mbidArtist
Expand Down Expand Up @@ -445,13 +458,19 @@ def getTagList(self, number, mbdiscid):
tags['ALBUMARTIST'] = releaseArtist
tags['ARTIST'] = trackArtist
tags['TITLE'] = title
tags['ALBUM'] = disc
tags['ALBUM'] = album

tags['TRACKNUMBER'] = '%s' % number

if self.metadata:
if self.metadata.release is not None:
tags['DATE'] = self.metadata.release
if self.metadata.tracks:
tags['TRACKTOTAL'] = str(len(self.metadata.tracks))
if self.metadata.discTotal is not None:
tags['DISCTOTAL'] = str(self.metadata.discTotal)
if self.metadata.discNumber is not None:
tags['DISCNUMBER'] = str(self.metadata.discNumber)

if number > 0:
tags['MUSICBRAINZ_RELEASETRACKID'] = mbidTrack
Expand Down
4 changes: 2 additions & 2 deletions whipper/test/test_common_program.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def testStandardTemplateFilled(self):
prog = program.Program(config.Config())
md = mbngs.DiscMetadata()
md.artist = md.sortName = 'Jeff Buckley'
md.title = 'Grace'
md.releaseTitle = 'Grace'

path = prog.getPath('/tmp', DEFAULT_DISC_TEMPLATE,
'mbdiscid', md, 0)
Expand All @@ -36,7 +36,7 @@ def testIssue66TemplateFilled(self):
prog = program.Program(config.Config())
md = mbngs.DiscMetadata()
md.artist = md.sortName = 'Jeff Buckley'
md.title = 'Grace'
md.releaseTitle = 'Grace'

path = prog.getPath('/tmp', '%A/%d', 'mbdiscid', md, 0)
self.assertEqual(path,
Expand Down