Skip to content

Commit

Permalink
Merge pull request #46 from geigerzaehler/list-command
Browse files Browse the repository at this point in the history
Add list-tracks command
  • Loading branch information
wisp3rwind committed Feb 5, 2020
2 parents 8cc37a9 + 5f7a84a commit b4a7865
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 8 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
Change Log
==========

## Upcoming
* Add `beet alt list-tracks` command

## v0.10.1 - 2019-09-18
* Running `beet completion` does not crash anymore [#38][]

Expand Down
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,17 @@ The command accepts the following option.
command will ask you to confirm the creation of the external
collection. These options specify the answer as a cli option.

```
beet alt list-tracks [--format=FORMAT] NAME
```

Lists all tracks that are currently included in the collection.

The `--format` option accepts a [beets path format][path-format] string that is
used to format each track.

[path-format]: https://beets.readthedocs.io/en/latest/reference/pathformat.html

Configuration
-------------

Expand Down Expand Up @@ -241,7 +252,7 @@ following settings.
of the external collection. (optional)

* **`link_type`** Can be `absolute` (default) or `relative`. If
**`formats`** is `link`, it sets the type of links to create. For
**`formats`** is `link`, it sets the type of links to create. For
differences between link types and examples see [Symlink Views](#symlink-views).


Expand Down
43 changes: 40 additions & 3 deletions beetsplug/alternatives.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
import beets
from beets import util, art
from beets.plugins import BeetsPlugin
from beets.ui import Subcommand, get_path_formats, input_yn, UserError, print_
from beets.ui import Subcommand, get_path_formats, input_yn, UserError, \
print_, decargs
from beets.library import parse_query_string, Item
from beets.util import syspath, displayable_path, cpu_count, bytestring_path

Expand All @@ -43,6 +44,19 @@ def update(self, lib, options):
.format(e.args[0]))
alt.update(create=options.create)

def list_tracks(self, lib, options):
if options.format is not None:
fmt, = decargs([options.format])
beets.config[beets.library.Item._format_config_key].set(fmt)

alt = self.alternative(options.name, lib)

# This is slow but we cannot use a native SQL query since the
# path key is a flexible attribute
for item in lib.items():
if alt.path_key in item:
print_(format(item))

def alternative(self, name, lib):
conf = self.config[name]
if not conf.exists():
Expand All @@ -67,14 +81,36 @@ def __init__(self, plugin):
parser = ArgumentParser()
subparsers = parser.add_subparsers(prog=parser.prog + ' alt')
subparsers.required = True
subparsers.dest = 'update'

update = subparsers.add_parser('update')
update.set_defaults(func=plugin.update)
update.add_argument('name')
update.add_argument('name', metavar='NAME')
update.add_argument('--create', action='store_const',
dest='create', const=True)
update.add_argument('--no-create', action='store_const',
dest='create', const=False)

list_tracks = subparsers.add_parser(
'list-tracks',
description="""
List all tracks that are currently part of an alternative
collection""",
)
list_tracks.set_defaults(func=plugin.list_tracks)
list_tracks.add_argument(
'name',
metavar='NAME',
help='Name of the alternative',
)
list_tracks.add_argument(
'-f',
'--format',
metavar='FORMAT',
dest='format',
help="""Format string to print for each track. See beets’
Path Formats for more information.""",
)

super(AlternativesCommand, self).__init__(self.name, parser, self.help)

def func(self, lib, opts, _):
Expand All @@ -89,6 +125,7 @@ class ArgumentParser(argparse.ArgumentParser):
Facade for ``argparse.ArgumentParser`` so that beets can call
`_get_all_options()` to generate shell completion.
"""

def _get_all_options(self):
# FIXME return options like ``OptionParser._get_all_options``.
return []
Expand Down
19 changes: 15 additions & 4 deletions test/cli_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ def test_external(self):
self.add_album(artist='Beethoven', title='was ogg', format='ogg')

external_from_mp3 = bytestring_path(
os.path.join(external_dir, 'Bach', 'was mp3.mp3'))
os.path.join(external_dir, 'Bach', 'was mp3.mp3'))
external_from_m4a = bytestring_path(
os.path.join(external_dir, 'Bach', 'was m4a.m4a'))
os.path.join(external_dir, 'Bach', 'was m4a.m4a'))
external_from_ogg = bytestring_path(
os.path.join(external_dir, 'Bach', 'was ogg.m4a'))
os.path.join(external_dir, 'Bach', 'was ogg.m4a'))
external_beet = bytestring_path(
os.path.join(external_dir, 'Beethoven', 'was ogg.m4a'))
os.path.join(external_dir, 'Beethoven', 'was ogg.m4a'))

self.runcli('modify', '--yes', 'onplayer=true', 'artist:Bach')
with control_stdin('y'):
Expand All @@ -60,6 +60,12 @@ def test_external(self):
self.assertFalse(os.path.isfile(external_beet))

self.runcli('modify', '--yes', 'composer=JSB', 'artist:Bach')

list_output = self.runcli(
'alt', 'list-tracks', 'myplayer', '--format', '$artist $title')
self.assertEqual(list_output, '\n'.join(
['Bach was mp3', 'Bach was m4a', 'Bach was ogg', '']))

self.runcli('alt', 'update', 'myplayer')
mediafile = MediaFile(syspath(external_from_ogg))
self.assertEqual(mediafile.composer, 'JSB')
Expand All @@ -69,6 +75,10 @@ def test_external(self):
'onplayer=true', 'albumartist:Beethoven')
self.runcli('alt', 'update', 'myplayer')

list_output = self.runcli(
'alt', 'list-tracks', 'myplayer', '--format', '$artist')
self.assertEqual(list_output, 'Beethoven\n')

self.assertFalse(os.path.isfile(external_from_mp3))
self.assertFalse(os.path.isfile(external_from_m4a))
self.assertFalse(os.path.isfile(external_from_ogg))
Expand Down Expand Up @@ -544,5 +554,6 @@ class CompletionTest(TestHelper):
Only ensures that command does not fail.
"""

def test_completion(self):
self.runcli('completion')

0 comments on commit b4a7865

Please sign in to comment.