Ejemplo n.º 1
0
def resolve_duplicate(task, config):
    """Decide what to do when a new album or item seems similar to one
    that's already in the library.
    """
    log.warn("This %s is already in the library!" %
             ("album" if task.is_album else "item"))

    if config.quiet:
        # In quiet mode, don't prompt -- just skip.
        log.info('Skipping.')
        sel = 's'
    else:
        sel = ui.input_options(
            ('Skip new', 'Keep both', 'Remove old'),
            color=config.color
        )

    if sel == 's':
        # Skip new.
        task.set_choice(importer.action.SKIP)
    elif sel == 'k':
        # Keep both. Do nothing; leave the choice intact.
        pass
    elif sel == 'r':
        # Remove old.
        task.remove_duplicates = True
    else:
        assert False
Ejemplo n.º 2
0
def choose_candidate(candidates, singleton, rec, color, timid,
                     cur_artist=None, cur_album=None, item=None,
                     itemcount=None, per_disc_numbering=False):
    """Given a sorted list of candidates, ask the user for a selection
    of which candidate to use. Applies to both full albums and
    singletons  (tracks). Candidates are either AlbumMatch or TrackMatch
    objects depending on `singleton`. for albums, `cur_artist`,
    `cur_album`, and `itemcount` must be provided. For singletons,
    `item` must be provided.

    Returns the result of the choice, which may SKIP, ASIS, TRACKS, or
    MANUAL or a candidate (an AlbumMatch/TrackMatch object).
    """
    # Sanity check.
    if singleton:
        assert item is not None
    else:
        assert cur_artist is not None
        assert cur_album is not None

    # Zero candidates.
    if not candidates:
        if singleton:
            print_("No matching recordings found.")
            opts = ('Use as-is', 'Skip', 'Enter search', 'enter Id',
                    'aBort')
        else:
            print_("No matching release found for {0} tracks."
                   .format(itemcount))
            print_('For help, see: '
                   'https://github.com/sampsyo/beets/wiki/FAQ#wiki-nomatch')
            opts = ('Use as-is', 'as Tracks', 'Skip', 'Enter search',
                    'enter Id', 'aBort')
        sel = ui.input_options(opts, color=color)
        if sel == 'u':
            return importer.action.ASIS
        elif sel == 't':
            assert not singleton
            return importer.action.TRACKS
        elif sel == 'e':
            return importer.action.MANUAL
        elif sel == 's':
            return importer.action.SKIP
        elif sel == 'b':
            raise importer.ImportAbort()
        elif sel == 'i':
            return importer.action.MANUAL_ID
        else:
            assert False

    # Is the change good enough?
    bypass_candidates = False
    if rec != autotag.RECOMMEND_NONE:
        match = candidates[0]
        bypass_candidates = True

    while True:
        # Display and choose from candidates.
        if not bypass_candidates:
            # Display list of candidates.
            if singleton:
                print_('Finding tags for track "%s - %s".' %
                       (item.artist, item.title))
                print_('Candidates:')
                for i, match in enumerate(candidates):
                    print_('%i. %s - %s (%s)' %
                           (i + 1, match.info.artist, match.info.title,
                            dist_string(match.distance, color)))
            else:
                print_('Finding tags for album "%s - %s".' %
                       (cur_artist, cur_album))
                print_('Candidates:')
                for i, match in enumerate(candidates):
                    line = '%i. %s - %s' % (i + 1, match.info.artist,
                                            match.info.album)

                    # Label and year disambiguation, if available.
                    label, year = None, None
                    if match.info.label:
                        label = match.info.label
                    if match.info.year:
                        year = unicode(match.info.year)
                    if label and year:
                        line += u' [%s, %s]' % (label, year)
                    elif label:
                        line += u' [%s]' % label
                    elif year:
                        line += u' [%s]' % year

                    line += ' (%s)' % dist_string(match.distance, color)

                    # Point out the partial matches.
                    if match.extra_items or match.extra_tracks:
                        warning = PARTIAL_MATCH_MESSAGE
                        if color:
                            warning = ui.colorize('yellow', warning)
                        line += u' %s' % warning

                    print_(line)

            # Ask the user for a choice.
            if singleton:
                opts = ('Skip', 'Use as-is', 'Enter search', 'enter Id',
                        'aBort')
            else:
                opts = ('Skip', 'Use as-is', 'as Tracks', 'Enter search',
                        'enter Id', 'aBort')
            sel = ui.input_options(opts, numrange=(1, len(candidates)),
                                   color=color)
            if sel == 's':
                return importer.action.SKIP
            elif sel == 'u':
                return importer.action.ASIS
            elif sel == 'e':
                return importer.action.MANUAL
            elif sel == 't':
                assert not singleton
                return importer.action.TRACKS
            elif sel == 'b':
                raise importer.ImportAbort()
            elif sel == 'i':
                return importer.action.MANUAL_ID
            else:  # Numerical selection.
                if singleton:
                    match = candidates[sel - 1]
                else:
                    match = candidates[sel - 1]
        bypass_candidates = False

        # Show what we're about to do.
        if singleton:
            show_item_change(item, match, color)
        else:
            show_change(cur_artist, cur_album, match, color,
                        per_disc_numbering)

        # Exact match => tag automatically if we're not in timid mode.
        if rec == autotag.RECOMMEND_STRONG and not timid:
            return match

        # Ask for confirmation.
        if singleton:
            opts = ('Apply', 'More candidates', 'Skip', 'Use as-is',
                    'Enter search', 'enter Id', 'aBort')
        else:
            opts = ('Apply', 'More candidates', 'Skip', 'Use as-is',
                    'as Tracks', 'Enter search', 'enter Id', 'aBort')
        sel = ui.input_options(opts, color=color)
        if sel == 'a':
            return match
        elif sel == 'm':
            pass
        elif sel == 's':
            return importer.action.SKIP
        elif sel == 'u':
            return importer.action.ASIS
        elif sel == 't':
            assert not singleton
            return importer.action.TRACKS
        elif sel == 'e':
            return importer.action.MANUAL
        elif sel == 'b':
            raise importer.ImportAbort()
        elif sel == 'i':
            return importer.action.MANUAL_ID
Ejemplo n.º 3
0
def choose_candidate(candidates, singleton, rec, color, timid,
                     cur_artist=None, cur_album=None, item=None):
    """Given a sorted list of candidates, ask the user for a selection
    of which candidate to use. Applies to both full albums and 
    singletons  (tracks). For albums, the candidates are `(dist, items,
    info)` triples and `cur_artist` and `cur_album` must be provided.
    For singletons, the candidates are `(dist, info)` pairs and `item`
    must be provided.

    Returns the result of the choice, which may SKIP, ASIS, TRACKS, or
    MANUAL or a candidate. For albums, a candidate is a `(info, items)`
    pair; for items, it is just a TrackInfo object.
    """
    # Sanity check.
    if singleton:
        assert item is not None
    else:
        assert cur_artist is not None
        assert cur_album is not None

    # Zero candidates.
    if not candidates:
        print_("No match found.")
        if singleton:
            opts = ('Use as-is', 'Skip', 'Enter search', 'enter Id',
                    'aBort')
        else:
            opts = ('Use as-is', 'as Tracks', 'Skip', 'Enter search',
                    'enter Id', 'aBort')
        sel = ui.input_options(opts, color=color)
        if sel == 'u':
            return importer.action.ASIS
        elif sel == 't':
            assert not singleton
            return importer.action.TRACKS
        elif sel == 'e':
            return importer.action.MANUAL
        elif sel == 's':
            return importer.action.SKIP
        elif sel == 'b':
            raise importer.ImportAbort()
        elif sel == 'i':
            return importer.action.MANUAL_ID
        else:
            assert False

    # Is the change good enough?
    bypass_candidates = False
    if rec != autotag.RECOMMEND_NONE:
        if singleton:
            dist, info = candidates[0]
        else:
            dist, items, info = candidates[0]
        bypass_candidates = True
        
    while True:
        # Display and choose from candidates.
        if not bypass_candidates:
            # Display list of candidates.
            if singleton:
                print_('Finding tags for track "%s - %s".' %
                       (item.artist, item.title))
                print_('Candidates:')
                for i, (dist, info) in enumerate(candidates):
                    print_('%i. %s - %s (%s)' % (i+1, info.artist,
                           info.title, dist_string(dist, color)))
            else:
                print_('Finding tags for album "%s - %s".' %
                       (cur_artist, cur_album))
                print_('Candidates:')
                for i, (dist, items, info) in enumerate(candidates):
                    line = '%i. %s - %s' % (i+1, info.artist, info.album)

                    # Label and year disambiguation, if available.
                    label, year = None, None
                    if info.label:
                        label = info.label
                    if info.year:
                        year = unicode(info.year)
                    if label and year:
                        line += u' [%s, %s]' % (label, year)
                    elif label:
                        line += u' [%s]' % label
                    elif year:
                        line += u' [%s]' % year

                    line += ' (%s)' % dist_string(dist, color)

                    # Point out the partial matches.
                    if None in items:
                        warning = PARTIAL_MATCH_MESSAGE
                        if color:
                            warning = ui.colorize('yellow', warning)
                        line += u' %s' % warning

                    print_(line)
                                            
            # Ask the user for a choice.
            if singleton:
                opts = ('Skip', 'Use as-is', 'Enter search', 'enter Id',
                        'aBort')
            else:
                opts = ('Skip', 'Use as-is', 'as Tracks', 'Enter search',
                        'enter Id', 'aBort')
            sel = ui.input_options(opts, numrange=(1, len(candidates)),
                                   color=color)
            if sel == 's':
                return importer.action.SKIP
            elif sel == 'u':
                return importer.action.ASIS
            elif sel == 'e':
                return importer.action.MANUAL
            elif sel == 't':
                assert not singleton
                return importer.action.TRACKS
            elif sel == 'b':
                raise importer.ImportAbort()
            elif sel == 'i':
                return importer.action.MANUAL_ID
            else: # Numerical selection.
                if singleton:
                    dist, info = candidates[sel-1]
                else:
                    dist, items, info = candidates[sel-1]
        bypass_candidates = False
    
        # Show what we're about to do.
        if singleton:
            show_item_change(item, info, dist, color)
        else:
            show_change(cur_artist, cur_album, items, info, dist, color)
    
        # Exact match => tag automatically if we're not in timid mode.
        if rec == autotag.RECOMMEND_STRONG and not timid:
            if singleton:
                return info
            else:
                return info, items
        
        # Ask for confirmation.
        if singleton:
            opts = ('Apply', 'More candidates', 'Skip', 'Use as-is',
                    'Enter search', 'enter Id', 'aBort')
        else:
            opts = ('Apply', 'More candidates', 'Skip', 'Use as-is',
                    'as Tracks', 'Enter search', 'enter Id', 'aBort')
        sel = ui.input_options(opts, color=color)
        if sel == 'a':
            if singleton:
                return info
            else:
                return info, items
        elif sel == 'm':
            pass
        elif sel == 's':
            return importer.action.SKIP
        elif sel == 'u':
            return importer.action.ASIS
        elif sel == 't':
            assert not singleton
            return importer.action.TRACKS
        elif sel == 'e':
            return importer.action.MANUAL
        elif sel == 'b':
            raise importer.ImportAbort()
        elif sel == 'i':
            return importer.action.MANUAL_ID
Ejemplo n.º 4
0
def choose_candidate(candidates,
                     singleton,
                     rec,
                     color,
                     timid,
                     cur_artist=None,
                     cur_album=None,
                     item=None,
                     itemcount=None,
                     per_disc_numbering=False):
    """Given a sorted list of candidates, ask the user for a selection
    of which candidate to use. Applies to both full albums and
    singletons  (tracks). Candidates are either AlbumMatch or TrackMatch
    objects depending on `singleton`. for albums, `cur_artist`,
    `cur_album`, and `itemcount` must be provided. For singletons,
    `item` must be provided.

    Returns the result of the choice, which may SKIP, ASIS, TRACKS, or
    MANUAL or a candidate (an AlbumMatch/TrackMatch object).
    """
    # Sanity check.
    if singleton:
        assert item is not None
    else:
        assert cur_artist is not None
        assert cur_album is not None

    # Zero candidates.
    if not candidates:
        if singleton:
            print_("No matching recordings found.")
            opts = ('Use as-is', 'Skip', 'Enter search', 'enter Id', 'aBort')
        else:
            print_(
                "No matching release found for {0} tracks.".format(itemcount))
            print_('For help, see: '
                   'https://github.com/sampsyo/beets/wiki/FAQ#wiki-nomatch')
            opts = ('Use as-is', 'as Tracks', 'Skip', 'Enter search',
                    'enter Id', 'aBort')
        sel = ui.input_options(opts, color=color)
        if sel == 'u':
            return importer.action.ASIS
        elif sel == 't':
            assert not singleton
            return importer.action.TRACKS
        elif sel == 'e':
            return importer.action.MANUAL
        elif sel == 's':
            return importer.action.SKIP
        elif sel == 'b':
            raise importer.ImportAbort()
        elif sel == 'i':
            return importer.action.MANUAL_ID
        else:
            assert False

    # Is the change good enough?
    bypass_candidates = False
    if rec != autotag.RECOMMEND_NONE:
        match = candidates[0]
        bypass_candidates = True

    while True:
        # Display and choose from candidates.
        if not bypass_candidates:
            # Display list of candidates.
            if singleton:
                print_('Finding tags for track "%s - %s".' %
                       (item.artist, item.title))
                print_('Candidates:')
                for i, match in enumerate(candidates):
                    print_('%i. %s - %s (%s)' %
                           (i + 1, match.info.artist, match.info.title,
                            dist_string(match.distance, color)))
            else:
                print_('Finding tags for album "%s - %s".' %
                       (cur_artist, cur_album))
                print_('Candidates:')
                for i, match in enumerate(candidates):
                    line = '%i. %s - %s' % (i + 1, match.info.artist,
                                            match.info.album)

                    # Label and year disambiguation, if available.
                    label, year = None, None
                    if match.info.label:
                        label = match.info.label
                    if match.info.year:
                        year = unicode(match.info.year)
                    if label and year:
                        line += u' [%s, %s]' % (label, year)
                    elif label:
                        line += u' [%s]' % label
                    elif year:
                        line += u' [%s]' % year

                    line += ' (%s)' % dist_string(match.distance, color)

                    # Point out the partial matches.
                    if match.extra_items or match.extra_tracks:
                        warning = PARTIAL_MATCH_MESSAGE
                        if color:
                            warning = ui.colorize('yellow', warning)
                        line += u' %s' % warning

                    print_(line)

            # Ask the user for a choice.
            if singleton:
                opts = ('Skip', 'Use as-is', 'Enter search', 'enter Id',
                        'aBort')
            else:
                opts = ('Skip', 'Use as-is', 'as Tracks', 'Enter search',
                        'enter Id', 'aBort')
            sel = ui.input_options(opts,
                                   numrange=(1, len(candidates)),
                                   color=color)
            if sel == 's':
                return importer.action.SKIP
            elif sel == 'u':
                return importer.action.ASIS
            elif sel == 'e':
                return importer.action.MANUAL
            elif sel == 't':
                assert not singleton
                return importer.action.TRACKS
            elif sel == 'b':
                raise importer.ImportAbort()
            elif sel == 'i':
                return importer.action.MANUAL_ID
            else:  # Numerical selection.
                if singleton:
                    match = candidates[sel - 1]
                else:
                    match = candidates[sel - 1]
        bypass_candidates = False

        # Show what we're about to do.
        if singleton:
            show_item_change(item, match, color)
        else:
            show_change(cur_artist, cur_album, match, color,
                        per_disc_numbering)

        # Exact match => tag automatically if we're not in timid mode.
        if rec == autotag.RECOMMEND_STRONG and not timid:
            return match

        # Ask for confirmation.
        if singleton:
            opts = ('Apply', 'More candidates', 'Skip', 'Use as-is',
                    'Enter search', 'enter Id', 'aBort')
        else:
            opts = ('Apply', 'More candidates', 'Skip', 'Use as-is',
                    'as Tracks', 'Enter search', 'enter Id', 'aBort')
        sel = ui.input_options(opts, color=color)
        if sel == 'a':
            return match
        elif sel == 'm':
            pass
        elif sel == 's':
            return importer.action.SKIP
        elif sel == 'u':
            return importer.action.ASIS
        elif sel == 't':
            assert not singleton
            return importer.action.TRACKS
        elif sel == 'e':
            return importer.action.MANUAL
        elif sel == 'b':
            raise importer.ImportAbort()
        elif sel == 'i':
            return importer.action.MANUAL_ID