Ejemplo n.º 1
0
 def test_item_data_change_with_unicode(self):
     items, info = self._items_and_info()
     items[0].title = u'caf\xe9'
     commands.show_change('the artist', 'the album',
                          items, info, 0.1, color=False)
     msg = self.io.getoutput().lower()
     self.assertTrue(u'caf\xe9 -> the title' in msg.decode('utf8'))
Ejemplo n.º 2
0
 def test_null_change(self):
     items, info = self._items_and_info()
     commands.show_change('the artist', 'the album',
                          items, info, 0.1, color=False)
     msg = self.io.getoutput().lower()
     self.assertTrue('similarity: 90' in msg)
     self.assertTrue('tagging:' in msg)
Ejemplo n.º 3
0
 def test_item_data_change_with_unicode(self):
     items, info = self._items_and_info()
     items[0].title = u'caf\xe9'
     commands.show_change('the artist', 'the album',
                          items, info, 0.1, color=False)
     msg = self.io.getoutput().lower()
     self.assertTrue(u'caf\xe9 -> the title' in msg.decode('utf8'))
Ejemplo n.º 4
0
 def test_item_data_change_title_missing(self):
     items, info = self._items_and_info()
     items[0].title = ''
     commands.show_change('the artist', 'the album',
                          items, info, 0.1, color=False)
     msg = self.io.getoutput().lower()
     self.assertTrue('file.mp3 -> the title' in msg)
Ejemplo n.º 5
0
 def test_null_change(self):
     items, info = self._items_and_info()
     commands.show_change('the artist', 'the album',
                          items, info, 0.1, color=False)
     msg = self.io.getoutput().lower()
     self.assertTrue('similarity: 90' in msg)
     self.assertTrue('tagging:' in msg)
Ejemplo n.º 6
0
 def _show_change(self, items=None, info=None, cur_artist="the artist", cur_album="the album", dist=0.1):
     items = items or self.items
     info = info or self.info
     mapping = dict(zip(items, info.tracks))
     config["color"] = False
     commands.show_change(cur_artist, cur_album, autotag.AlbumMatch(0.1, info, mapping, set(), set()))
     return self.io.getoutput().lower()
Ejemplo n.º 7
0
 def test_item_data_change_title_missing(self):
     items, info = self._items_and_info()
     items[0].title = ''
     commands.show_change('the artist', 'the album',
                          items, info, 0.1, color=False)
     msg = self.io.getoutput().lower()
     self.assertTrue('file.mp3 -> the title' in msg)
Ejemplo n.º 8
0
 def test_item_data_change_title_missing_with_unicode_filename(self):
     items, info = self._items_and_info()
     items[0].title = ""
     items[0].path = u"/path/to/caf\xe9.mp3".encode("utf8")
     commands.show_change("the artist", "the album", items, info, 0.1, color=False)
     msg = self.io.getoutput().lower()
     self.assertTrue(u"caf\xe9.mp3 -> the title" in msg.decode("utf8"))
Ejemplo n.º 9
0
 def test_item_data_change_title_missing_with_unicode_filename(self):
     items, info = self._items_and_info()
     items[0].title = ''
     items[0].path = u'/path/to/caf\xe9.mp3'.encode('utf8')
     commands.show_change('the artist', 'the album',
                          items, info, 0.1, color=False)
     msg = self.io.getoutput().lower()
     self.assertTrue(u'caf\xe9.mp3 -> the title' in msg.decode('utf8'))
Ejemplo n.º 10
0
 def test_item_data_change_title_missing_with_unicode_filename(self):
     items, info = self._items_and_info()
     items[0].title = ''
     items[0].path = u'/path/to/caf\xe9.mp3'.encode('utf8')
     commands.show_change('the artist', 'the album',
                          items, info, 0.1, color=False)
     msg = self.io.getoutput().lower()
     self.assertTrue(u'caf\xe9.mp3 -> the title' in msg.decode('utf8'))
Ejemplo n.º 11
0
 def _show_change(self, items=None, info=None, cur_artist=u"the artist", cur_album=u"the album", dist=0.1):
     items = items or self.items
     info = info or self.info
     mapping = dict(zip(items, info.tracks))
     config["color"] = False
     album_dist = distance(items, info, mapping)
     album_dist._penalties = {"album": [dist]}
     commands.show_change(cur_artist, cur_album, autotag.AlbumMatch(album_dist, info, mapping, set(), set()))
     return self.io.getoutput().lower()
Ejemplo n.º 12
0
 def test_album_data_change_with_unicode(self):
     items, info = self._items_and_info()
     commands.show_change(u'caf\xe9',
                          u'another album',
                          items,
                          info,
                          0.1,
                          color=False)
     msg = self.io.getoutput().lower()
     self.assertTrue('correcting tags from:' in msg)
Ejemplo n.º 13
0
 def _show_change(self, items=None, info=None, cur_artist="the artist", cur_album="the album", dist=0.1):
     """Return an unicode string representing the changes"""
     items = items or self.items
     info = info or self.info
     mapping = dict(zip(items, info.tracks))
     config["ui"]["color"] = False
     album_dist = distance(items, info, mapping)
     album_dist._penalties = {"album": [dist]}
     commands.show_change(cur_artist, cur_album, autotag.AlbumMatch(album_dist, info, mapping, set(), set()))
     # FIXME decoding shouldn't be done here
     return self.io.getoutput().lower().decode("utf8")
Ejemplo n.º 14
0
 def _show_change(self, items=None, info=None,
                  cur_artist='the artist', cur_album='the album',
                  dist=0.1):
     items = items or self.items
     info = info or self.info
     mapping = dict(zip(items, info.tracks))
     commands.show_change(
         cur_artist,
         cur_album,
         autotag.AlbumMatch(0.1, info, mapping, set(), set()),
         color=False,
     )
     return self.io.getoutput().lower()
Ejemplo n.º 15
0
 def _show_change(self, items=None, info=None,
                  cur_artist='the artist', cur_album='the album',
                  dist=0.1):
     items = items or self.items
     info = info or self.info
     mapping = dict(zip(items, info.tracks))
     commands.show_change(
         _common.iconfig(None),
         cur_artist,
         cur_album,
         autotag.AlbumMatch(0.1, info, mapping, set(), set()),
         color=False,
     )
     return self.io.getoutput().lower()
Ejemplo n.º 16
0
 def _show_change(self, items=None, info=None,
                  cur_artist=u'the artist', cur_album=u'the album',
                  dist=0.1):
     items = items or self.items
     info = info or self.info
     mapping = dict(zip(items, info.tracks))
     config['color'] = False
     album_dist = distance(items, info, mapping)
     album_dist._penalties = {'album': [dist]}
     commands.show_change(
         cur_artist,
         cur_album,
         autotag.AlbumMatch(album_dist, info, mapping, set(), set()),
     )
     return self.io.getoutput().lower()
Ejemplo n.º 17
0
 def _show_change(self, items=None, info=None,
                  cur_artist=u'the artist', cur_album=u'the album',
                  dist=0.1):
     """Return an unicode string representing the changes"""
     items = items or self.items
     info = info or self.info
     mapping = dict(zip(items, info.tracks))
     config['ui']['color'] = False
     album_dist = distance(items, info, mapping)
     album_dist._penalties = {'album': [dist]}
     commands.show_change(
         cur_artist,
         cur_album,
         autotag.AlbumMatch(album_dist, info, mapping, set(), set()),
     )
     # FIXME decoding shouldn't be done here
     return util.text_string(self.io.getoutput().lower())
Ejemplo n.º 18
0
 def _show_change(self, items=None, info=None,
                  cur_artist=u'the artist', cur_album=u'the album',
                  dist=0.1):
     """Return an unicode string representing the changes"""
     items = items or self.items
     info = info or self.info
     mapping = dict(zip(items, info.tracks))
     config['ui']['color'] = False
     album_dist = distance(items, info, mapping)
     album_dist._penalties = {'album': [dist]}
     commands.show_change(
         cur_artist,
         cur_album,
         autotag.AlbumMatch(album_dist, info, mapping, set(), set()),
     )
     # FIXME decoding shouldn't be done here
     return self.io.getoutput().lower().decode('utf8')
Ejemplo n.º 19
0
 def test_item_data_change_with_unicode(self):
     items, info = self._items_and_info()
     items[0].title = u"caf\xe9"
     commands.show_change("the artist", "the album", items, info, 0.1, color=False)
     msg = self.io.getoutput().lower()
     self.assertTrue(u"caf\xe9 -> the title" in msg.decode("utf8"))
Ejemplo n.º 20
0
 def test_album_data_change_with_unicode(self):
     items, info = self._items_and_info()
     commands.show_change(u'caf\xe9', u'another album',
                          items, info, 0.1, color=False)
     msg = self.io.getoutput().lower()
     self.assertTrue('correcting tags from:' in msg)
Ejemplo n.º 21
0
 def test_album_data_change(self):
     items, info = self._items_and_info()
     commands.show_change("another artist", "another album", items, info, 0.1, color=False)
     msg = self.io.getoutput().lower()
     self.assertTrue("correcting tags from:" in msg)
Ejemplo n.º 22
0
 def test_item_data_change(self):
     items, info = self._items_and_info()
     items[0].title = "different"
     commands.show_change("the artist", "the album", items, info, 0.1, color=False)
     msg = self.io.getoutput().lower()
     self.assertTrue("different -> the title" in msg)
Ejemplo n.º 23
0
def choose_candidate(candidates,
                     singleton,
                     rec,
                     cur_artist=None,
                     cur_album=None,
                     item=None,
                     itemcount=None,
                     extra_choices=[]):
    """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.

    `extra_choices` is a list of `PromptChoice`s, containg the choices
    appended by the plugins after receiving the `before_choose_candidate`
    event. If not empty, the choices are appended to the prompt presented
    to the user.

    Returns one of the following:
    * the result of the choice, which may be SKIP, ASIS, TRACKS, or MANUAL
    * a candidate (an AlbumMatch/TrackMatch object)
    * the short letter of a `PromptChoice` (if the user selected one of
    the `extra_choices`).
    """
    # Sanity check.
    assert not singleton
    assert cur_artist is not None
    assert cur_album is not None

    # Zero candidates.
    if not candidates:
        print_(u"No matching release found for {0} tracks.".format(itemcount))
        print_(u'For help, see: '
               u'http://beets.readthedocs.org/en/latest/faq.html#nomatch')
        opts = (u'Skip', u'Enter search', u'enter Id', u'aBort')
        sel = ui.input_options(opts)
        if sel == u'e':
            return importer.action.MANUAL
        elif sel == u's':
            return importer.action.SKIP
        elif sel == u'b':
            raise importer.ImportAbort()
        elif sel == u'i':
            return importer.action.MANUAL_ID
        else:
            assert False

    while True:
        # Display and choose from candidates.
        require = rec <= Recommendation.low

        # Display list of candidates.
        print_(u'Finding tags for {0} "{1} - {2}".'.format(
            u'album',
            cur_artist,
            cur_album,
        ))

        print_(u'Candidates:')
        for i, match in enumerate(candidates):
            # Index, metadata, and distance.
            line = [
                u'{0}.'.format(i + 1),
                u'{0} - {1}'.format(
                    match.info.artist,
                    match.info.album,
                ),
                u'({0})'.format(dist_string(match.distance)),
            ]

            # Penalties.
            penalties = penalty_string(match.distance, 3)
            if penalties:
                line.append(penalties)

            # Disambiguation
            disambig = disambig_string(match.info)
            if disambig:
                line.append(
                    ui.colorize('text_highlight_minor', u'(%s)' % disambig))

            print_(u' '.join(line))

        # Ask the user for a choice.
        opts = (u'Skip', u'Enter search', u'enter Id', u'aBort')
        sel = ui.input_options(opts, numrange=(1, len(candidates)))
        if sel == u's':
            return importer.action.SKIP
        elif sel == u'e':
            return importer.action.MANUAL
        elif sel == u'b':
            raise importer.ImportAbort()
        elif sel == u'i':
            return importer.action.MANUAL_ID
        else:  # Numerical selection.
            match = candidates[sel - 1]
            if sel != 1:
                # When choosing anything but the first match,
                # disable the default action.
                require = True

        # Show what we're about to do.
        show_change(cur_artist, cur_album, match)

        # Exact match => tag automatically.
        if rec == Recommendation.strong:
            return match

        # Ask for confirmation.
        opts = (u'Apply', u'More candidates', u'Skip', u'Enter search',
                u'enter Id', u'aBort')
        default = config['import']['default_action'].as_choice({
            u'apply': u'a',
            u'skip': u's',
            u'none': None,
        })
        if default is None:
            require = True
        sel = ui.input_options(opts, require=require, default=default)
        if sel == u'a':
            return match
        elif sel == u's':
            return importer.action.SKIP
        elif sel == u'e':
            return importer.action.MANUAL
        elif sel == u'b':
            raise importer.ImportAbort()
        elif sel == u'i':
            return importer.action.MANUAL_ID