annotate roundup/xmlrpc.py @ 3916:57ad3e2c2545

handle bad cookies Roundup's cgi gets all cookies from all apps on the same server. some apps aren't as well behaved as roundup and generate cookies that do not follow the spec perfectly. This causes python's Cookie module to throw an exception when trying to parse them. In the spirit of being liberal in what we accept, we create a LiberalCookie class that can handle those out-of-spec cookies and allow roundup to continue onward. [SF#1691708] code from S. Woodside
author Justus Pendleton <jpend@users.sourceforge.net>
date Sat, 22 Sep 2007 21:20:57 +0000
parents c31da624ae3b
children 3c3077582c16
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3828
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
1 #
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
2 # Copyright (C) 2007 Stefan Seefeld
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
3 # All rights reserved.
3839
Stefan Seefeld <stefan@seefeld.name>
parents: 3828
diff changeset
4 # For license terms see the file COPYING.txt.
3828
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
5 #
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
6
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
7 import base64
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
8 import roundup.instance
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
9 from roundup import hyperdb
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
10 from roundup.cgi.exceptions import *
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
11 from roundup.admin import UsageError
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
12 from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
13
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
14 class RoundupRequestHandler(SimpleXMLRPCRequestHandler):
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
15 """A SimpleXMLRPCRequestHandler with support for basic
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
16 HTTP Authentication."""
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
17
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
18 def do_POST(self):
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
19 """Extract username and password from authorization header."""
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
20
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
21 # Try to extract username and password from HTTP Authentication.
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
22 self.username = None
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
23 self.password = None
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
24 authorization = self.headers.get('authorization', ' ')
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
25 scheme, challenge = authorization.split(' ', 1)
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
26
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
27 if scheme.lower() == 'basic':
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
28 decoded = base64.decodestring(challenge)
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
29 self.username, self.password = decoded.split(':')
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
30
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
31 SimpleXMLRPCRequestHandler.do_POST(self)
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
32
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
33 def _dispatch(self, method, params):
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
34 """Inject username and password into function arguments."""
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
35
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
36 # Add username and password to function arguments
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
37 params = [self.username, self.password] + list(params)
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
38 return self.server._dispatch(method, params)
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
39
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
40
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
41 class RoundupRequest:
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
42 """Little helper class to handle common per-request tasks such
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
43 as authentication and login."""
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
44
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
45 def __init__(self, tracker, username, password):
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
46 """Open the database for the given tracker, using the given
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
47 username and password."""
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
48
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
49 self.tracker = tracker
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
50 self.db = self.tracker.open('admin')
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
51 try:
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
52 userid = self.db.user.lookup(username)
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
53 except KeyError: # No such user
3841
c31da624ae3b fix RoundupRequest:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3840
diff changeset
54 self.db.close()
3828
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
55 raise Unauthorised, 'Invalid user.'
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
56 stored = self.db.user.get(userid, 'password')
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
57 if stored != password: # Wrong password
3841
c31da624ae3b fix RoundupRequest:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3840
diff changeset
58 self.db.close()
3828
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
59 raise Unauthorised, 'Invalid user.'
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
60 self.db.setCurrentUser(username)
3840
9596a516d78c fix compatibility with Python2.3:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3839
diff changeset
61
3839
Stefan Seefeld <stefan@seefeld.name>
parents: 3828
diff changeset
62 def close(self):
3828
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
63 """Close the database, after committing any changes, if needed."""
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
64
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
65 if getattr(self, 'db'):
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
66 try:
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
67 if self.db.transactions:
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
68 self.db.commit()
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
69 finally:
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
70 self.db.close()
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
71
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
72
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
73 def get_class(self, classname):
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
74 """Return the class for the given classname."""
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
75
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
76 try:
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
77 return self.db.getclass(classname)
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
78 except KeyError:
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
79 raise UsageError, 'no such class "%s"'%classname
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
80
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
81 def props_from_args(self, cl, args):
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
82 """Construct a list of properties from the given arguments,
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
83 and return them after validation."""
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
84
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
85 props = {}
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
86 for arg in args:
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
87 if arg.find('=') == -1:
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
88 raise UsageError, 'argument "%s" not propname=value'%arg
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
89 l = arg.split('=')
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
90 if len(l) < 2:
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
91 raise UsageError, 'argument "%s" not propname=value'%arg
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
92 key, value = l[0], '='.join(l[1:])
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
93 if value:
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
94 try:
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
95 props[key] = hyperdb.rawToHyperdb(self.db, cl, None,
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
96 key, value)
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
97 except hyperdb.HyperdbValueError, message:
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
98 raise UsageError, message
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
99 else:
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
100 props[key] = None
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
101
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
102 return props
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
103
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
104
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
105 #The server object
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
106 class RoundupServer:
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
107 """The RoundupServer provides the interface accessible through
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
108 the Python XMLRPC mapping. All methods take an additional username
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
109 and password argument so each request can be authenticated."""
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
110
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
111 def __init__(self, tracker, verbose = False):
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
112 self.tracker = roundup.instance.open(tracker)
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
113 self.verbose = verbose
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
114
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
115 def list(self, username, password, classname, propname = None):
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
116
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
117 r = RoundupRequest(self.tracker, username, password)
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
118 cl = r.get_class(classname)
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
119 if not propname:
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
120 propname = cl.labelprop()
3839
Stefan Seefeld <stefan@seefeld.name>
parents: 3828
diff changeset
121 result = [cl.get(id, propname) for id in cl.list()]
Stefan Seefeld <stefan@seefeld.name>
parents: 3828
diff changeset
122 r.close()
Stefan Seefeld <stefan@seefeld.name>
parents: 3828
diff changeset
123 return result
3828
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
124
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
125 def display(self, username, password, designator, *properties):
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
126
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
127 r = RoundupRequest(self.tracker, username, password)
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
128 classname, nodeid = hyperdb.splitDesignator(designator)
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
129 cl = r.get_class(classname)
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
130 props = properties and list(properties) or cl.properties.keys()
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
131 props.sort()
3839
Stefan Seefeld <stefan@seefeld.name>
parents: 3828
diff changeset
132 result = [(property, cl.get(nodeid, property)) for property in props]
Stefan Seefeld <stefan@seefeld.name>
parents: 3828
diff changeset
133 r.close()
Stefan Seefeld <stefan@seefeld.name>
parents: 3828
diff changeset
134 return dict(result)
3828
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
135
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
136 def create(self, username, password, classname, *args):
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
137
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
138 r = RoundupRequest(self.tracker, username, password)
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
139 cl = r.get_class(classname)
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
140
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
141 # convert types
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
142 props = r.props_from_args(cl, args)
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
143
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
144 # check for the key property
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
145 key = cl.getkey()
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
146 if key and not props.has_key(key):
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
147 raise UsageError, 'you must provide the "%s" property.'%key
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
148
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
149 # do the actual create
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
150 try:
3840
9596a516d78c fix compatibility with Python2.3:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3839
diff changeset
151 try:
9596a516d78c fix compatibility with Python2.3:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3839
diff changeset
152 result = cl.create(**props)
9596a516d78c fix compatibility with Python2.3:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3839
diff changeset
153 except (TypeError, IndexError, ValueError), message:
9596a516d78c fix compatibility with Python2.3:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3839
diff changeset
154 raise UsageError, message
3839
Stefan Seefeld <stefan@seefeld.name>
parents: 3828
diff changeset
155 finally:
Stefan Seefeld <stefan@seefeld.name>
parents: 3828
diff changeset
156 r.close()
Stefan Seefeld <stefan@seefeld.name>
parents: 3828
diff changeset
157 return result
3828
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
158
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
159 def set(self, username, password, designator, *args):
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
160
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
161 r = RoundupRequest(self.tracker, username, password)
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
162 classname, itemid = hyperdb.splitDesignator(designator)
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
163 cl = r.get_class(classname)
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
164
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
165 # convert types
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
166 props = r.props_from_args(cl, args)
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
167 try:
3840
9596a516d78c fix compatibility with Python2.3:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3839
diff changeset
168 try:
9596a516d78c fix compatibility with Python2.3:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3839
diff changeset
169 cl.set(itemid, **props)
9596a516d78c fix compatibility with Python2.3:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3839
diff changeset
170 except (TypeError, IndexError, ValueError), message:
9596a516d78c fix compatibility with Python2.3:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3839
diff changeset
171 raise UsageError, message
3839
Stefan Seefeld <stefan@seefeld.name>
parents: 3828
diff changeset
172 finally:
Stefan Seefeld <stefan@seefeld.name>
parents: 3828
diff changeset
173 r.close()
3828
ba6ba8d6bcc1 Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff changeset
174
3840
9596a516d78c fix compatibility with Python2.3:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3839
diff changeset
175 # vim: set et sts=4 sw=4 :

Roundup Issue Tracker: http://roundup-tracker.org/