Mercurial > p > roundup > code
comparison roundup/cgi/client.py @ 1384:a87f59436895 maint-0.5
ported CGI fixes from HEAD
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Wed, 15 Jan 2003 22:38:14 +0000 |
| parents | 83f33642d220 |
| children | 3c9bd1faddd8 |
comparison
equal
deleted
inserted
replaced
| 1371:56c5b4509378 | 1384:a87f59436895 |
|---|---|
| 1 # $Id: client.py,v 1.65 2003-01-08 04:39:36 richard Exp $ | 1 # $Id: client.py,v 1.65.2.1 2003-01-15 22:38:14 richard Exp $ |
| 2 | 2 |
| 3 __doc__ = """ | 3 __doc__ = """ |
| 4 WWW request handler (also used in the stand-alone server). | 4 WWW request handler (also used in the stand-alone server). |
| 5 """ | 5 """ |
| 6 | 6 |
| 1148 endings. Our solution is to convert all line endings to LF. | 1148 endings. Our solution is to convert all line endings to LF. |
| 1149 ''' | 1149 ''' |
| 1150 text = text.replace('\r\n', '\n') | 1150 text = text.replace('\r\n', '\n') |
| 1151 return text.replace('\r', '\n') | 1151 return text.replace('\r', '\n') |
| 1152 | 1152 |
| 1153 | |
| 1153 def parsePropsFromForm(db, cl, form, nodeid=0, num_re=re.compile('^\d+$')): | 1154 def parsePropsFromForm(db, cl, form, nodeid=0, num_re=re.compile('^\d+$')): |
| 1154 ''' Pull properties for the given class out of the form. | 1155 ''' Pull properties for the given class out of the form. |
| 1155 | 1156 |
| 1156 If a ":required" parameter is supplied, then the names property values | 1157 If a ":required" parameter is supplied, then the names property values |
| 1157 must be supplied or a ValueError will be raised. | 1158 must be supplied or a ValueError will be raised. |
| 1171 required = [i.strip() for i in value.value.split(',')] | 1172 required = [i.strip() for i in value.value.split(',')] |
| 1172 | 1173 |
| 1173 props = {} | 1174 props = {} |
| 1174 keys = form.keys() | 1175 keys = form.keys() |
| 1175 properties = cl.getprops() | 1176 properties = cl.getprops() |
| 1176 existing_cache = {} | |
| 1177 for key in keys: | 1177 for key in keys: |
| 1178 # see if we're performing a special multilink action | 1178 # see if we're performing a special multilink action |
| 1179 mlaction = 'set' | 1179 mlaction = 'set' |
| 1180 if key.startswith(':remove:'): | 1180 if key.startswith(':remove:'): |
| 1181 propname = key[8:] | 1181 propname = key[8:] |
| 1186 else: | 1186 else: |
| 1187 propname = key | 1187 propname = key |
| 1188 | 1188 |
| 1189 # does the property exist? | 1189 # does the property exist? |
| 1190 if not properties.has_key(propname): | 1190 if not properties.has_key(propname): |
| 1191 if mlaction == 'remove': | 1191 if mlaction != 'set': |
| 1192 raise ValueError, 'You have submitted a remove action for'\ | 1192 raise ValueError, 'You have submitted a %s action for'\ |
| 1193 ' the property "%s" which doesn\'t exist'%propname | 1193 ' the property "%s" which doesn\'t exist'%(mlaction, |
| 1194 propname) | |
| 1194 continue | 1195 continue |
| 1195 proptype = properties[propname] | 1196 proptype = properties[propname] |
| 1196 | 1197 |
| 1197 # Get the form value. This value may be a MiniFieldStorage or a list | 1198 # Get the form value. This value may be a MiniFieldStorage or a list |
| 1198 # of MiniFieldStorages. | 1199 # of MiniFieldStorages. |
| 1206 value = [i.value.strip() for i in value] | 1207 value = [i.value.strip() for i in value] |
| 1207 else: | 1208 else: |
| 1208 # it's a MiniFieldStorage, but may be a comma-separated list | 1209 # it's a MiniFieldStorage, but may be a comma-separated list |
| 1209 # of values | 1210 # of values |
| 1210 value = [i.strip() for i in value.value.split(',')] | 1211 value = [i.strip() for i in value.value.split(',')] |
| 1212 | |
| 1213 # filter out the empty bits | |
| 1214 value = filter(None, value) | |
| 1211 else: | 1215 else: |
| 1212 # multiple values are not OK | 1216 # multiple values are not OK |
| 1213 if isinstance(value, type([])): | 1217 if isinstance(value, type([])): |
| 1214 raise ValueError, 'You have submitted more than one value'\ | 1218 raise ValueError, 'You have submitted more than one value'\ |
| 1215 ' for the %s property'%propname | 1219 ' for the %s property'%propname |
| 1216 # we've got a MiniFieldStorage, so pull out the value and strip | 1220 # we've got a MiniFieldStorage, so pull out the value and strip |
| 1217 # surrounding whitespace | 1221 # surrounding whitespace |
| 1218 value = value.value.strip() | 1222 value = value.value.strip() |
| 1219 | 1223 |
| 1220 if isinstance(proptype, hyperdb.String): | 1224 if isinstance(proptype, hyperdb.String): |
| 1221 if not value: | |
| 1222 continue | |
| 1223 # fix the CRLF/CR -> LF stuff | 1225 # fix the CRLF/CR -> LF stuff |
| 1224 value = fixNewlines(value) | 1226 value = fixNewlines(value) |
| 1225 elif isinstance(proptype, hyperdb.Password): | 1227 elif isinstance(proptype, hyperdb.Password): |
| 1226 if not value: | 1228 if not value: |
| 1227 # ignore empty password values | 1229 # ignore empty password values |
| 1245 value = date.Interval(value) | 1247 value = date.Interval(value) |
| 1246 else: | 1248 else: |
| 1247 value = None | 1249 value = None |
| 1248 elif isinstance(proptype, hyperdb.Link): | 1250 elif isinstance(proptype, hyperdb.Link): |
| 1249 # see if it's the "no selection" choice | 1251 # see if it's the "no selection" choice |
| 1250 if value == '-1': | 1252 if value == '-1' or not value: |
| 1251 # if we're creating, just don't include this property | 1253 # if we're creating, just don't include this property |
| 1252 if not nodeid: | 1254 if not nodeid: |
| 1253 continue | 1255 continue |
| 1254 value = None | 1256 value = None |
| 1255 else: | 1257 else: |
| 1268 'for property "%(propname)s": %(message)s')%{ | 1270 'for property "%(propname)s": %(message)s')%{ |
| 1269 'propname': propname, 'message': message} | 1271 'propname': propname, 'message': message} |
| 1270 elif isinstance(proptype, hyperdb.Multilink): | 1272 elif isinstance(proptype, hyperdb.Multilink): |
| 1271 # perform link class key value lookup if necessary | 1273 # perform link class key value lookup if necessary |
| 1272 link = proptype.classname | 1274 link = proptype.classname |
| 1275 link_cl = db.classes[link] | |
| 1273 l = [] | 1276 l = [] |
| 1274 for entry in value: | 1277 for entry in value: |
| 1275 if not entry: continue | 1278 if not entry: continue |
| 1276 if not num_re.match(entry): | 1279 if not num_re.match(entry): |
| 1277 try: | 1280 try: |
| 1278 entry = db.classes[link].lookup(entry) | 1281 entry = link_cl.lookup(entry) |
| 1279 except KeyError: | 1282 except KeyError: |
| 1280 raise ValueError, _('property "%(propname)s": ' | 1283 raise ValueError, _('property "%(propname)s": ' |
| 1281 '"%(value)s" not an entry of %(classname)s')%{ | 1284 '"%(value)s" not an entry of %(classname)s')%{ |
| 1282 'propname': propname, 'value': entry, | 1285 'propname': propname, 'value': entry, |
| 1283 'classname': link} | 1286 'classname': link} |
| 1293 value = l | 1296 value = l |
| 1294 else: | 1297 else: |
| 1295 # we're modifying the list - get the current list of ids | 1298 # we're modifying the list - get the current list of ids |
| 1296 if props.has_key(propname): | 1299 if props.has_key(propname): |
| 1297 existing = props[propname] | 1300 existing = props[propname] |
| 1301 elif nodeid: | |
| 1302 existing = cl.get(nodeid, propname, []) | |
| 1298 else: | 1303 else: |
| 1299 existing = cl.get(nodeid, propname, []) | 1304 existing = [] |
| 1300 | 1305 |
| 1301 # now either remove or add | 1306 # now either remove or add |
| 1302 if mlaction == 'remove': | 1307 if mlaction == 'remove': |
| 1303 # remove - handle situation where the id isn't in the list | 1308 # remove - handle situation where the id isn't in the list |
| 1304 for entry in l: | 1309 for entry in l: |
| 1333 # this might be a new property for which there is no existing | 1338 # this might be a new property for which there is no existing |
| 1334 # value | 1339 # value |
| 1335 if not properties.has_key(propname): | 1340 if not properties.has_key(propname): |
| 1336 raise | 1341 raise |
| 1337 | 1342 |
| 1343 # existing may be None, which won't equate to empty strings | |
| 1344 if not existing and not value: | |
| 1345 continue | |
| 1346 | |
| 1347 # existing will come out unsorted in some cases | |
| 1348 if isinstance(proptype, hyperdb.Multilink): | |
| 1349 existing.sort() | |
| 1350 | |
| 1338 # if changed, set it | 1351 # if changed, set it |
| 1339 if value != existing: | 1352 if value != existing: |
| 1340 props[propname] = value | 1353 props[propname] = value |
| 1341 else: | 1354 else: |
| 1355 # don't bother setting empty/unset values | |
| 1356 if not value: | |
| 1357 continue | |
| 1342 props[propname] = value | 1358 props[propname] = value |
| 1343 | 1359 |
| 1344 # see if all the required properties have been supplied | 1360 # see if all the required properties have been supplied |
| 1345 if required: | 1361 if required: |
| 1346 if len(required) > 1: | 1362 if len(required) > 1: |
| 1348 else: | 1364 else: |
| 1349 p = 'property' | 1365 p = 'property' |
| 1350 raise ValueError, 'Required %s %s not supplied'%(p, ', '.join(required)) | 1366 raise ValueError, 'Required %s %s not supplied'%(p, ', '.join(required)) |
| 1351 | 1367 |
| 1352 return props | 1368 return props |
| 1353 | |
| 1354 |
