| OLD | NEW |
| (Empty) |
| 1 # Early, and incomplete implementation of -04. | |
| 2 # | |
| 3 import re | |
| 4 import urllib | |
| 5 | |
| 6 RESERVED = ":/?#[]@!$&'()*+,;=" | |
| 7 OPERATOR = "+./;?|!@" | |
| 8 EXPLODE = "*+" | |
| 9 MODIFIER = ":^" | |
| 10 TEMPLATE = re.compile(r"{(?P<operator>[\+\./;\?|!@])?(?P<varlist>[^}]+)}", re.UN
ICODE) | |
| 11 VAR = re.compile(r"^(?P<varname>[^=\+\*:\^]+)((?P<explode>[\+\*])|(?P<partial>[:
\^]-?[0-9]+))?(=(?P<default>.*))?$", re.UNICODE) | |
| 12 | |
| 13 def _tostring(varname, value, explode, operator, safe=""): | |
| 14 if type(value) == type([]): | |
| 15 if explode == "+": | |
| 16 return ",".join([varname + "." + urllib.quote(x, safe) for x in value]) | |
| 17 else: | |
| 18 return ",".join([urllib.quote(x, safe) for x in value]) | |
| 19 if type(value) == type({}): | |
| 20 keys = value.keys() | |
| 21 keys.sort() | |
| 22 if explode == "+": | |
| 23 return ",".join([varname + "." + urllib.quote(key, safe) + "," + urllib.qu
ote(value[key], safe) for key in keys]) | |
| 24 else: | |
| 25 return ",".join([urllib.quote(key, safe) + "," + urllib.quote(value[key],
safe) for key in keys]) | |
| 26 else: | |
| 27 return urllib.quote(value, safe) | |
| 28 | |
| 29 | |
| 30 def _tostring_path(varname, value, explode, operator, safe=""): | |
| 31 joiner = operator | |
| 32 if type(value) == type([]): | |
| 33 if explode == "+": | |
| 34 return joiner.join([varname + "." + urllib.quote(x, safe) for x in value]) | |
| 35 elif explode == "*": | |
| 36 return joiner.join([urllib.quote(x, safe) for x in value]) | |
| 37 else: | |
| 38 return ",".join([urllib.quote(x, safe) for x in value]) | |
| 39 elif type(value) == type({}): | |
| 40 keys = value.keys() | |
| 41 keys.sort() | |
| 42 if explode == "+": | |
| 43 return joiner.join([varname + "." + urllib.quote(key, safe) + joiner + url
lib.quote(value[key], safe) for key in keys]) | |
| 44 elif explode == "*": | |
| 45 return joiner.join([urllib.quote(key, safe) + joiner + urllib.quote(value[
key], safe) for key in keys]) | |
| 46 else: | |
| 47 return ",".join([urllib.quote(key, safe) + "," + urllib.quote(value[key],
safe) for key in keys]) | |
| 48 else: | |
| 49 if value: | |
| 50 return urllib.quote(value, safe) | |
| 51 else: | |
| 52 return "" | |
| 53 | |
| 54 def _tostring_query(varname, value, explode, operator, safe=""): | |
| 55 joiner = operator | |
| 56 varprefix = "" | |
| 57 if operator == "?": | |
| 58 joiner = "&" | |
| 59 varprefix = varname + "=" | |
| 60 if type(value) == type([]): | |
| 61 if 0 == len(value): | |
| 62 return "" | |
| 63 if explode == "+": | |
| 64 return joiner.join([varname + "=" + urllib.quote(x, safe) for x in value]) | |
| 65 elif explode == "*": | |
| 66 return joiner.join([urllib.quote(x, safe) for x in value]) | |
| 67 else: | |
| 68 return varprefix + ",".join([urllib.quote(x, safe) for x in value]) | |
| 69 elif type(value) == type({}): | |
| 70 if 0 == len(value): | |
| 71 return "" | |
| 72 keys = value.keys() | |
| 73 keys.sort() | |
| 74 if explode == "+": | |
| 75 return joiner.join([varname + "." + urllib.quote(key, safe) + "=" + urllib
.quote(value[key], safe) for key in keys]) | |
| 76 elif explode == "*": | |
| 77 return joiner.join([urllib.quote(key, safe) + "=" + urllib.quote(value[key
], safe) for key in keys]) | |
| 78 else: | |
| 79 return varprefix + ",".join([urllib.quote(key, safe) + "," + urllib.quote(
value[key], safe) for key in keys]) | |
| 80 else: | |
| 81 if value: | |
| 82 return varname + "=" + urllib.quote(value, safe) | |
| 83 else: | |
| 84 return varname | |
| 85 | |
| 86 TOSTRING = { | |
| 87 "" : _tostring, | |
| 88 "+": _tostring, | |
| 89 ";": _tostring_query, | |
| 90 "?": _tostring_query, | |
| 91 "/": _tostring_path, | |
| 92 ".": _tostring_path, | |
| 93 } | |
| 94 | |
| 95 | |
| 96 def expand(template, vars): | |
| 97 def _sub(match): | |
| 98 groupdict = match.groupdict() | |
| 99 operator = groupdict.get('operator') | |
| 100 if operator is None: | |
| 101 operator = '' | |
| 102 varlist = groupdict.get('varlist') | |
| 103 | |
| 104 safe = "@" | |
| 105 if operator == '+': | |
| 106 safe = RESERVED | |
| 107 varspecs = varlist.split(",") | |
| 108 varnames = [] | |
| 109 defaults = {} | |
| 110 for varspec in varspecs: | |
| 111 m = VAR.search(varspec) | |
| 112 groupdict = m.groupdict() | |
| 113 varname = groupdict.get('varname') | |
| 114 explode = groupdict.get('explode') | |
| 115 partial = groupdict.get('partial') | |
| 116 default = groupdict.get('default') | |
| 117 if default: | |
| 118 defaults[varname] = default | |
| 119 varnames.append((varname, explode, partial)) | |
| 120 | |
| 121 retval = [] | |
| 122 joiner = operator | |
| 123 prefix = operator | |
| 124 if operator == "+": | |
| 125 prefix = "" | |
| 126 joiner = "," | |
| 127 if operator == "?": | |
| 128 joiner = "&" | |
| 129 if operator == "": | |
| 130 joiner = "," | |
| 131 for varname, explode, partial in varnames: | |
| 132 if varname in vars: | |
| 133 value = vars[varname] | |
| 134 #if not value and (type(value) == type({}) or type(value) == type([])) a
nd varname in defaults: | |
| 135 if not value and value != "" and varname in defaults: | |
| 136 value = defaults[varname] | |
| 137 elif varname in defaults: | |
| 138 value = defaults[varname] | |
| 139 else: | |
| 140 continue | |
| 141 retval.append(TOSTRING[operator](varname, value, explode, operator, safe=s
afe)) | |
| 142 if "".join(retval): | |
| 143 return prefix + joiner.join(retval) | |
| 144 else: | |
| 145 return "" | |
| 146 | |
| 147 return TEMPLATE.sub(_sub, template) | |
| OLD | NEW |