debug_proto = 0x0001
debug_body = 0x0002
- def __init__(self):
+ def __init__(self, user=None, password=None):
"""Constructor for DisOrder client class.
The constructor reads the configuration file, but does not connect
self.config = { 'collections': [],
'username': pw.pw_name,
'home': _dbhome }
+ self.user = user
+ self.password = password
home = os.getenv("HOME")
if not home:
home = pw.pw_dir
sys.stderr.write("\n")
sys.stderr.flush()
- def connect(self):
- """Connect to the DisOrder server and authenticate.
+ def connect(self, cookie=None):
+ """c.connect(cookie=None)
+
+ Connect to the DisOrder server and authenticate.
Raises communicationError if connection fails and operationError if
authentication fails (in which case disconnection is automatic).
Other operations automatically connect if we're not already
connected, so it is not strictly necessary to call this method.
+
+ If COOKIE is specified then that is used to log in instead of
+ the username/password.
"""
if self.state == 'disconnected':
try:
s.connect(self.who)
self.w = s.makefile("wb")
self.r = s.makefile("rb")
- (res, challenge) = self._simple()
- h = sha.sha()
- h.update(self.config['password'])
- h.update(binascii.unhexlify(challenge))
- self._simple("user", self.config['username'], h.hexdigest())
+ (res, details) = self._simple()
+ (protocol, algo, challenge) = _split(details)
+ if protocol != '2':
+ raise communicationError(self.who,
+ "unknown protocol version %s" % protocol)
+ if cookie is None:
+ if self.user is None:
+ user = self.config['username']
+ else:
+ user = self.user
+ if self.password is None:
+ password = self.config['password']
+ else:
+ password = self.password
+ # TODO support algorithms other than SHA-1
+ h = sha.sha()
+ h.update(password)
+ h.update(binascii.unhexlify(challenge))
+ self._simple("user", user, h.hexdigest())
+ else:
+ self._simple("cookie", cookie)
self.state = 'connected'
except socket.error, e:
self._disconnect()
########################################################################
# Operations
- def become(self, who):
- """Become another user.
-
- Arguments:
- who -- the user to become.
-
- Only trusted users can perform this operation.
- """
- self._simple("become", who)
-
def play(self, track):
"""Play a track.
def version(self):
"""Return the server's version number."""
- return self._simple("version")[1]
+ return _split(self._simple("version")[1])[0]
def playing(self):
"""Return the currently playing track.
if ret == 555:
return None
else:
- return details
+ return _split(details)[0]
def prefs(self, track):
"""Get all the preferences for a track.
The return value is the preference
"""
ret, details = self._simple("part", track, context, part)
- return details
+ return _split(details)[0]
def setglobal(self, key, value):
"""Set a global preference value.
if ret == 555:
return None
else:
- return details
+ return _split(details)[0]
+
+ def make_cookie(self):
+ """Create a login cookie"""
+ ret, details = self._simple("make-cookie")
+ return _split(details)[0]
+
+ def revoke(self):
+ """Revoke a login cookie"""
+ self._simple("revoke")
+
+ def adduser(self, user, password):
+ """Create a user"""
+ self._simple("adduser", user, password)
+
+ def deluser(self, user):
+ """Delete a user"""
+ self._simple("deluser", user)
+
+ def userinfo(self, user, key):
+ """Get user information"""
+ res, details = self._simple("userinfo", user, key)
+ if res == 555:
+ return None
+ return _split(details)[0]
+
+ def edituser(self, user, key, value):
+ """Set user information"""
+ self._simple("edituser", user, key, value)
+
+ def users(self):
+ """List all users
+
+ The return value is a list of all users."""
+ self._simple("users")
+ return self._body()
+
+ def register(self, username, password, email):
+ """Register a user"""
+ res, details = self._simple("register", username, password, email)
+ return _split(details)[0]
+
+ def confirm(self, confirmation):
+ """Confirm a user registration"""
+ res, details = self._simple("confirm", confirmation)
########################################################################
# I/O infrastructure