Merge pull request #1578 from nathdwek/play-raw

beets-play: Add the option to pass the "raw" queried pathes to the player command
This commit is contained in:
Adrian Sampson 2015-09-02 12:31:43 -07:00
commit 7087f8cf00
5 changed files with 33 additions and 18 deletions

View file

@ -1485,7 +1485,7 @@ def config_edit():
try:
if not os.path.isfile(path):
open(path, 'w+').close()
util.interactive_open(path, editor)
util.interactive_open([path], editor)
except OSError as exc:
message = "Could not edit configuration: {0}".format(exc)
if not editor:

View file

@ -735,8 +735,8 @@ def open_anything():
return base_cmd
def interactive_open(target, command=None):
"""Open the file `target` by `exec`ing a new command. (The new
def interactive_open(targets, command=None):
"""Open the files in `targets` by `exec`ing a new command. (The new
program takes over, and Python execution ends: this does not fork a
subprocess.)
@ -757,5 +757,6 @@ def interactive_open(target, command=None):
base_cmd = open_anything()
command = [base_cmd, base_cmd]
command.append(target)
command += targets
return os.execlp(*command)

View file

@ -39,6 +39,7 @@ class PlayPlugin(BeetsPlugin):
'command': None,
'use_folders': False,
'relative_to': None,
'raw': False,
})
def commands(self):
@ -62,6 +63,7 @@ class PlayPlugin(BeetsPlugin):
command_str = config['play']['command'].get()
use_folders = config['play']['use_folders'].get(bool)
relative_to = config['play']['relative_to'].get()
raw = config['play']['raw'].get(bool)
if relative_to:
relative_to = util.normpath(relative_to)
@ -91,6 +93,8 @@ class PlayPlugin(BeetsPlugin):
else:
selection = lib.items(ui.decargs(args))
paths = [item.path for item in selection]
if relative_to:
paths = [relpath(path, relative_to) for path in paths]
item_type = 'track'
item_type += 's' if len(selection) > 1 else ''
@ -111,22 +115,29 @@ class PlayPlugin(BeetsPlugin):
if ui.input_options(('Continue', 'Abort')) == 'a':
return
# Create temporary m3u file to hold our playlist.
m3u = NamedTemporaryFile('w', suffix='.m3u', delete=False)
for item in paths:
if relative_to:
m3u.write(relpath(item, relative_to) + b'\n')
else:
m3u.write(item + b'\n')
m3u.close()
ui.print_(u'Playing {0} {1}.'.format(len(selection), item_type))
if raw:
open_args = paths
else:
open_args = self._create_tmp_playlist(paths)
self._log.debug('executing command: {} {}', command_str, m3u.name)
self._log.debug('executing command: {} {}', command_str,
b'"' + b' '.join(open_args) + b'"')
try:
util.interactive_open(m3u.name, command_str)
util.interactive_open(open_args, command_str)
except OSError as exc:
raise ui.UserError("Could not play the music playlist: "
"{0}".format(exc))
finally:
util.remove(m3u.name)
if not raw:
self._log.debug('Removing temporary playlist: {}',
open_args[0])
util.remove(open_args[0])
def _create_tmp_playlist(self, paths_list):
# Create temporary m3u file to hold our playlist.
m3u = NamedTemporaryFile('w', suffix='.m3u', delete=False)
for item in paths_list:
m3u.write(item + b'\n')
m3u.close()
return [m3u.name]

View file

@ -44,6 +44,9 @@ configuration file. The available options are:
paths to each track on the matched albums. Enable this option to
store paths to folders instead.
Default: ``no``.
- **raw**: Instead of creating a temporary m3u playlist and then opening it,
simply call the command with the paths returned by the query as arguments.
Default: ``no``.
Optional Arguments
------------------

View file

@ -43,11 +43,11 @@ class UtilTest(unittest.TestCase):
@patch('beets.util.open_anything')
def test_interactive_open(self, mock_open, mock_execlp):
mock_open.return_value = 'tagada'
util.interactive_open('foo')
util.interactive_open(['foo'])
mock_execlp.assert_called_once_with('tagada', 'tagada', 'foo')
mock_execlp.reset_mock()
util.interactive_open('foo', 'bar')
util.interactive_open(['foo'], 'bar')
mock_execlp.assert_called_once_with('bar', 'bar', 'foo')
def test_sanitize_unix_replaces_leading_dot(self):