mirror of
https://github.com/beetbox/beets.git
synced 2025-12-15 21:14:19 +01:00
Adding limit and its documentation
This commit is contained in:
parent
736443708b
commit
cdb6b21f1a
2 changed files with 147 additions and 0 deletions
95
beetsplug/limit.py
Normal file
95
beetsplug/limit.py
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
# 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.
|
||||
|
||||
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"""
|
||||
|
||||
head = opts.head
|
||||
tail = opts.tail
|
||||
|
||||
if head and tail:
|
||||
raise RuntimeError("Only use one of --head and --tail")
|
||||
|
||||
query = decargs(args)
|
||||
if opts.album:
|
||||
objs = lib.albums(query)
|
||||
else:
|
||||
objs = lib.items(query)
|
||||
|
||||
if head:
|
||||
objs = islice(objs, head)
|
||||
elif tail:
|
||||
objs = deque(objs, 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 LsLimitPlugin(BeetsPlugin):
|
||||
def commands(self):
|
||||
return [lslimit_cmd]
|
||||
|
||||
|
||||
class HeadPlugin(BeetsPlugin):
|
||||
"""Head of an arbitrary query.
|
||||
|
||||
This allows a user to limit the results of any query to the first
|
||||
`pattern` rows. Example usage: return first 10 tracks `beet ls '<10'`.
|
||||
"""
|
||||
|
||||
def queries(self):
|
||||
|
||||
class HeadQuery(FieldQuery):
|
||||
"""Singleton query implementation that tracks result count."""
|
||||
n = 0
|
||||
include = True
|
||||
@classmethod
|
||||
def value_match(cls, pattern, value):
|
||||
cls.n += 1
|
||||
if cls.include:
|
||||
cls.include = cls.n <= int(pattern)
|
||||
return cls.include
|
||||
|
||||
return {
|
||||
"<": HeadQuery
|
||||
}
|
||||
52
docs/plugins/limit.rst
Normal file
52
docs/plugins/limit.rst
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
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 ``smartplaylists`` (see :doc:`/plugins/
|
||||
smartplaylists`) to limit the number of tracks in a smart playlist for
|
||||
applications like most played and recently added.
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
||||
Enable the ``last`` plugin in your configuration (see
|
||||
:ref:`using-plugins`).
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
First 10 tracks
|
||||
|
||||
$ beet ls | head -n 10
|
||||
$ beet lslimit --head 10
|
||||
$ beet ls '<10'
|
||||
|
||||
100 mostly recently released tracks
|
||||
|
||||
$ beet lslimit --tail 100 year+ month+ day+
|
||||
$ beet ls year- month- day- '<100'
|
||||
Loading…
Reference in a new issue