smarter MBID input (based on patch by derwin)

This commit is contained in:
Adrian Sampson 2011-10-07 15:33:19 -07:00
parent b62b462b1e
commit ec49fca4dc
3 changed files with 55 additions and 13 deletions

View file

@ -21,6 +21,7 @@ import sys
import os
import time
import itertools
import re
from beets import ui
from beets.ui import print_, decargs
@ -387,10 +388,20 @@ def manual_search(singleton):
return artist.strip(), name.strip()
def manual_id(singleton):
"""Input a MusicBrainz ID, either for an album or a track.
"""Input a MusicBrainz ID, either for an album ("release") or a
track ("recording"). If no valid ID is entered, returns None.
"""
prompt = 'Enter MusicBrainz %s ID: ' % ('track' if singleton else 'album')
return raw_input(prompt).decode(sys.stdin.encoding).strip()
prompt = 'Enter MusicBrainz %s ID: ' % \
('recording' if singleton else 'release')
entry = raw_input(prompt).decode(sys.stdin.encoding).strip()
# Find the first thing that looks like a UUID/MBID.
match = re.search('[a-f0-9]{8}(-[a-f0-9]{4}){3}-[a-f0-9]{12}', entry)
if match:
return match.group()
else:
log.error('Invalid MBID.')
return None
def choose_match(task, config):
"""Given an initial autotagging of items, go through an interactive
@ -436,12 +447,13 @@ def choose_match(task, config):
elif choice is importer.action.MANUAL_ID:
# Try a manually-entered ID.
search_id = manual_id(False)
try:
_, _, candidates, rec = \
autotag.tag_album(task.items, config.timid,
search_id=search_id)
except autotag.AutotagError:
candidates, rec = None, None
if search_id:
try:
_, _, candidates, rec = \
autotag.tag_album(task.items, config.timid,
search_id=search_id)
except autotag.AutotagError:
candidates, rec = None, None
else:
# We have a candidate! Finish tagging. Here, choice is
# an (info, items) pair as desired.
@ -482,8 +494,9 @@ def choose_item(task, config):
elif choice == importer.action.MANUAL_ID:
# Ask for a track ID.
search_id = manual_id(True)
candidates, rec = autotag.tag_item(task.item, config.timid,
search_id=search_id)
if search_id:
candidates, rec = autotag.tag_item(task.item, config.timid,
search_id=search_id)
else:
# Chose a candidate.
assert not isinstance(choice, importer.action)

View file

@ -7,6 +7,9 @@ Changelog
* The new :doc:`/plugins/lastgenre` automatically assigns genres to imported
albums and items based on Last.fm tags and an internal whitelist. (Thanks to
`KraYmer`_.)
* When entering an ID manually during tagging, beets now searches for anything
that looks like an MBID in the entered string. This means that full
MusicBrainz URLs now work as IDs at the prompt. (Thanks to derwin.)
.. _KraYmer: https://github.com/KraYmer

View file

@ -18,9 +18,9 @@ import unittest
import os
import shutil
import textwrap
import logging
from StringIO import StringIO
import _common
from beets import library
from beets import ui
from beets.ui import commands
@ -28,6 +28,8 @@ from beets import autotag
from beets import importer
from beets.mediafile import MediaFile
import _common
class ListTest(unittest.TestCase):
def setUp(self):
self.io = _common.DummyIO()
@ -502,7 +504,7 @@ class ConfigTest(unittest.TestCase):
library: /xxx/yyy/not/a/real/path
"""), func)
class UtilTest(unittest.TestCase):
class ShowdiffTest(unittest.TestCase):
def setUp(self):
self.io = _common.DummyIO()
self.io.install()
@ -554,6 +556,30 @@ class UtilTest(unittest.TestCase):
self.assertEqual(complete_diff, partial_diff)
AN_ID = "28e32c71-1450-463e-92bf-e0a46446fc11"
class ManualIDTest(unittest.TestCase):
def setUp(self):
_common.log.setLevel(logging.CRITICAL)
self.io = _common.DummyIO()
self.io.install()
def tearDown(self):
self.io.restore()
def test_id_accepted(self):
self.io.addinput(AN_ID)
out = commands.manual_id(False)
self.assertEqual(out, AN_ID)
def test_non_id_returns_none(self):
self.io.addinput("blah blah")
out = commands.manual_id(False)
self.assertEqual(out, None)
def test_url_finds_id(self):
self.io.addinput("http://musicbrainz.org/entity/%s?something" % AN_ID)
out = commands.manual_id(False)
self.assertEqual(out, AN_ID)
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)