X-Git-Url: https://git.distorted.org.uk/~mdw/disorder/blobdiff_plain/763d5e6ad88ef3ba1cd1d7742d060e4f1e54c6b8..31773020eedbe29daff0a407619df9607e569e22:/python/disorder.py.in diff --git a/python/disorder.py.in b/python/disorder.py.in index eb58507..a8afcba 100644 --- a/python/disorder.py.in +++ b/python/disorder.py.in @@ -53,6 +53,7 @@ import locale _configfile = "pkgconfdir/config" _dbhome = "pkgstatedir" +_userconf = True # various regexps we'll use _ws = re.compile(r"^[ \t\n\r]+") @@ -104,15 +105,20 @@ class operationError(Error): Indicates that an operation failed (e.g. an attempt to play a nonexistent track). The connection should still be usable. """ - def __init__(self, res, details): + def __init__(self, res, details, cmd=None): self.res_ = int(res) + self.cmd_ = cmd self.details_ = details def __str__(self): - """Return the complete response string from the server. + """Return the complete response string from the server, with the command + if available. Excludes the final newline. """ - return "%d %s" % (self.res_, self.details_) + if self.cmd_ is None: + return "%d %s" % (self.res_, self.details_) + else: + return "%d %s [%s]" % (self.res_, self.details_, self.cmd_) def response(self): """Return the response code from the server.""" return self.res_ @@ -291,7 +297,7 @@ class client: self._readfile(_configfile) if os.path.exists(privconf): self._readfile(privconf) - if os.path.exists(passfile): + if os.path.exists(passfile) and _userconf: self._readfile(passfile) self.state = 'disconnected' @@ -579,7 +585,10 @@ class client: The return value is the preference """ ret, details = self._simple("get", track, key) - return details + if ret == 555: + return None + else: + return details def prefs(self, track): """Get all the preferences for a track. @@ -647,7 +656,15 @@ class client: all of the required words (in their path name, trackname preferences, etc.) """ - self._simple("search", *words) + self._simple("search", _quote(words)) + return self._body() + + def tags(self): + """List all tags + + The return value is a list of all tags which apply to at least one + track.""" + self._simple("tags") return self._body() def stats(self): @@ -749,6 +766,37 @@ class client: ret, details = self._simple("part", track, context, part) return details + def setglobal(self, key, value): + """Set a global preference value. + + Arguments: + key -- the preference name + value -- the new preference value + """ + self._simple("set-global", key, value) + + def unsetglobal(self, key): + """Unset a global preference value. + + Arguments: + key -- the preference to remove + """ + self._simple("set-global", key, value) + + def getglobal(self, key): + """Get a global preference value. + + Arguments: + key -- the preference to look up + + The return value is the preference + """ + ret, details = self._simple("get-global", key) + if ret == 555: + return None + else: + return details + ######################################################################## # I/O infrastructure @@ -779,6 +827,9 @@ class client: raise protocolError(self.who, "invalid response %s") def _send(self, *command): + # Quote and send a command + # + # Returns the encoded command. quoted = _quote(command) self._debug(client.debug_proto, "==> %s" % quoted) encoded = quoted.encode("UTF-8") @@ -786,6 +837,7 @@ class client: self.w.write(encoded) self.w.write("\n") self.w.flush() + return encoded except IOError, e: # e.g. EPIPE self._disconnect() @@ -799,17 +851,19 @@ class client: # # If an I/O error occurs, disconnect from the server. # - # On success returns response as a (code, details) tuple + # On success or 'normal' errors returns response as a (code, details) tuple # # On error raise operationError if self.state == 'disconnected': self.connect() if command: - self._send(*command) + cmd = self._send(*command) + else: + cmd = None res, details = self._response() - if res / 100 == 2: + if res / 100 == 2 or res == 555: return res, details - raise operationError(res, details) + raise operationError(res, details, cmd) def _body(self): # Fetch a dot-stuffed body