urls.py (7266B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\werkzeug\urls.py 2 import urlparse 3 from werkzeug._internal import _decode_unicode 4 _always_safe = frozenset('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.-') 5 _hextochr = dict((('%02x' % i, chr(i)) for i in xrange(256))) 6 _hextochr.update((('%02X' % i, chr(i)) for i in xrange(256))) 7 8 def _quote(s, safe = '/', _quotechar = '%%%02X'.__mod__): 9 safe = _always_safe | set(safe) 10 rv = list(s) 11 for idx, char in enumerate(s): 12 if char not in safe: 13 rv[idx] = _quotechar(ord(char)) 14 15 return ''.join(rv) 16 17 18 def _quote_plus(s, safe = ''): 19 if ' ' in s: 20 return _quote(s, safe + ' ').replace(' ', '+') 21 return _quote(s, safe) 22 23 24 def _safe_urlsplit(s): 25 rv = urlparse.urlsplit(s) 26 if type(rv[1]) is not type(s): 27 try: 28 return tuple(map(type(s), rv)) 29 except UnicodeError: 30 pass 31 32 return rv 33 34 35 def _unquote(s, unsafe = ''): 36 unsafe = set(unsafe) 37 rv = s.split('%') 38 for i in xrange(1, len(rv)): 39 item = rv[i] 40 try: 41 char = _hextochr[item[:2]] 42 if char in unsafe: 43 raise KeyError() 44 rv[i] = char + item[2:] 45 except KeyError: 46 rv[i] = '%' + item 47 48 return ''.join(rv) 49 50 51 def _unquote_plus(s): 52 return _unquote(s.replace('+', ' ')) 53 54 55 def _uri_split(uri): 56 scheme, netloc, path, query, fragment = _safe_urlsplit(uri) 57 port = None 58 if '@' in netloc: 59 auth, hostname = netloc.split('@', 1) 60 else: 61 auth = None 62 hostname = netloc 63 if hostname: 64 if ':' in hostname: 65 hostname, port = hostname.split(':', 1) 66 return (scheme, 67 auth, 68 hostname, 69 port, 70 path, 71 query, 72 fragment) 73 74 75 def iri_to_uri(iri, charset = 'utf-8'): 76 iri = unicode(iri) 77 scheme, auth, hostname, port, path, query, fragment = _uri_split(iri) 78 scheme = scheme.encode('ascii') 79 hostname = hostname.encode('idna') 80 if auth: 81 if ':' in auth: 82 auth, password = auth.split(':', 1) 83 else: 84 password = None 85 auth = _quote(auth.encode(charset)) 86 if password: 87 auth += ':' + _quote(password.encode(charset)) 88 hostname = auth + '@' + hostname 89 if port: 90 hostname += ':' + port 91 path = _quote(path.encode(charset), safe='/:~+') 92 query = _quote(query.encode(charset), safe='=%&[]:;$()+,!?*/') 93 return urlparse.urlunsplit([scheme, 94 hostname, 95 path, 96 query, 97 fragment]) 98 99 100 def uri_to_iri(uri, charset = 'utf-8', errors = 'ignore'): 101 uri = url_fix(str(uri), charset) 102 scheme, auth, hostname, port, path, query, fragment = _uri_split(uri) 103 scheme = _decode_unicode(scheme, 'ascii', errors) 104 try: 105 hostname = hostname.decode('idna') 106 except UnicodeError: 107 if errors not in ('ignore', 'replace'): 108 raise 109 hostname = hostname.decode('ascii', errors) 110 111 if auth: 112 if ':' in auth: 113 auth, password = auth.split(':', 1) 114 else: 115 password = None 116 auth = _decode_unicode(_unquote(auth), charset, errors) 117 if password: 118 auth += u':' + _decode_unicode(_unquote(password), charset, errors) 119 hostname = auth + u'@' + hostname 120 if port: 121 hostname += u':' + port.decode(charset, errors) 122 path = _decode_unicode(_unquote(path, '/;?'), charset, errors) 123 query = _decode_unicode(_unquote(query, ';/?:@&=+,$'), charset, errors) 124 return urlparse.urlunsplit([scheme, 125 hostname, 126 path, 127 query, 128 fragment]) 129 130 131 def url_decode(s, charset = 'utf-8', decode_keys = False, include_empty = True, errors = 'ignore', separator = '&', cls = None): 132 if cls is None: 133 cls = MultiDict 134 result = [] 135 for pair in str(s).split(separator): 136 if not pair: 137 continue 138 if '=' in pair: 139 key, value = pair.split('=', 1) 140 else: 141 key = pair 142 value = '' 143 key = _unquote_plus(key) 144 if decode_keys: 145 key = _decode_unicode(key, charset, errors) 146 result.append((key, url_unquote_plus(value, charset, errors))) 147 148 return cls(result) 149 150 151 def url_encode(obj, charset = 'utf-8', encode_keys = False, sort = False, key = None, separator = '&'): 152 iterable = iter_multi_items(obj) 153 if sort: 154 iterable = list(iterable) 155 iterable.sort(key=key) 156 tmp = [] 157 for key, value in iterable: 158 if encode_keys and isinstance(key, unicode): 159 key = key.encode(charset) 160 else: 161 key = str(key) 162 if value is None: 163 continue 164 elif isinstance(value, unicode): 165 value = value.encode(charset) 166 else: 167 value = str(value) 168 tmp.append('%s=%s' % (_quote(key), _quote_plus(value))) 169 170 return separator.join(tmp) 171 172 173 def url_quote(s, charset = 'utf-8', safe = '/:'): 174 if isinstance(s, unicode): 175 s = s.encode(charset) 176 elif not isinstance(s, str): 177 s = str(s) 178 return _quote(s, safe=safe) 179 180 181 def url_quote_plus(s, charset = 'utf-8', safe = ''): 182 if isinstance(s, unicode): 183 s = s.encode(charset) 184 elif not isinstance(s, str): 185 s = str(s) 186 return _quote_plus(s, safe=safe) 187 188 189 def url_unquote(s, charset = 'utf-8', errors = 'ignore'): 190 if isinstance(s, unicode): 191 s = s.encode(charset) 192 return _decode_unicode(_unquote(s), charset, errors) 193 194 195 def url_unquote_plus(s, charset = 'utf-8', errors = 'ignore'): 196 return _decode_unicode(_unquote_plus(s), charset, errors) 197 198 199 def url_fix(s, charset = 'utf-8'): 200 if isinstance(s, unicode): 201 s = s.encode(charset, 'ignore') 202 scheme, netloc, path, qs, anchor = _safe_urlsplit(s) 203 path = _quote(path, '/%') 204 qs = _quote_plus(qs, ':&%=') 205 return urlparse.urlunsplit((scheme, 206 netloc, 207 path, 208 qs, 209 anchor)) 210 211 212 class Href(object): 213 214 def __init__(self, base = './', charset = 'utf-8', sort = False, key = None): 215 if not base: 216 base = './' 217 self.base = base 218 self.charset = charset 219 self.sort = sort 220 self.key = key 221 222 def __getattr__(self, name): 223 if name[:2] == '__': 224 raise AttributeError(name) 225 base = self.base 226 if base[-1:] != '/': 227 base += '/' 228 return Href(urlparse.urljoin(base, name), self.charset, self.sort, self.key) 229 230 def __call__(self, *path, **query): 231 if path and isinstance(path[-1], dict): 232 if query: 233 raise TypeError("keyword arguments and query-dicts can't be combined") 234 query, path = path[-1], path[:-1] 235 elif query: 236 query = dict([ (k.endswith('_') and k[:-1] or k, v) for k, v in query.items() ]) 237 path = '/'.join([ url_quote(x, self.charset) for x in path if x is not None ]).lstrip('/') 238 rv = self.base 239 if path: 240 if not rv.endswith('/'): 241 rv += '/' 242 rv = urlparse.urljoin(rv, path) 243 if query: 244 rv += '?' + url_encode(query, self.charset, sort=self.sort, key=self.key) 245 return str(rv) 246 247 248 from werkzeug.datastructures import MultiDict, iter_multi_items