PageRenderTime 43ms CodeModel.GetById 9ms app.highlight 27ms RepoModel.GetById 2ms app.codeStats 0ms

/atom/url.py

http://radioappz.googlecode.com/
Python | 139 lines | 102 code | 10 blank | 27 comment | 10 complexity | 8da1a83bd79ea061a97deba4de4afa3d MD5 | raw file
  1#!/usr/bin/python
  2#
  3# Copyright (C) 2008 Google Inc.
  4#
  5# Licensed under the Apache License, Version 2.0 (the "License");
  6# you may not use this file except in compliance with the License.
  7# You may obtain a copy of the License at
  8#
  9#      http://www.apache.org/licenses/LICENSE-2.0
 10#
 11# Unless required by applicable law or agreed to in writing, software
 12# distributed under the License is distributed on an "AS IS" BASIS,
 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14# See the License for the specific language governing permissions and
 15# limitations under the License.
 16
 17
 18__author__ = 'api.jscudder (Jeff Scudder)'
 19
 20
 21import urlparse
 22import urllib
 23
 24
 25DEFAULT_PROTOCOL = 'http'
 26DEFAULT_PORT = 80
 27
 28
 29def parse_url(url_string):
 30  """Creates a Url object which corresponds to the URL string.
 31  
 32  This method can accept partial URLs, but it will leave missing
 33  members of the Url unset.
 34  """
 35  parts = urlparse.urlparse(url_string)
 36  url = Url()
 37  if parts[0]:
 38    url.protocol = parts[0]
 39  if parts[1]:
 40    host_parts = parts[1].split(':')
 41    if host_parts[0]:
 42      url.host = host_parts[0]
 43    if len(host_parts) > 1:
 44      url.port = host_parts[1]
 45  if parts[2]:
 46    url.path = parts[2]
 47  if parts[4]:
 48    param_pairs = parts[4].split('&')
 49    for pair in param_pairs:
 50      pair_parts = pair.split('=')
 51      if len(pair_parts) > 1:
 52        url.params[urllib.unquote_plus(pair_parts[0])] = (
 53            urllib.unquote_plus(pair_parts[1]))
 54      elif len(pair_parts) == 1:
 55        url.params[urllib.unquote_plus(pair_parts[0])] = None
 56  return url
 57   
 58class Url(object):
 59  """Represents a URL and implements comparison logic.
 60  
 61  URL strings which are not identical can still be equivalent, so this object
 62  provides a better interface for comparing and manipulating URLs than 
 63  strings. URL parameters are represented as a dictionary of strings, and
 64  defaults are used for the protocol (http) and port (80) if not provided.
 65  """
 66  def __init__(self, protocol=None, host=None, port=None, path=None, 
 67               params=None):
 68    self.protocol = protocol
 69    self.host = host
 70    self.port = port
 71    self.path = path
 72    self.params = params or {}
 73
 74  def to_string(self):
 75    url_parts = ['', '', '', '', '', '']
 76    if self.protocol:
 77      url_parts[0] = self.protocol
 78    if self.host:
 79      if self.port:
 80        url_parts[1] = ':'.join((self.host, str(self.port)))
 81      else:
 82        url_parts[1] = self.host
 83    if self.path:
 84      url_parts[2] = self.path
 85    if self.params:
 86      url_parts[4] = self.get_param_string()
 87    return urlparse.urlunparse(url_parts)
 88
 89  def get_param_string(self):
 90    param_pairs = []
 91    for key, value in self.params.iteritems():
 92      param_pairs.append('='.join((urllib.quote_plus(key), 
 93          urllib.quote_plus(str(value)))))
 94    return '&'.join(param_pairs)
 95
 96  def get_request_uri(self):
 97    """Returns the path with the parameters escaped and appended."""
 98    param_string = self.get_param_string()
 99    if param_string:
100      return '?'.join([self.path, param_string])
101    else:
102      return self.path
103
104  def __cmp__(self, other):
105    if not isinstance(other, Url):
106      return cmp(self.to_string(), str(other))
107    difference = 0
108    # Compare the protocol
109    if self.protocol and other.protocol:
110      difference = cmp(self.protocol, other.protocol)
111    elif self.protocol and not other.protocol:
112      difference = cmp(self.protocol, DEFAULT_PROTOCOL)
113    elif not self.protocol and other.protocol:
114      difference = cmp(DEFAULT_PROTOCOL, other.protocol)
115    if difference != 0:
116      return difference
117    # Compare the host
118    difference = cmp(self.host, other.host)
119    if difference != 0:
120      return difference
121    # Compare the port
122    if self.port and other.port:
123      difference = cmp(self.port, other.port)
124    elif self.port and not other.port:
125      difference = cmp(self.port, DEFAULT_PORT)
126    elif not self.port and other.port:
127      difference = cmp(DEFAULT_PORT, other.port)
128    if difference != 0:
129      return difference
130    # Compare the path
131    difference = cmp(self.path, other.path)
132    if difference != 0:
133      return difference
134    # Compare the parameters
135    return cmp(self.params, other.params)
136
137  def __str__(self):
138    return self.to_string()
139