-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into atomic-move-fix
- Loading branch information
Showing
16 changed files
with
360 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
# This file is part of beets. | ||
# | ||
# Permission is hereby granted, free of charge, to any person obtaining | ||
# a copy of this software and associated documentation files (the | ||
# "Software"), to deal in the Software without restriction, including | ||
# without limitation the rights to use, copy, modify, merge, publish, | ||
# distribute, sublicense, and/or sell copies of the Software, and to | ||
# permit persons to whom the Software is furnished to do so, subject to | ||
# the following conditions: | ||
# | ||
# The above copyright notice and this permission notice shall be | ||
# included in all copies or substantial portions of the Software. | ||
|
||
"""Adds head/tail functionality to list/ls. | ||
1. Implemented as `lslimit` command with `--head` and `--tail` options. This is | ||
the idiomatic way to use this plugin. | ||
2. Implemented as query prefix `<` for head functionality only. This is the | ||
composable way to use the plugin (plays nicely with anything that uses the | ||
query language). | ||
""" | ||
|
||
from beets.dbcore import FieldQuery | ||
from beets.plugins import BeetsPlugin | ||
from beets.ui import Subcommand, decargs, print_ | ||
from collections import deque | ||
from itertools import islice | ||
|
||
|
||
def lslimit(lib, opts, args): | ||
"""Query command with head/tail.""" | ||
|
||
if (opts.head is not None) and (opts.tail is not None): | ||
raise ValueError("Only use one of --head and --tail") | ||
if (opts.head or opts.tail or 0) < 0: | ||
raise ValueError("Limit value must be non-negative") | ||
|
||
query = decargs(args) | ||
if opts.album: | ||
objs = lib.albums(query) | ||
else: | ||
objs = lib.items(query) | ||
|
||
if opts.head is not None: | ||
objs = islice(objs, opts.head) | ||
elif opts.tail is not None: | ||
objs = deque(objs, opts.tail) | ||
|
||
for obj in objs: | ||
print_(format(obj)) | ||
|
||
|
||
lslimit_cmd = Subcommand( | ||
"lslimit", | ||
help="query with optional head or tail" | ||
) | ||
|
||
lslimit_cmd.parser.add_option( | ||
"--head", | ||
action="store", | ||
type="int", | ||
default=None | ||
) | ||
|
||
lslimit_cmd.parser.add_option( | ||
"--tail", | ||
action="store", | ||
type="int", | ||
default=None | ||
) | ||
|
||
lslimit_cmd.parser.add_all_common_options() | ||
lslimit_cmd.func = lslimit | ||
|
||
|
||
class LimitPlugin(BeetsPlugin): | ||
"""Query limit functionality via command and query prefix.""" | ||
|
||
def commands(self): | ||
"""Expose `lslimit` subcommand.""" | ||
return [lslimit_cmd] | ||
|
||
def queries(self): | ||
|
||
class HeadQuery(FieldQuery): | ||
"""This inner class pattern allows the query to track state.""" | ||
n = 0 | ||
N = None | ||
|
||
@classmethod | ||
def value_match(cls, pattern, value): | ||
if cls.N is None: | ||
cls.N = int(pattern) | ||
if cls.N < 0: | ||
raise ValueError("Limit value must be non-negative") | ||
cls.n += 1 | ||
return cls.n <= cls.N | ||
|
||
return { | ||
"<": HeadQuery | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -98,6 +98,7 @@ following to your configuration:: | |
kodiupdate | ||
lastgenre | ||
lastimport | ||
limit | ||
loadext | ||
lyrics | ||
mbcollection | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
Limit Query Plugin | ||
================== | ||
|
||
``limit`` is a plugin to limit a query to the first or last set of | ||
results. We also provide a query prefix ``'<n'`` to inline the same | ||
behavior in the ``list`` command. They are analagous to piping results: | ||
|
||
$ beet [list|ls] [QUERY] | [head|tail] -n n | ||
|
||
There are two provided interfaces: | ||
|
||
1. ``beet lslimit [--head n | --tail n] [QUERY]`` returns the head or | ||
tail of a query | ||
|
||
2. ``beet [list|ls] [QUERY] '<n'`` returns the head of a query | ||
|
||
There are two differences in behavior: | ||
|
||
1. The query prefix does not support tail. | ||
|
||
2. The query prefix could appear anywhere in the query but will only | ||
have the same behavior as the ``lslimit`` command and piping to ``head`` | ||
when it appears last. | ||
|
||
Performance for the query previx is much worse due to the current | ||
singleton-based implementation. | ||
|
||
So why does the query prefix exist? Because it composes with any other | ||
query-based API or plugin (see :doc:`/reference/query`). For example, | ||
you can use the query prefix in ``smartplaylist`` | ||
(see :doc:`/plugins/smartplaylist`) to limit the number of tracks in a smart | ||
playlist for applications like most played and recently added. | ||
|
||
Configuration | ||
============= | ||
|
||
Enable the ``limit`` plugin in your configuration (see | ||
:ref:`using-plugins`). | ||
|
||
Examples | ||
======== | ||
|
||
First 10 tracks | ||
|
||
$ beet ls | head -n 10 | ||
$ beet lslimit --head 10 | ||
$ beet ls '<10' | ||
|
||
Last 10 tracks | ||
|
||
$ beet ls | tail -n 10 | ||
$ beet lslimit --tail 10 | ||
|
||
100 mostly recently released tracks | ||
|
||
$ beet lslimit --head 100 year- month- day- | ||
$ beet ls year- month- day- '<100' | ||
$ beet lslimit --tail 100 year+ month+ day+ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.