mirror of
https://github.com/beetbox/beets.git
synced 2026-01-05 23:43:31 +01:00
added list and count
--HG-- extra : convert_revision : svn%3A41726ec3-264d-0410-9c23-a9f1637257cc/trunk%40184
This commit is contained in:
parent
70cb2d4e60
commit
7d10b76169
3 changed files with 70 additions and 21 deletions
|
|
@ -373,6 +373,17 @@ class Query(object):
|
|||
clause, subvals = self.clause()
|
||||
return ('SELECT ' + columns + ' FROM items WHERE ' + clause, subvals)
|
||||
|
||||
def count(self, library):
|
||||
"""Returns `(num, length)` where `num` is the number of items in
|
||||
the library matching this query and `length` is their total
|
||||
length in seconds.
|
||||
"""
|
||||
clause, subvals = self.clause()
|
||||
statement = 'SELECT COUNT(id), SUM(length) FROM items WHERE ' + clause
|
||||
c = library.conn.cursor()
|
||||
result = c.execute(statement, subvals).fetchone()
|
||||
return (result[0], result[1])
|
||||
|
||||
def execute(self, library):
|
||||
"""Runs the query in the specified library, returning a
|
||||
ResultIterator.
|
||||
|
|
|
|||
|
|
@ -858,31 +858,32 @@ class Server(BaseServer):
|
|||
|
||||
|
||||
def cmd_stats(self, conn):
|
||||
# The first three items need to be done more efficiently. The
|
||||
# last three need to be implemented.
|
||||
# The first two items need to be done more efficiently.
|
||||
songs, totaltime = beets.library.TrueQuery().count(self.lib)
|
||||
conn.send('artists: ' + str(len(self.lib.artists())),
|
||||
'albums: ' + str(len(self.lib.albums())),
|
||||
'songs: ' + str(len(list(self.lib.items()))),
|
||||
'songs: ' + str(songs),
|
||||
'uptime: ' + str(int(time.time() - self.startup_time)),
|
||||
'playtime: ' + '0',
|
||||
'db_playtime: ' + '0',
|
||||
'db_update: ' + str(int(self.startup_time)),
|
||||
'playtime: ' + '0', #fixme
|
||||
'db_playtime: ' + str(int(totaltime)),
|
||||
'db_update: ' + str(int(self.startup_time)), #fixme
|
||||
)
|
||||
|
||||
|
||||
# Searching.
|
||||
|
||||
tagtype_map = {
|
||||
'Artist': 'artist',
|
||||
'Album': 'album',
|
||||
'Title': 'title',
|
||||
'Track': 'track',
|
||||
'artist': 'artist',
|
||||
'album': 'album',
|
||||
'title': 'title',
|
||||
'track': 'track',
|
||||
# Name?
|
||||
'Genre': 'genre',
|
||||
'Date': 'year',
|
||||
'Composer': 'composer',
|
||||
'genre': 'genre',
|
||||
'date': 'year',
|
||||
'composer': 'composer',
|
||||
# Performer?
|
||||
'Disc': 'disc',
|
||||
'disc': 'disc',
|
||||
'filename': 'path', # Suspect.
|
||||
}
|
||||
|
||||
def cmd_tagtypes(self, conn):
|
||||
|
|
@ -892,22 +893,59 @@ class Server(BaseServer):
|
|||
for tag in self.tagtype_map:
|
||||
conn.send('tagtype: ' + tag)
|
||||
|
||||
def cmd_search(self, conn, key, value):
|
||||
def _tagtype_to_key(self, tag):
|
||||
"""Uses `tagtype_map` to look up the beets column name for an
|
||||
MPD tagtype (or throw an appropriate exception).
|
||||
"""
|
||||
try:
|
||||
return self.tagtype_map[tag.lower()]
|
||||
except KeyError:
|
||||
raise BPDError(ERROR_UNKNOWN, 'no such tagtype')
|
||||
|
||||
def cmd_search(self, conn, tag, value):
|
||||
"""Perform a substring match in a specific column."""
|
||||
if key == 'filename':
|
||||
key = 'path'
|
||||
key = self._tagtype_to_key(tag)
|
||||
query = beets.library.SubstringQuery(key, value)
|
||||
for item in self.lib.get(query):
|
||||
conn.send(*self._item_info(item))
|
||||
|
||||
def cmd_find(self, conn, key, value):
|
||||
def cmd_find(self, conn, tag, value):
|
||||
"""Perform an exact match in a specific column."""
|
||||
if key == 'filename':
|
||||
key = 'path'
|
||||
key = self._tagtype_to_key(tag)
|
||||
query = beets.library.MatchQuery(key, value)
|
||||
for item in self.lib.get(query):
|
||||
conn.send(*self._item_info(item))
|
||||
|
||||
def cmd_list(self, conn, show_tag, match_tag=None, match_term=None):
|
||||
"""List distinct metadata values for show_tag, possibly
|
||||
filtered by matching match_tag to match_term.
|
||||
"""
|
||||
show_key = self._tagtype_to_key(show_tag)
|
||||
if match_tag and match_term:
|
||||
match_key = self._tagtype_to_key(match_tag)
|
||||
query = beets.library.MatchQuery(match_key, match_term)
|
||||
else:
|
||||
query = beets.library.TrueQuery()
|
||||
|
||||
clause, subvals = query.clause()
|
||||
statement = 'SELECT DISTINCT ' + show_key + \
|
||||
' FROM items WHERE ' + clause
|
||||
c = self.lib.conn.cursor()
|
||||
c.execute(statement, subvals)
|
||||
|
||||
for row in c:
|
||||
conn.send(show_tag + ': ' + row[0])
|
||||
|
||||
def cmd_count(self, conn, tag, value):
|
||||
"""Returns the number and total time of songs matching the
|
||||
tag/value query.
|
||||
"""
|
||||
key = self._tagtype_to_key(tag)
|
||||
query = beets.library.MatchQuery(key, value)
|
||||
songs, playtime = query.count(self.lib)
|
||||
conn.send('songs: ' + str(songs),
|
||||
'playtime: ' + str(int(playtime)))
|
||||
|
||||
|
||||
# "Outputs." Just a dummy implementation because we don't control
|
||||
# any outputs.
|
||||
|
|
|
|||
2
bts
2
bts
|
|
@ -82,7 +82,7 @@ def bpd(lib, config, opts):
|
|||
if __name__ == "__main__":
|
||||
# parse options
|
||||
usage = """usage: %prog [options] command
|
||||
command is one of: add, remove, update, write, list, help"""
|
||||
command is one of: add, remove, update, write, list, bpd, help"""
|
||||
op = OptionParser(usage=usage)
|
||||
op.add_option('-l', '--library', dest='libpath', metavar='PATH',
|
||||
default=None,
|
||||
|
|
|
|||
Loading…
Reference in a new issue