mirror of
https://github.com/beetbox/beets.git
synced 2025-12-25 01:53:31 +01:00
implemented a bunch of commands
--HG-- extra : convert_revision : svn%3A41726ec3-264d-0410-9c23-a9f1637257cc/trunk%40115
This commit is contained in:
parent
5ee460bcd5
commit
8fe53fec4c
3 changed files with 87 additions and 15 deletions
|
|
@ -1 +1,2 @@
|
|||
from beets.library import Library
|
||||
import beets.library
|
||||
Library = beets.library.Library
|
||||
|
|
|
|||
|
|
@ -105,7 +105,8 @@ class Item(object):
|
|||
self.dirty[key] = False
|
||||
|
||||
def __repr__(self):
|
||||
return 'Item(' + repr(self.record) + ', library=' + self.library + ')'
|
||||
return 'Item(' + repr(self.record) + \
|
||||
', library=' + repr(self.library) + ')'
|
||||
|
||||
|
||||
#### item field accessors ####
|
||||
|
|
@ -358,15 +359,26 @@ class Query(object):
|
|||
c = library.conn.cursor()
|
||||
c.execute(*self.statement())
|
||||
return ResultIterator(c, library)
|
||||
|
||||
class SubstringQuery(Query):
|
||||
"""A query that matches a substring in a specific item field."""
|
||||
|
||||
class FieldQuery(Query):
|
||||
"""An abstract query that searches in a specific field for a
|
||||
pattern.
|
||||
"""
|
||||
|
||||
def __init__(self, field, pattern):
|
||||
if field not in item_keys:
|
||||
raise InvalidFieldError(field + ' is not an item key')
|
||||
self.field = field
|
||||
self.pattern = pattern
|
||||
|
||||
class MatchQuery(FieldQuery):
|
||||
"""A query that looks for exact matches in an item field."""
|
||||
|
||||
def clause(self):
|
||||
return self.field + " = ?", [self.pattern]
|
||||
|
||||
class SubstringQuery(FieldQuery):
|
||||
"""A query that matches a substring in a specific item field."""
|
||||
|
||||
def clause(self):
|
||||
search = '%' + (self.pattern.replace('\\','\\\\').replace('%','\\%')
|
||||
|
|
@ -490,12 +502,22 @@ class ResultIterator(object):
|
|||
|
||||
def __iter__(self): return self
|
||||
|
||||
def count(self):
|
||||
"""Returns the number of matched rows and invalidates the
|
||||
iterator."""
|
||||
# Apparently, there is no good way to get the number of rows
|
||||
# returned by an sqlite SELECT.
|
||||
num = 0
|
||||
for i in self:
|
||||
num += 1
|
||||
return num
|
||||
|
||||
def next(self):
|
||||
try:
|
||||
row = self.cursor.next()
|
||||
except StopIteration:
|
||||
self.cursor.close()
|
||||
raise StopIteration
|
||||
raise
|
||||
return Item(row, self.library)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use of the wide range of MPD clients.
|
|||
import eventlet.api
|
||||
import re
|
||||
from string import Template
|
||||
from beets import Library
|
||||
import beets
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
|
|
@ -152,8 +152,8 @@ class Server(object):
|
|||
returns its index in the playlist.
|
||||
"""
|
||||
track_id = cast_arg(int, track_id)
|
||||
for index, track in self.playlist:
|
||||
if _item_id(track) == track_id:
|
||||
for index, track in enumerate(self.playlist):
|
||||
if self._item_id(track) == track_id:
|
||||
return index
|
||||
# Loop finished with no track found.
|
||||
raise ArgumentNotFoundError()
|
||||
|
|
@ -311,10 +311,19 @@ class Server(object):
|
|||
track = self.playlist[index]
|
||||
except IndexError:
|
||||
raise ArgumentIndexError()
|
||||
return SuccessReponse(self._item_info(track))
|
||||
return SuccessResponse(self._item_info(track))
|
||||
def cmd_playlistid(self, track_id=-1):
|
||||
return self.cmd_playlistinfo(self._id_to_index(track_id))
|
||||
|
||||
def cmd_plchanges(self, version):
|
||||
"""Returns playlist changes since the given version.
|
||||
|
||||
This is a "fake" implementation that ignores the version and
|
||||
just returns the entire playlist (rather like version=0). This
|
||||
seems to satisfy many clients.
|
||||
"""
|
||||
return self.cmd_playlistinfo()
|
||||
|
||||
def cmd_currentsong(self):
|
||||
"""Returns information about the currently-playing song.
|
||||
"""
|
||||
|
|
@ -354,9 +363,13 @@ class Server(object):
|
|||
self.current_index = index
|
||||
|
||||
self.paused = False
|
||||
|
||||
|
||||
def cmd_playid(self, track_id=0):
|
||||
index = self._id_to_index(track_id)
|
||||
track_id = cast_arg(int, track_id)
|
||||
if track_id == -1:
|
||||
index = -1
|
||||
else:
|
||||
index = self._id_to_index(track_id)
|
||||
self.cmd_play(index)
|
||||
|
||||
def cmd_stop(self):
|
||||
|
|
@ -525,7 +538,6 @@ class CommandList(list):
|
|||
|
||||
for i, command in enumerate(self):
|
||||
resp = command.run(server)
|
||||
print resp.items
|
||||
out.extend(resp.items)
|
||||
|
||||
# If the command failed, stop executing and send the completion
|
||||
|
|
@ -640,16 +652,53 @@ class BGServer(Server):
|
|||
return item.id
|
||||
|
||||
def cmd_lsinfo(self, path="/"):
|
||||
"""Return info on all the items in the path."""
|
||||
if path != "/":
|
||||
raise BPDError(ERROR_NO_EXIST, 'cannot list paths other than /')
|
||||
return self._items_info(self.lib.get())
|
||||
def cmd_listallinfo(self, path="/"):
|
||||
"""Return info on all the items in the directory, recursively."""
|
||||
# Because we have a flat directory path, this recursive version
|
||||
# is equivalent to the non-recursive version.
|
||||
return self.cmd_lsinfo(path)
|
||||
def cmd_listall(self, path="/"):
|
||||
"""Return the paths all items in the directory, recursively."""
|
||||
if path != "/":
|
||||
raise BPDError(ERROR_NO_EXIST, 'cannot list paths other than /')
|
||||
out = ['file: ' + i.path for i in self.lib.get()]
|
||||
return SuccessResponse(out)
|
||||
|
||||
def cmd_search(self, key, value):
|
||||
"""Perform a substring match in a specific column."""
|
||||
if key == 'filename':
|
||||
key = 'path'
|
||||
query = key + ':' + value + ''
|
||||
query = beets.library.SubstringQuery(key, value)
|
||||
return self._items_info(self.lib.get(query))
|
||||
|
||||
def cmd_find(self, key, value):
|
||||
"""Perform an exact match in a specific column."""
|
||||
if key == 'filename':
|
||||
key = 'path'
|
||||
query = beets.library.MatchQuery(key, value)
|
||||
return self._items_info(self.lib.get(query))
|
||||
|
||||
def _get_by_path(self, path):
|
||||
it = self.lib.get(beets.library.MatchQuery('path', path))
|
||||
try:
|
||||
return it.next()
|
||||
except StopIteration:
|
||||
raise ArgumentNotFoundError()
|
||||
def cmd_add(self, path):
|
||||
"""Adds a track to the playlist, specified by its path."""
|
||||
self.playlist.append(self._get_by_path(path))
|
||||
self.playlist_version += 1
|
||||
def cmd_addid(self, path):
|
||||
"""Same as cmd_add but returns an id."""
|
||||
track = self._get_by_path(path)
|
||||
self.playlist.append(track)
|
||||
self.playlist_version += 1
|
||||
return SuccessResponse(['Id: ' + str(track.id)])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
BGServer(Library('library.blb')).run()
|
||||
BGServer(beets.Library('library.blb')).run()
|
||||
|
|
|
|||
Loading…
Reference in a new issue