mirror of
https://github.com/beetbox/beets.git
synced 2025-12-15 21:14:19 +01:00
merge
This commit is contained in:
commit
f53a06ddf1
7 changed files with 46 additions and 15 deletions
1
NEWS
1
NEWS
|
|
@ -62,6 +62,7 @@
|
|||
reuse by plugins (e.g., the FUSE plugin).
|
||||
* Singleton imports ("beet import -s") can now take individual files as
|
||||
arguments as well as directories.
|
||||
* Fix Unicode queries given on the command line.
|
||||
* Fix crasher in quiet singleton imports (import -qs).
|
||||
* Fix crash when autotagging files with no metadata.
|
||||
* Fix a rare deadlock when finishing the import pipeline.
|
||||
|
|
|
|||
|
|
@ -52,6 +52,21 @@ class UserError(Exception):
|
|||
|
||||
# Utilities.
|
||||
|
||||
def _encoding():
|
||||
"""Tries to guess the encoding uses by the terminal."""
|
||||
try:
|
||||
return locale.getdefaultlocale()[1] or 'utf8'
|
||||
except ValueError:
|
||||
# Invalid locale environment variable setting. To avoid
|
||||
# failing entirely for no good reason, assume UTF-8.
|
||||
return 'utf8'
|
||||
|
||||
def decargs(arglist):
|
||||
"""Given a list of command-line argument bytestrings, attempts to
|
||||
decode them to Unicode strings.
|
||||
"""
|
||||
return [s.decode(_encoding()) for s in arglist]
|
||||
|
||||
def print_(*strings):
|
||||
"""Like print, but rather than raising an error when a character
|
||||
is not in the terminal's encoding's character set, just silently
|
||||
|
|
@ -65,13 +80,7 @@ def print_(*strings):
|
|||
else:
|
||||
txt = u''
|
||||
if isinstance(txt, unicode):
|
||||
try:
|
||||
encoding = locale.getdefaultlocale()[1] or 'utf8'
|
||||
except ValueError:
|
||||
# Invalid locale environment variable setting. To avoid
|
||||
# failing entirely for no good reason, assume UTF-8.
|
||||
encoding = 'utf8'
|
||||
txt = txt.encode(encoding, 'replace')
|
||||
txt = txt.encode(_encoding(), 'replace')
|
||||
print txt
|
||||
|
||||
def input_options(options, require=False, prompt=None, fallback_prompt=None,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import os
|
|||
import time
|
||||
|
||||
from beets import ui
|
||||
from beets.ui import print_
|
||||
from beets.ui import print_, decargs
|
||||
from beets import autotag
|
||||
import beets.autotag.art
|
||||
from beets import plugins
|
||||
|
|
@ -622,7 +622,7 @@ list_cmd.parser.add_option('-a', '--album', action='store_true',
|
|||
list_cmd.parser.add_option('-p', '--path', action='store_true',
|
||||
help='print paths for matched items or albums')
|
||||
def list_func(lib, config, opts, args):
|
||||
list_items(lib, args, opts.album, opts.path)
|
||||
list_items(lib, decargs(args), opts.album, opts.path)
|
||||
list_cmd.func = list_func
|
||||
default_commands.append(list_cmd)
|
||||
|
||||
|
|
@ -677,7 +677,7 @@ remove_cmd.parser.add_option("-d", "--delete", action="store_true",
|
|||
remove_cmd.parser.add_option('-a', '--album', action='store_true',
|
||||
help='match albums instead of tracks')
|
||||
def remove_func(lib, config, opts, args):
|
||||
remove_items(lib, args, opts.album, opts.delete)
|
||||
remove_items(lib, decargs(args), opts.album, opts.delete)
|
||||
remove_cmd.func = remove_func
|
||||
default_commands.append(remove_cmd)
|
||||
|
||||
|
|
@ -718,7 +718,7 @@ Albums: %i""" % (
|
|||
stats_cmd = ui.Subcommand('stats',
|
||||
help='show statistics about the library or a query')
|
||||
def stats_func(lib, config, opts, args):
|
||||
show_stats(lib, args)
|
||||
show_stats(lib, decargs(args))
|
||||
stats_cmd.func = stats_func
|
||||
default_commands.append(stats_cmd)
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import imghdr
|
|||
from beets.plugins import BeetsPlugin
|
||||
from beets import mediafile
|
||||
from beets import ui
|
||||
from beets.ui import decargs
|
||||
from beets.util import syspath, normpath
|
||||
|
||||
log = logging.getLogger('beets')
|
||||
|
|
@ -41,7 +42,7 @@ class EmbedCoverArtPlugin(BeetsPlugin):
|
|||
if not args:
|
||||
raise ui.UserError('specify an image file')
|
||||
imagepath = normpath(args.pop(0))
|
||||
embed(lib, imagepath, args)
|
||||
embed(lib, imagepath, decargs(args))
|
||||
embed_cmd.func = embed_func
|
||||
|
||||
# Extract command.
|
||||
|
|
@ -51,14 +52,14 @@ class EmbedCoverArtPlugin(BeetsPlugin):
|
|||
help='image output file')
|
||||
def extract_func(lib, config, opts, args):
|
||||
outpath = normpath(opts.outpath or 'cover')
|
||||
extract(lib, outpath, args)
|
||||
extract(lib, outpath, decargs(args))
|
||||
extract_cmd.func = extract_func
|
||||
|
||||
# Clear command.
|
||||
clear_cmd = ui.Subcommand('clearart',
|
||||
help='remove images from file metadata')
|
||||
def clear_func(lib, config, opts, args):
|
||||
clear(lib, args)
|
||||
clear(lib, decargs(args))
|
||||
clear_cmd.func = clear_func
|
||||
|
||||
return [embed_cmd, extract_cmd, clear_cmd]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
"""Some common functionality for beets' test cases."""
|
||||
# This file is part of beets.
|
||||
# Copyright 2011, Adrian Sampson.
|
||||
#
|
||||
|
|
@ -13,6 +12,7 @@
|
|||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
|
||||
"""Some common functionality for beets' test cases."""
|
||||
import time
|
||||
import sys
|
||||
import os
|
||||
|
|
|
|||
|
|
@ -215,6 +215,16 @@ class MemoryGetTest(unittest.TestCase, AssertsMixin):
|
|||
names = [a.album for a in results]
|
||||
self.assertEqual(names, ['the album'])
|
||||
|
||||
def test_unicode_query(self):
|
||||
self.single_item.title = u'caf\xe9'
|
||||
self.lib.store(self.single_item)
|
||||
self.lib.save()
|
||||
|
||||
q = u'title:caf\xe9'
|
||||
results = self.lib.items(q)
|
||||
self.assert_matched(results, u'caf\xe9')
|
||||
self.assert_done(results)
|
||||
|
||||
class PathQueryTest(unittest.TestCase, AssertsMixin):
|
||||
def setUp(self):
|
||||
self.lib = beets.library.Library(':memory:')
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ class ListTest(unittest.TestCase):
|
|||
i.path = 'xxx/yyy'
|
||||
self.lib.add(i)
|
||||
self.lib.add_album([i])
|
||||
self.item = i
|
||||
|
||||
def tearDown(self):
|
||||
self.io.restore()
|
||||
|
|
@ -46,6 +47,15 @@ class ListTest(unittest.TestCase):
|
|||
out = self.io.getoutput()
|
||||
self.assertTrue(u'the title' in out)
|
||||
|
||||
def test_list_unicode_query(self):
|
||||
self.item.title = u'na\xefve'
|
||||
self.lib.store(self.item)
|
||||
self.lib.save()
|
||||
|
||||
commands.list_items(self.lib, [u'na\xefve'], False, False)
|
||||
out = self.io.getoutput()
|
||||
self.assertTrue(u'na\xefve' in out.decode(self.io.stdout.encoding))
|
||||
|
||||
def test_list_item_path(self):
|
||||
commands.list_items(self.lib, '', False, True)
|
||||
out = self.io.getoutput()
|
||||
|
|
|
|||
Loading…
Reference in a new issue