mirror of
https://github.com/beetbox/beets.git
synced 2025-12-24 17:43:52 +01:00
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:
commit
7087f8cf00
5 changed files with 33 additions and 18 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
------------------
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
Loading…
Reference in a new issue