def show_change(cur_artist, cur_album, match): """Print out a representation of the changes that will be made if an album's tags are changed according to `match`, which must be an AlbumMatch object. """ def show_album(artist, album): if artist: album_description = u' %s - %s' % (artist, album) elif album: album_description = u' %s' % album else: album_description = u' (unknown album)' print_(album_description) def format_index(track_info): """Return a string representing the track index of the given TrackInfo or Item object. """ if isinstance(track_info, hooks.TrackInfo): index = track_info.index medium_index = track_info.medium_index medium = track_info.medium mediums = match.info.mediums else: index = medium_index = track_info.track medium = track_info.disc mediums = track_info.disctotal if config['per_disc_numbering']: if mediums > 1: return u'{0}-{1}'.format(medium, medium_index) else: return unicode(medium_index) else: return unicode(index) # Identify the album in question. if cur_artist != match.info.artist or \ (cur_album != match.info.album and match.info.album != VARIOUS_ARTISTS): artist_l, artist_r = cur_artist or '', match.info.artist album_l, album_r = cur_album or '', match.info.album if artist_r == VARIOUS_ARTISTS: # Hide artists for VA releases. artist_l, artist_r = u'', u'' artist_l, artist_r = ui.colordiff(artist_l, artist_r) album_l, album_r = ui.colordiff(album_l, album_r) print_("Correcting tags from:") show_album(artist_l, album_l) print_("To:") show_album(artist_r, album_r) else: print_(u"Tagging:\n {0.artist} - {0.album}".format(match.info)) # Data URL. if match.info.data_url: print_('URL:\n %s' % match.info.data_url) # Info line. info = [] # Similarity. info.append('(Similarity: %s)' % dist_string(match.distance)) # Penalties. penalties = penalty_string(match.distance) if penalties: info.append(penalties) # Disambiguation. disambig = disambig_string(match.info) if disambig: info.append(ui.colorize('lightgray', '(%s)' % disambig)) print_(' '.join(info)) # Tracks. pairs = match.mapping.items() pairs.sort(key=lambda (_, track_info): track_info.index) # Build up LHS and RHS for track difference display. The `lines` list # contains ``(lhs, rhs, width)`` tuples where `width` is the length (in # characters) of the uncolorized LHS. lines = [] medium = disctitle = None for item, track_info in pairs: # Medium number and title. if medium != track_info.medium or disctitle != track_info.disctitle: media = match.info.media or 'Media' if match.info.mediums > 1 and track_info.disctitle: lhs = '%s %s: %s' % (media, track_info.medium, track_info.disctitle) elif match.info.mediums > 1: lhs = '%s %s' % (media, track_info.medium) elif track_info.disctitle: lhs = '%s: %s' % (media, track_info.disctitle) else: lhs = None if lhs: lines.append((lhs, '', 0)) medium, disctitle = track_info.medium, track_info.disctitle # Titles. new_title = track_info.title if not item.title.strip(): # If there's no title, we use the filename. cur_title = displayable_path(os.path.basename(item.path)) lhs, rhs = cur_title, new_title else: cur_title = item.title.strip() lhs, rhs = ui.colordiff(cur_title, new_title) lhs_width = len(cur_title) # Track number change. cur_track, new_track = format_index(item), format_index(track_info) if cur_track != new_track: if item.track in (track_info.index, track_info.medium_index): color = 'lightgray' else: color = 'red' if (cur_track + new_track).count('-') == 1: lhs_track, rhs_track = ui.colorize(color, cur_track), \ ui.colorize(color, new_track) else: color = 'red' lhs_track, rhs_track = ui.color_diff_suffix(cur_track, new_track) templ = ui.colorize(color, u' (#') + u'{0}' + \ ui.colorize(color, u')') lhs += templ.format(lhs_track) rhs += templ.format(rhs_track) lhs_width += len(cur_track) + 4 # Length change. if item.length and track_info.length and \ abs(item.length - track_info.length) > \ config['ui']['length_diff_thresh'].as_number(): cur_length = ui.human_seconds_short(item.length) new_length = ui.human_seconds_short(track_info.length) lhs_length, rhs_length = ui.color_diff_suffix(cur_length, new_length) templ = ui.colorize('red', u' (') + u'{0}' + \ ui.colorize('red', u')') lhs += templ.format(lhs_length) rhs += templ.format(rhs_length) lhs_width += len(cur_length) + 3 # Penalties. penalties = penalty_string(match.distance.tracks[track_info]) if penalties: rhs += ' %s' % penalties if lhs != rhs: lines.append((' * %s' % lhs, rhs, lhs_width)) elif config['import']['detail']: lines.append((' * %s' % lhs, '', lhs_width)) # Print each track in two columns, or across two lines. col_width = (ui.term_width() - len(''.join([' * ', ' -> ']))) // 2 if lines: max_width = max(w for _, _, w in lines) for lhs, rhs, lhs_width in lines: if not rhs: print_(lhs) elif max_width > col_width: print_(u'%s ->\n %s' % (lhs, rhs)) else: pad = max_width - lhs_width print_(u'%s%s -> %s' % (lhs, ' ' * pad, rhs)) # Missing and unmatched tracks. if match.extra_tracks: print_('Missing tracks:') for track_info in match.extra_tracks: line = ' ! %s (#%s)' % (track_info.title, format_index(track_info)) if track_info.length: line += ' (%s)' % ui.human_seconds_short(track_info.length) print_(ui.colorize('yellow', line)) if match.extra_items: print_('Unmatched tracks:') for item in match.extra_items: line = ' ! %s (#%s)' % (item.title, format_index(item)) if item.length: line += ' (%s)' % ui.human_seconds_short(item.length) print_(ui.colorize('yellow', line))
def show_change(cur_artist, cur_album, match): """Print out a representation of the changes that will be made if an album's tags are changed according to `match`, which must be an AlbumMatch object. """ def show_album(artist, album, partial=False): if artist: album_description = u' %s - %s' % (artist, album) elif album: album_description = u' %s' % album else: album_description = u' (unknown album)' out = album_description # Add a suffix if this is a partial match. if partial: out += u' ' + ui.colorize('yellow', PARTIAL_MATCH_MESSAGE) print_(out) def format_index(track_info): """Return a string representing the track index of the given TrackInfo object. """ if config['per_disc_numbering'].get(bool): if match.info.mediums > 1: return u'{0}-{1}'.format(track_info.medium, track_info.medium_index) else: return unicode(track_info.medium_index) else: return unicode(track_info.index) # Identify the album in question. if cur_artist != match.info.artist or \ (cur_album != match.info.album and match.info.album != VARIOUS_ARTISTS): artist_l, artist_r = cur_artist or '', match.info.artist album_l, album_r = cur_album or '', match.info.album if artist_r == VARIOUS_ARTISTS: # Hide artists for VA releases. artist_l, artist_r = u'', u'' artist_l, artist_r = ui.colordiff(artist_l, artist_r) album_l, album_r = ui.colordiff(album_l, album_r) print_("Correcting tags from:") show_album(artist_l, album_l) print_("To:") show_album(artist_r, album_r) else: message = u"Tagging: %s - %s" % (match.info.artist, match.info.album) if match.extra_items or match.extra_tracks: message += u' ' + ui.colorize('yellow', PARTIAL_MATCH_MESSAGE) print_(message) # Distance/similarity. print_('(Similarity: %s)' % dist_string(match.distance)) # Tracks. pairs = match.mapping.items() pairs.sort(key=lambda (_, track_info): track_info.index) # Build up LHS and RHS for track difference display. The `lines` # list contains ``(current title, new title, width)`` tuples where # `width` is the length (in characters) of the uncolorized LHS. lines = [] for item, track_info in pairs: # Titles. new_title = track_info.title if not item.title.strip(): # If there's no title, we use the filename. cur_title = displayable_path(os.path.basename(item.path)) lhs, rhs = cur_title, new_title else: cur_title = item.title.strip() lhs, rhs = ui.colordiff(cur_title, new_title) lhs_width = len(cur_title) # Track number change. if item.track not in (track_info.index, track_info.medium_index): cur_track, new_track = unicode(item.track), format_index(track_info) lhs_track, rhs_track = ui.color_diff_suffix(cur_track, new_track) templ = ui.colorize('red', u' (#') + u'{0}' + \ ui.colorize('red', u')') lhs += templ.format(lhs_track) rhs += templ.format(rhs_track) lhs_width += len(cur_track) + 4 # Length change. if item.length and track_info.length and \ abs(item.length - track_info.length) > \ config['ui']['length_diff_thresh'].as_number(): cur_length = ui.human_seconds_short(item.length) new_length = ui.human_seconds_short(track_info.length) lhs_length, rhs_length = ui.color_diff_suffix(cur_length, new_length) templ = ui.colorize('red', u' (') + u'{0}' + \ ui.colorize('red', u')') lhs += templ.format(lhs_length) rhs += templ.format(rhs_length) lhs_width += len(cur_length) + 3 if lhs != rhs: lines.append((lhs, rhs, lhs_width)) elif config['import']['detail']: lines.append((lhs, '', lhs_width)) # Print each track in two columns, or across two lines. col_width = (ui.term_width() - len(''.join([' * ', ' -> ']))) // 2 if lines: max_width = max(w for _, _, w in lines) for lhs, rhs, lhs_width in lines: if not rhs: print_(u' * {0}'.format(lhs)) elif max_width > col_width: print_(u' * %s ->\n %s' % (lhs, rhs)) else: pad = max_width - lhs_width print_(u' * %s%s -> %s' % (lhs, ' ' * pad, rhs)) # Missing and unmatched tracks. for track_info in match.extra_tracks: line = u' * Missing track: {0} ({1})'.format(track_info.title, format_index(track_info)) line = ui.colorize('yellow', line) print_(line) for item in match.extra_items: line = u' * Unmatched track: {0} ({1})'.format(item.title, item.track) line = ui.colorize('yellow', line) print_(line)
def show_change(cur_artist, cur_album, match): """Print out a representation of the changes that will be made if an album's tags are changed according to `match`, which must be an AlbumMatch object. """ def show_album(artist, album, partial=False): if artist: album_description = u' %s - %s' % (artist, album) elif album: album_description = u' %s' % album else: album_description = u' (unknown album)' out = album_description # Add a suffix if this is a partial match. if partial: out += u' %s' % ui.colorize('yellow', PARTIAL_MATCH_MESSAGE) print_(out) def format_index(track_info): """Return a string representing the track index of the given TrackInfo or Item object. """ if isinstance(track_info, autotag.hooks.TrackInfo): index = track_info.index medium_index = track_info.medium_index medium = track_info.medium mediums = match.info.mediums else: index = medium_index = track_info.track medium = track_info.disc mediums = track_info.disctotal if config['per_disc_numbering'].get(bool): if mediums > 1: return u'{0}-{1}'.format(medium, medium_index) else: return unicode(medium_index) else: return unicode(index) # Identify the album in question. if cur_artist != match.info.artist or \ (cur_album != match.info.album and match.info.album != VARIOUS_ARTISTS): artist_l, artist_r = cur_artist or '', match.info.artist album_l, album_r = cur_album or '', match.info.album if artist_r == VARIOUS_ARTISTS: # Hide artists for VA releases. artist_l, artist_r = u'', u'' artist_l, artist_r = ui.colordiff(artist_l, artist_r) album_l, album_r = ui.colordiff(album_l, album_r) print_("Correcting tags from:") show_album(artist_l, album_l) print_("To:") show_album(artist_r, album_r) else: message = u"Tagging:\n %s - %s" % (match.info.artist, match.info.album) if match.extra_items or match.extra_tracks: message += u' %s' % ui.colorize('yellow', PARTIAL_MATCH_MESSAGE) print_(message) # Data URL. if match.info.data_url: print_('URL:\n %s' % match.info.data_url) # Info line. info = [] info.append('(Similarity: %s)' % dist_string(match.distance)) if match.info.data_source != 'MusicBrainz': info.append(ui.colorize('turquoise', '(%s)' % match.info.data_source)) disambig = disambig_string(match.info) if disambig: info.append(ui.colorize('lightgray', '(%s)' % disambig)) print_(' '.join(info)) # Tracks. pairs = match.mapping.items() pairs.sort(key=lambda (_, track_info): track_info.index) # Build up LHS and RHS for track difference display. The `lines` list # contains ``(lhs, rhs, width)`` tuples where `width` is the length (in # characters) of the uncolorized LHS. lines = [] medium = disctitle = None for item, track_info in pairs: # Medium number and title. if medium != track_info.medium or disctitle != track_info.disctitle: media = match.info.media or 'Media' if match.info.mediums > 1 and track_info.disctitle: lhs = '%s %s: %s' % (media, track_info.medium, track_info.disctitle) elif match.info.mediums > 1: lhs = '%s %s' % (media, track_info.medium) elif track_info.disctitle: lhs = '%s: %s' % (media, track_info.disctitle) else: lhs = None if lhs: lines.append((lhs, '', 0)) medium, disctitle = track_info.medium, track_info.disctitle # Titles. new_title = track_info.title if not item.title.strip(): # If there's no title, we use the filename. cur_title = displayable_path(os.path.basename(item.path)) lhs, rhs = cur_title, new_title else: cur_title = item.title.strip() lhs, rhs = ui.colordiff(cur_title, new_title) lhs_width = len(cur_title) # Track number change. cur_track, new_track = format_index(item), format_index(track_info) if cur_track != new_track: if item.track in (track_info.index, track_info.medium_index): color = 'yellow' else: color = 'red' if (cur_track + new_track).count('-') == 1: lhs_track, rhs_track = ui.colorize(color, cur_track), \ ui.colorize(color, new_track) else: color = 'red' lhs_track, rhs_track = ui.color_diff_suffix( cur_track, new_track) templ = ui.colorize(color, u' (#') + u'{0}' + \ ui.colorize(color, u')') lhs += templ.format(lhs_track) rhs += templ.format(rhs_track) lhs_width += len(cur_track) + 4 # Length change. if item.length and track_info.length and \ abs(item.length - track_info.length) > \ config['ui']['length_diff_thresh'].as_number(): cur_length = ui.human_seconds_short(item.length) new_length = ui.human_seconds_short(track_info.length) lhs_length, rhs_length = ui.color_diff_suffix( cur_length, new_length) templ = ui.colorize('red', u' (') + u'{0}' + \ ui.colorize('red', u')') lhs += templ.format(lhs_length) rhs += templ.format(rhs_length) lhs_width += len(cur_length) + 3 # Hidden penalties. No LHS/RHS diff is displayed, but we still want to # indicate that a penalty has been applied to explain the similarity # score. penalties = [] if match.info.va and track_info.artist and \ item.artist.lower() not in VA_ARTISTS: penalties.append('artist') if item.mb_trackid and item.mb_trackid != track_info.track_id: penalties.append('ID') if penalties: rhs += ' %s' % ui.colorize('red', '(%s)' % ', '.join(penalties)) if lhs != rhs: lines.append((' * %s' % lhs, rhs, lhs_width)) elif config['import']['detail']: lines.append((' * %s' % lhs, '', lhs_width)) # Print each track in two columns, or across two lines. col_width = (ui.term_width() - len(''.join([' * ', ' -> ']))) // 2 if lines: max_width = max(w for _, _, w in lines) for lhs, rhs, lhs_width in lines: if not rhs: print_(lhs) elif max_width > col_width: print_(u'%s ->\n %s' % (lhs, rhs)) else: pad = max_width - lhs_width print_(u'%s%s -> %s' % (lhs, ' ' * pad, rhs)) # Missing and unmatched tracks. if match.extra_tracks: print_('Missing tracks:') for track_info in match.extra_tracks: line = ' ! %s (#%s)' % (track_info.title, format_index(track_info)) if track_info.length: line += ' (%s)' % ui.human_seconds_short(track_info.length) print_(ui.colorize('yellow', line)) if match.extra_items: print_('Unmatched tracks:') for item in match.extra_items: line = ' ! %s (#%s)' % (item.title, format_index(item)) if item.length: line += ' (%s)' % ui.human_seconds_short(item.length) print_(ui.colorize('yellow', line))
def show_change(cur_artist, cur_album, match): """Print out a representation of the changes that will be made if an album's tags are changed according to `match`, which must be an AlbumMatch object. """ def show_album(artist, album, partial=False): if artist: album_description = u' %s - %s' % (artist, album) elif album: album_description = u' %s' % album else: album_description = u' (unknown album)' out = album_description # Add a suffix if this is a partial match. if partial: out += u' ' + ui.colorize('yellow', PARTIAL_MATCH_MESSAGE) print_(out) def format_index(track_info): """Return a string representing the track index of the given TrackInfo object. """ if config['per_disc_numbering'].get(bool): if match.info.mediums > 1: return u'{0}-{1}'.format(track_info.medium, track_info.medium_index) else: return unicode(track_info.medium_index) else: return unicode(track_info.index) # Identify the album in question. if cur_artist != match.info.artist or \ (cur_album != match.info.album and match.info.album != VARIOUS_ARTISTS): artist_l, artist_r = cur_artist or '', match.info.artist album_l, album_r = cur_album or '', match.info.album if artist_r == VARIOUS_ARTISTS: # Hide artists for VA releases. artist_l, artist_r = u'', u'' artist_l, artist_r = ui.colordiff(artist_l, artist_r) album_l, album_r = ui.colordiff(album_l, album_r) print_("Correcting tags from:") show_album(artist_l, album_l) print_("To:") show_album(artist_r, album_r) else: message = u"Tagging: %s - %s" % (match.info.artist, match.info.album) if match.extra_items or match.extra_tracks: message += u' ' + ui.colorize('yellow', PARTIAL_MATCH_MESSAGE) print_(message) # Distance/similarity. print_('(Similarity: %s)' % dist_string(match.distance)) # Tracks. pairs = match.mapping.items() pairs.sort(key=lambda (_, track_info): track_info.index) # Build up LHS and RHS for track difference display. The `lines` # list contains ``(current title, new title, width)`` tuples where # `width` is the length (in characters) of the uncolorized LHS. lines = [] for item, track_info in pairs: # Titles. new_title = track_info.title if not item.title.strip(): # If there's no title, we use the filename. cur_title = displayable_path(os.path.basename(item.path)) lhs, rhs = cur_title, new_title else: cur_title = item.title.strip() lhs, rhs = ui.colordiff(cur_title, new_title) lhs_width = len(cur_title) # Track number change. if item.track not in (track_info.index, track_info.medium_index): cur_track, new_track = unicode( item.track), format_index(track_info) lhs_track, rhs_track = ui.color_diff_suffix(cur_track, new_track) templ = ui.colorize('red', u' (#') + u'{0}' + \ ui.colorize('red', u')') lhs += templ.format(lhs_track) rhs += templ.format(rhs_track) lhs_width += len(cur_track) + 4 # Length change. if item.length and track_info.length and \ abs(item.length - track_info.length) > \ config['ui']['length_diff_thresh'].as_number(): cur_length = ui.human_seconds_short(item.length) new_length = ui.human_seconds_short(track_info.length) lhs_length, rhs_length = ui.color_diff_suffix( cur_length, new_length) templ = ui.colorize('red', u' (') + u'{0}' + \ ui.colorize('red', u')') lhs += templ.format(lhs_length) rhs += templ.format(rhs_length) lhs_width += len(cur_length) + 3 if lhs != rhs: lines.append((lhs, rhs, lhs_width)) # Print each track in two columns, or across two lines. col_width = (ui.term_width() - len(''.join([' * ', ' -> ']))) // 2 if lines: max_width = max(w for _, _, w in lines) for lhs, rhs, lhs_width in lines: if max_width > col_width: print_(u' * %s ->\n %s' % (lhs, rhs)) else: pad = max_width - lhs_width print_(u' * %s%s -> %s' % (lhs, ' ' * pad, rhs)) # Missing and unmatched tracks. for track_info in match.extra_tracks: line = u' * Missing track: {0} ({1})'.format(track_info.title, format_index(track_info)) line = ui.colorize('yellow', line) print_(line) for item in match.extra_items: line = u' * Unmatched track: {0} ({1})'.format(item.title, item.track) line = ui.colorize('yellow', line) print_(line)