Source code for storm.uri

#
# Copyright (c) 2006, 2007 Canonical
#
# Written by Gustavo Niemeyer <gustavo@niemeyer.net>
#
# This file is part of Storm Object Relational Mapper.
#
# Storm is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation; either version 2.1 of
# the License, or (at your option) any later version.
#
# Storm is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

try:
    from urllib.parse import quote, unquote
except ImportError:
    # Python 2
    from urllib import quote, unquote


from storm.compat import iter_items
from storm.exceptions import URIError


[docs]class URI(object): username = None password = None host = None port = None database = None def __init__(self, uri_str): try: self.scheme, rest = uri_str.split(":", 1) except ValueError: raise URIError("URI has no scheme: %s" % repr(uri_str)) self.options = {} if "?" in rest: rest, options = rest.split("?", 1) for pair in options.split("&"): key, value = pair.split("=", 1) self.options[unescape(key)] = unescape(value) if rest: if not rest.startswith("//"): self.database = unescape(rest) else: rest = rest[2:] if "/" in rest: rest, database = rest.split("/", 1) self.database = unescape(database) if "@" in rest: userpass, hostport = rest.split("@", 1) else: userpass = None hostport = rest if hostport: if ":" in hostport: host, port = hostport.rsplit(":", 1) self.host = unescape(host) if port: self.port = int(port) else: self.host = unescape(hostport) if userpass is not None: if ":" in userpass: username, password = userpass.rsplit(":", 1) self.username = unescape(username) self.password = unescape(password) else: self.username = unescape(userpass)
[docs] def copy(self): uri = object.__new__(self.__class__) uri.__dict__.update(self.__dict__) uri.options = self.options.copy() return uri
def __str__(self): tokens = [self.scheme, ":"] append = tokens.append if (self.username is not None or self.password is not None or self.host is not None or self.port is not None): append("//") if self.username is not None or self.password is not None: if self.username is not None: append(escape(self.username)) if self.password is not None: append(":") append(escape(self.password)) append("@") if self.host is not None: append(escape(self.host)) if self.port is not None: append(":") append(str(self.port)) append("/") if self.database is not None: append(escape(self.database, "/")) if self.options: options = ["%s=%s" % (escape(key), escape(value)) for key, value in sorted(iter_items(self.options))] append("?") append("&".join(options)) return "".join(tokens) __unicode__ = __str__
[docs]def escape(s, safe=""): return quote(s, safe)
[docs]def unescape(s): return unquote(s)