| 244 | pass # Generic server error. |
| 245 | |
| 246 | class URL(object): |
| 247 | |
| 248 | def __init__(self, string=u"", method=GET, query={}, **kwargs): |
| 249 | """ URL object with the individual parts available as attributes: |
| 250 | For protocol://username:password@domain:port/path/page?query_string#anchor: |
| 251 | - URL.protocol: http, https, ftp, ... |
| 252 | - URL.username: username for restricted domains. |
| 253 | - URL.password: password for restricted domains. |
| 254 | - URL.domain : the domain name, e.g. nodebox.net. |
| 255 | - URL.port : the server port to connect to. |
| 256 | - URL.path : the server path of folders, as a list, e.g. ['news', '2010'] |
| 257 | - URL.page : the page name, e.g. page.html. |
| 258 | - URL.query : the query string as a dictionary of (name, value)-items. |
| 259 | - URL.anchor : the page anchor. |
| 260 | If method is POST, the query string is sent with HTTP POST. |
| 261 | """ |
| 262 | self.__dict__["method"] = method # Use __dict__ directly since __setattr__ is overridden. |
| 263 | self.__dict__["_string"] = u(string) |
| 264 | self.__dict__["_parts"] = None |
| 265 | self.__dict__["_headers"] = None |
| 266 | self.__dict__["_redirect"] = None |
| 267 | if isinstance(string, URL): |
| 268 | self.__dict__["method"] = string.method |
| 269 | self.query.update(string.query) |
| 270 | if len(query) > 0: |
| 271 | # Requires that we parse the string first (see URL.__setattr__). |
| 272 | self.query.update(query) |
| 273 | if len(kwargs) > 0: |
| 274 | # Requires that we parse the string first (see URL.__setattr__). |
| 275 | self.parts.update(kwargs) |
| 276 | |
| 277 | def _parse(self): |
| 278 | """ Parses all the parts of the URL string to a dictionary. |
| 279 | URL format: protocal://username:password@domain:port/path/page?querystring#anchor |
| 280 | For example: http://user:pass@example.com:992/animal/bird?species=seagull&q#wings |
| 281 | This is a cached method that is only invoked when necessary, and only once. |
| 282 | """ |
| 283 | p = urlparse.urlsplit(self._string) |
| 284 | P = {PROTOCOL: p[0], # http |
| 285 | USERNAME: u"", # user |
| 286 | PASSWORD: u"", # pass |
| 287 | DOMAIN: p[1], # example.com |
| 288 | PORT: u"", # 992 |
| 289 | PATH: p[2], # [animal] |
| 290 | PAGE: u"", # bird |
| 291 | QUERY: urldecode(p[3]), # {"species": "seagull", "q": None} |
| 292 | ANCHOR: p[4] # wings |
| 293 | } |
| 294 | # Split the username and password from the domain. |
| 295 | if "@" in P[DOMAIN]: |
| 296 | P[USERNAME], \ |
| 297 | P[PASSWORD] = (p[1].split("@")[0].split(":")+[u""])[:2] |
| 298 | P[DOMAIN] = p[1].split("@")[1] |
| 299 | # Split the port number from the domain. |
| 300 | if ":" in P[DOMAIN]: |
| 301 | P[DOMAIN], \ |
| 302 | P[PORT] = P[DOMAIN].split(":") |
| 303 | P[PORT] = P[PORT].isdigit() and int(P[PORT]) or P[PORT] |
no outgoing calls
no test coverage detected