mirror of
https://github.com/beetbox/beets.git
synced 2025-12-06 16:42:42 +01:00
use print_function __future__ import
All code should now use Python 3-style "print"s.
This commit is contained in:
parent
f6b37d2c8c
commit
429af42e14
15 changed files with 77 additions and 64 deletions
|
|
@ -12,16 +12,13 @@
|
||||||
# The above copyright notice and this permission notice shall be
|
# The above copyright notice and this permission notice shall be
|
||||||
# included in all copies or substantial portions of the Software.
|
# included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
"""Finding album art for tagged albums."""
|
"""Finding album art for tagged albums.
|
||||||
|
"""
|
||||||
import urllib
|
import urllib
|
||||||
import sys
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from beets.autotag.mb import album_for_id
|
|
||||||
|
|
||||||
IMAGE_EXTENSIONS = ['png', 'jpg', 'jpeg']
|
IMAGE_EXTENSIONS = ['png', 'jpg', 'jpeg']
|
||||||
COVER_NAMES = ['cover', 'front', 'art', 'album', 'folder']
|
COVER_NAMES = ['cover', 'front', 'art', 'album', 'folder']
|
||||||
|
|
||||||
|
|
@ -134,19 +131,3 @@ def art_for_album(album, path):
|
||||||
else:
|
else:
|
||||||
log.debug('No ASIN available: no art found.')
|
log.debug('No ASIN available: no art found.')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
# Smoke test.
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
aid = sys.argv[1]
|
|
||||||
album = album_for_id(aid)
|
|
||||||
if not album:
|
|
||||||
print 'album not found'
|
|
||||||
else:
|
|
||||||
fn = art_for_album(album, None)
|
|
||||||
if fn:
|
|
||||||
print fn
|
|
||||||
print len(open(fn).read())/1024
|
|
||||||
else:
|
|
||||||
print 'no art found'
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@
|
||||||
"""Provides the basic, interface-agnostic workflow for importing and
|
"""Provides the basic, interface-agnostic workflow for importing and
|
||||||
autotagging music files.
|
autotagging music files.
|
||||||
"""
|
"""
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
import pickle
|
import pickle
|
||||||
|
|
@ -55,7 +57,7 @@ def tag_log(logfile, status, path):
|
||||||
reflect the reason the album couldn't be tagged.
|
reflect the reason the album couldn't be tagged.
|
||||||
"""
|
"""
|
||||||
if logfile:
|
if logfile:
|
||||||
print >>logfile, '%s %s' % (status, path)
|
print('{0} {1}'.format(status, path), file=logfile)
|
||||||
logfile.flush()
|
logfile.flush()
|
||||||
|
|
||||||
def log_choice(config, task, duplicate=False):
|
def log_choice(config, task, duplicate=False):
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@
|
||||||
interface. To invoke the CLI, just call beets.ui.main(). The actual
|
interface. To invoke the CLI, just call beets.ui.main(). The actual
|
||||||
CLI commands are implemented in the ui.commands module.
|
CLI commands are implemented in the ui.commands module.
|
||||||
"""
|
"""
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import locale
|
import locale
|
||||||
import optparse
|
import optparse
|
||||||
|
|
@ -106,7 +108,7 @@ def print_(*strings):
|
||||||
txt = u''
|
txt = u''
|
||||||
if isinstance(txt, unicode):
|
if isinstance(txt, unicode):
|
||||||
txt = txt.encode(_encoding(), 'replace')
|
txt = txt.encode(_encoding(), 'replace')
|
||||||
print txt
|
print(txt)
|
||||||
|
|
||||||
def input_options(options, require=False, prompt=None, fallback_prompt=None,
|
def input_options(options, require=False, prompt=None, fallback_prompt=None,
|
||||||
numrange=None, default=None, color=False, max_width=72):
|
numrange=None, default=None, color=False, max_width=72):
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@
|
||||||
"""This module provides the default commands for beets' command-line
|
"""This module provides the default commands for beets' command-line
|
||||||
interface.
|
interface.
|
||||||
"""
|
"""
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|
@ -87,10 +89,10 @@ def _showdiff(field, oldval, newval, color):
|
||||||
fields_cmd = ui.Subcommand('fields',
|
fields_cmd = ui.Subcommand('fields',
|
||||||
help='show fields available for queries and format strings')
|
help='show fields available for queries and format strings')
|
||||||
def fields_func(lib, config, opts, args):
|
def fields_func(lib, config, opts, args):
|
||||||
print "Available item fields:"
|
print("Available item fields:")
|
||||||
print " " + "\n ".join([key for key in library.ITEM_KEYS])
|
print(" " + "\n ".join([key for key in library.ITEM_KEYS]))
|
||||||
print "\nAvailable album fields:"
|
print("\nAvailable album fields:")
|
||||||
print " " + "\n ".join([key for key in library.ALBUM_KEYS])
|
print(" " + "\n ".join([key for key in library.ALBUM_KEYS]))
|
||||||
|
|
||||||
fields_cmd.func = fields_func
|
fields_cmd.func = fields_func
|
||||||
default_commands.append(fields_cmd)
|
default_commands.append(fields_cmd)
|
||||||
|
|
@ -651,7 +653,7 @@ def import_files(lib, paths, copy, move, write, autot, logpath, art, threaded,
|
||||||
except IOError:
|
except IOError:
|
||||||
raise ui.UserError(u"could not open log file for writing: %s" %
|
raise ui.UserError(u"could not open log file for writing: %s" %
|
||||||
displayable_path(logpath))
|
displayable_path(logpath))
|
||||||
print >>logfile, 'import started', time.asctime()
|
print('import started', time.asctime(), file=logfile)
|
||||||
else:
|
else:
|
||||||
logfile = None
|
logfile = None
|
||||||
|
|
||||||
|
|
@ -690,7 +692,7 @@ def import_files(lib, paths, copy, move, write, autot, logpath, art, threaded,
|
||||||
finally:
|
finally:
|
||||||
# If we were logging, close the file.
|
# If we were logging, close the file.
|
||||||
if logfile:
|
if logfile:
|
||||||
print >>logfile, ''
|
print('', file=logfile)
|
||||||
logfile.close()
|
logfile.close()
|
||||||
|
|
||||||
# Emit event.
|
# Emit event.
|
||||||
|
|
@ -1035,16 +1037,16 @@ default_commands.append(stats_cmd)
|
||||||
# version: Show current beets version.
|
# version: Show current beets version.
|
||||||
|
|
||||||
def show_version(lib, config, opts, args):
|
def show_version(lib, config, opts, args):
|
||||||
print 'beets version %s' % beets.__version__
|
print_('beets version %s' % beets.__version__)
|
||||||
# Show plugins.
|
# Show plugins.
|
||||||
names = []
|
names = []
|
||||||
for plugin in plugins.find_plugins():
|
for plugin in plugins.find_plugins():
|
||||||
modname = plugin.__module__
|
modname = plugin.__module__
|
||||||
names.append(modname.split('.')[-1])
|
names.append(modname.split('.')[-1])
|
||||||
if names:
|
if names:
|
||||||
print 'plugins:', ', '.join(names)
|
print_('plugins:', ', '.join(names))
|
||||||
else:
|
else:
|
||||||
print 'no plugins loaded'
|
print_('no plugins loaded')
|
||||||
version_cmd = ui.Subcommand('version',
|
version_cmd = ui.Subcommand('version',
|
||||||
help='output version information')
|
help='output version information')
|
||||||
version_cmd.func = show_version
|
version_cmd.func = show_version
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ class Enumerated(object):
|
||||||
>>> class Garment(Enumerated):
|
>>> class Garment(Enumerated):
|
||||||
... values = 'hat glove belt poncho lederhosen suspenders'
|
... values = 'hat glove belt poncho lederhosen suspenders'
|
||||||
... def wear(self):
|
... def wear(self):
|
||||||
... print 'now wearing a ' + self.name
|
... print('now wearing a ' + self.name)
|
||||||
...
|
...
|
||||||
>>> Garment.poncho.wear()
|
>>> Garment.poncho.wear()
|
||||||
now wearing a poncho
|
now wearing a poncho
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ library: unknown symbols are left intact.
|
||||||
This is sort of like a tiny, horrible degeneration of a real templating
|
This is sort of like a tiny, horrible degeneration of a real templating
|
||||||
engine like Jinja2 or Mustache.
|
engine like Jinja2 or Mustache.
|
||||||
"""
|
"""
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import ast
|
import ast
|
||||||
import dis
|
import dis
|
||||||
|
|
@ -548,9 +550,9 @@ if __name__ == '__main__':
|
||||||
interp_time = timeit.timeit('_tmpl.interpret(_vars, _funcs)',
|
interp_time = timeit.timeit('_tmpl.interpret(_vars, _funcs)',
|
||||||
'from __main__ import _tmpl, _vars, _funcs',
|
'from __main__ import _tmpl, _vars, _funcs',
|
||||||
number=10000)
|
number=10000)
|
||||||
print interp_time
|
print(interp_time)
|
||||||
comp_time = timeit.timeit('_tmpl.substitute(_vars, _funcs)',
|
comp_time = timeit.timeit('_tmpl.substitute(_vars, _funcs)',
|
||||||
'from __main__ import _tmpl, _vars, _funcs',
|
'from __main__ import _tmpl, _vars, _funcs',
|
||||||
number=10000)
|
number=10000)
|
||||||
print comp_time
|
print(comp_time)
|
||||||
print 'Speedup:', interp_time / comp_time
|
print('Speedup:', interp_time / comp_time)
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,8 @@ up a bottleneck stage by dividing its work among multiple threads.
|
||||||
To do so, pass an iterable of coroutines to the Pipeline constructor
|
To do so, pass an iterable of coroutines to the Pipeline constructor
|
||||||
in place of any single coroutine.
|
in place of any single coroutine.
|
||||||
"""
|
"""
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import Queue
|
import Queue
|
||||||
from threading import Thread, Lock
|
from threading import Thread, Lock
|
||||||
import sys
|
import sys
|
||||||
|
|
@ -392,20 +394,20 @@ if __name__ == '__main__':
|
||||||
# in parallel.
|
# in parallel.
|
||||||
def produce():
|
def produce():
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
print 'generating %i' % i
|
print('generating %i' % i)
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
yield i
|
yield i
|
||||||
def work():
|
def work():
|
||||||
num = yield
|
num = yield
|
||||||
while True:
|
while True:
|
||||||
print 'processing %i' % num
|
print('processing %i' % num)
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
num = yield num*2
|
num = yield num*2
|
||||||
def consume():
|
def consume():
|
||||||
while True:
|
while True:
|
||||||
num = yield
|
num = yield
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
print 'received %i' % num
|
print('received %i' % num)
|
||||||
ts_start = time.time()
|
ts_start = time.time()
|
||||||
Pipeline([produce(), work(), consume()]).run_sequential()
|
Pipeline([produce(), work(), consume()]).run_sequential()
|
||||||
ts_seq = time.time()
|
ts_seq = time.time()
|
||||||
|
|
@ -413,21 +415,21 @@ if __name__ == '__main__':
|
||||||
ts_par = time.time()
|
ts_par = time.time()
|
||||||
Pipeline([produce(), (work(), work()), consume()]).run_parallel()
|
Pipeline([produce(), (work(), work()), consume()]).run_parallel()
|
||||||
ts_end = time.time()
|
ts_end = time.time()
|
||||||
print 'Sequential time:', ts_seq - ts_start
|
print('Sequential time:', ts_seq - ts_start)
|
||||||
print 'Parallel time:', ts_par - ts_seq
|
print('Parallel time:', ts_par - ts_seq)
|
||||||
print 'Multiply-parallel time:', ts_end - ts_par
|
print('Multiply-parallel time:', ts_end - ts_par)
|
||||||
print
|
print()
|
||||||
|
|
||||||
# Test a pipeline that raises an exception.
|
# Test a pipeline that raises an exception.
|
||||||
def exc_produce():
|
def exc_produce():
|
||||||
for i in range(10):
|
for i in range(10):
|
||||||
print 'generating %i' % i
|
print('generating %i' % i)
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
yield i
|
yield i
|
||||||
def exc_work():
|
def exc_work():
|
||||||
num = yield
|
num = yield
|
||||||
while True:
|
while True:
|
||||||
print 'processing %i' % num
|
print('processing %i' % num)
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
if num == 3:
|
if num == 3:
|
||||||
raise Exception()
|
raise Exception()
|
||||||
|
|
@ -437,5 +439,5 @@ if __name__ == '__main__':
|
||||||
num = yield
|
num = yield
|
||||||
#if num == 4:
|
#if num == 4:
|
||||||
# raise Exception()
|
# raise Exception()
|
||||||
print 'received %i' % num
|
print('received %i' % num)
|
||||||
Pipeline([exc_produce(), exc_work(), exc_consume()]).run_parallel(1)
|
Pipeline([exc_produce(), exc_work(), exc_consume()]).run_parallel(1)
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,10 @@
|
||||||
# The above copyright notice and this permission notice shall be
|
# The above copyright notice and this permission notice shall be
|
||||||
# included in all copies or substantial portions of the Software.
|
# included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
"""Some simple performance benchmarks for beets.
|
||||||
|
"""
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
from beets.plugins import BeetsPlugin
|
from beets.plugins import BeetsPlugin
|
||||||
from beets import ui
|
from beets import ui
|
||||||
from beets import vfs
|
from beets import vfs
|
||||||
|
|
@ -34,7 +38,7 @@ def benchmark(lib, prof):
|
||||||
'paths.withaunique.prof')
|
'paths.withaunique.prof')
|
||||||
else:
|
else:
|
||||||
interval = timeit.timeit(_build_tree, number=1)
|
interval = timeit.timeit(_build_tree, number=1)
|
||||||
print 'With %aunique:', interval
|
print('With %aunique:', interval)
|
||||||
|
|
||||||
# And with %aunique replaceed with a "cheap" no-op function.
|
# And with %aunique replaceed with a "cheap" no-op function.
|
||||||
lib.path_formats = [
|
lib.path_formats = [
|
||||||
|
|
@ -46,7 +50,7 @@ def benchmark(lib, prof):
|
||||||
'paths.withoutaunique.prof')
|
'paths.withoutaunique.prof')
|
||||||
else:
|
else:
|
||||||
interval = timeit.timeit(_build_tree, number=1)
|
interval = timeit.timeit(_build_tree, number=1)
|
||||||
print 'Without %aunique:', interval
|
print('Without %aunique:', interval)
|
||||||
|
|
||||||
class BenchmarkPlugin(BeetsPlugin):
|
class BenchmarkPlugin(BeetsPlugin):
|
||||||
"""A plugin for performing some simple performance benchmarks.
|
"""A plugin for performing some simple performance benchmarks.
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
Beets library. Attempts to implement a compatible protocol to allow
|
Beets library. Attempts to implement a compatible protocol to allow
|
||||||
use of the wide range of MPD clients.
|
use of the wide range of MPD clients.
|
||||||
"""
|
"""
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import bluelet
|
import bluelet
|
||||||
import re
|
import re
|
||||||
|
|
@ -536,7 +537,7 @@ class BaseServer(object):
|
||||||
"""Memory profiling for debugging."""
|
"""Memory profiling for debugging."""
|
||||||
from guppy import hpy
|
from guppy import hpy
|
||||||
heap = hpy().heap()
|
heap = hpy().heap()
|
||||||
print heap
|
print(heap)
|
||||||
|
|
||||||
class Connection(object):
|
class Connection(object):
|
||||||
"""A connection between a client and the server. Handles input and
|
"""A connection between a client and the server. Handles input and
|
||||||
|
|
@ -789,9 +790,9 @@ class Server(BaseServer):
|
||||||
"""
|
"""
|
||||||
# Path is ignored. Also, the real MPD does this asynchronously;
|
# Path is ignored. Also, the real MPD does this asynchronously;
|
||||||
# this is done inline.
|
# this is done inline.
|
||||||
print 'Building directory tree...'
|
print('Building directory tree...')
|
||||||
self.tree = vfs.libtree(self.lib)
|
self.tree = vfs.libtree(self.lib)
|
||||||
print '... done.'
|
print('... done.')
|
||||||
self.updated_time = time.time()
|
self.updated_time = time.time()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
"""A wrapper for the GStreamer Python bindings that exposes a simple
|
"""A wrapper for the GStreamer Python bindings that exposes a simple
|
||||||
music player.
|
music player.
|
||||||
"""
|
"""
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import gst
|
import gst
|
||||||
import sys
|
import sys
|
||||||
|
|
@ -83,7 +84,7 @@ class GstPlayer(object):
|
||||||
# error
|
# error
|
||||||
self.player.set_state(gst.STATE_NULL)
|
self.player.set_state(gst.STATE_NULL)
|
||||||
err, debug = message.parse_error()
|
err, debug = message.parse_error()
|
||||||
print "Error: " + str(err)
|
print("Error: " + str(err))
|
||||||
self.playing = False
|
self.playing = False
|
||||||
|
|
||||||
def _set_volume(self, volume):
|
def _set_volume(self, volume):
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
"""Fetches, embeds, and displays lyrics.
|
"""Fetches, embeds, and displays lyrics.
|
||||||
"""
|
"""
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import urllib
|
import urllib
|
||||||
import re
|
import re
|
||||||
import logging
|
import logging
|
||||||
|
|
@ -83,7 +85,7 @@ def extract_text(html, starttag):
|
||||||
parts.append(html[pos:match.start()])
|
parts.append(html[pos:match.start()])
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
print 'no closing tag found!'
|
print('no closing tag found!')
|
||||||
return
|
return
|
||||||
lyrics = ''.join(parts)
|
lyrics = ''.join(parts)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@
|
||||||
#ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
#ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
#OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
#OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
from beets.plugins import BeetsPlugin
|
from beets.plugins import BeetsPlugin
|
||||||
from beets.ui import Subcommand
|
from beets.ui import Subcommand
|
||||||
from beets import ui
|
from beets import ui
|
||||||
|
|
@ -44,9 +46,9 @@ def update_collection(lib, config, opts, args):
|
||||||
albums = [a.mb_albumid for a in lib.albums() if a.mb_albumid]
|
albums = [a.mb_albumid for a in lib.albums() if a.mb_albumid]
|
||||||
|
|
||||||
# Submit to MusicBrainz.
|
# Submit to MusicBrainz.
|
||||||
print 'Updating MusicBrainz collection {0}...'.format(collection_id)
|
print('Updating MusicBrainz collection {0}...'.format(collection_id))
|
||||||
submit_albums(collection_id, albums)
|
submit_albums(collection_id, albums)
|
||||||
print '...MusicBrainz collection updated.'
|
print('...MusicBrainz collection updated.')
|
||||||
|
|
||||||
update_mb_collection_cmd = Subcommand('mbupdate',
|
update_mb_collection_cmd = Subcommand('mbupdate',
|
||||||
help='Update MusicBrainz collection')
|
help='Update MusicBrainz collection')
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ Put something like the following in your .beetsconfig to configure:
|
||||||
port = 6600
|
port = 6600
|
||||||
password = seekrit
|
password = seekrit
|
||||||
"""
|
"""
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
from beets.plugins import BeetsPlugin
|
from beets.plugins import BeetsPlugin
|
||||||
from beets import ui
|
from beets import ui
|
||||||
|
|
@ -60,20 +61,20 @@ def update_mpd(host='localhost', port=6600, password=None):
|
||||||
"""Sends the "update" command to the MPD server indicated,
|
"""Sends the "update" command to the MPD server indicated,
|
||||||
possibly authenticating with a password first.
|
possibly authenticating with a password first.
|
||||||
"""
|
"""
|
||||||
print 'Updating MPD database...'
|
print('Updating MPD database...')
|
||||||
|
|
||||||
s = BufferedSocket()
|
s = BufferedSocket()
|
||||||
s.connect(host, port)
|
s.connect(host, port)
|
||||||
resp = s.readline()
|
resp = s.readline()
|
||||||
if 'OK MPD' not in resp:
|
if 'OK MPD' not in resp:
|
||||||
print 'MPD connection failed:', repr(resp)
|
print('MPD connection failed:', repr(resp))
|
||||||
return
|
return
|
||||||
|
|
||||||
if password:
|
if password:
|
||||||
s.send('password "%s"\n' % password)
|
s.send('password "%s"\n' % password)
|
||||||
resp = s.readline()
|
resp = s.readline()
|
||||||
if 'OK' not in resp:
|
if 'OK' not in resp:
|
||||||
print 'Authentication failed:', repr(resp)
|
print('Authentication failed:', repr(resp))
|
||||||
s.send('close\n')
|
s.send('close\n')
|
||||||
s.close()
|
s.close()
|
||||||
return
|
return
|
||||||
|
|
@ -81,11 +82,11 @@ def update_mpd(host='localhost', port=6600, password=None):
|
||||||
s.send('update\n')
|
s.send('update\n')
|
||||||
resp = s.readline()
|
resp = s.readline()
|
||||||
if 'updating_db' not in resp:
|
if 'updating_db' not in resp:
|
||||||
print 'Update failed:', repr(resp)
|
print('Update failed:', repr(resp))
|
||||||
|
|
||||||
s.send('close\n')
|
s.send('close\n')
|
||||||
s.close()
|
s.close()
|
||||||
print '... updated.'
|
print('... updated.')
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
'host': 'localhost',
|
'host': 'localhost',
|
||||||
|
|
|
||||||
|
|
@ -12,14 +12,13 @@
|
||||||
# The above copyright notice and this permission notice shall be
|
# The above copyright notice and this permission notice shall be
|
||||||
# included in all copies or substantial portions of the Software.
|
# included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
"""Get a random song or album from the library.
|
||||||
|
"""
|
||||||
from beets.plugins import BeetsPlugin
|
from beets.plugins import BeetsPlugin
|
||||||
from beets.ui import Subcommand, decargs, print_
|
from beets.ui import Subcommand, decargs, print_
|
||||||
from beets.util.functemplate import Template
|
from beets.util.functemplate import Template
|
||||||
import random
|
import random
|
||||||
|
|
||||||
"""Get a random song or album from the library.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def random_item(lib, config, opts, args):
|
def random_item(lib, config, opts, args):
|
||||||
query = decargs(args)
|
query = decargs(args)
|
||||||
path = opts.path
|
path = opts.path
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
|
import StringIO
|
||||||
|
|
||||||
import _common
|
import _common
|
||||||
from _common import unittest
|
from _common import unittest
|
||||||
|
|
@ -827,6 +828,17 @@ class ArtFetchTest(unittest.TestCase, _common.ExtraAsserts):
|
||||||
art.art_for_album = lambda a, b: artdest
|
art.art_for_album = lambda a, b: artdest
|
||||||
self._fetch_art(True)
|
self._fetch_art(True)
|
||||||
|
|
||||||
|
class TagLogTest(unittest.TestCase):
|
||||||
|
def test_tag_log_line(self):
|
||||||
|
sio = StringIO.StringIO()
|
||||||
|
importer.tag_log(sio, 'status', 'path')
|
||||||
|
assert 'status path' in sio.getvalue()
|
||||||
|
|
||||||
|
def test_tag_log_unicode(self):
|
||||||
|
sio = StringIO.StringIO()
|
||||||
|
importer.tag_log(sio, 'status', 'caf\xc3\xa9')
|
||||||
|
assert 'status caf' in sio.getvalue()
|
||||||
|
|
||||||
def suite():
|
def suite():
|
||||||
return unittest.TestLoader().loadTestsFromName(__name__)
|
return unittest.TestLoader().loadTestsFromName(__name__)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue