Skip to content

Instantly share code, notes, and snippets.

@techtonik
Last active August 29, 2015 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save techtonik/8bfb0999a2984610a580 to your computer and use it in GitHub Desktop.
Save techtonik/8bfb0999a2984610a580 to your computer and use it in GitHub Desktop.
urlparse for humans
#!/usr/bin/env python
"""
Public domain work by anatoly techtonik <techtonik@gmail.com>
History:
1.0 - parse URL string and split into attributes
2.0 - modify properties to reconstruct URL with str()
"""
class urlpath(object):
__version__ = '2.0'
protocol = '' # https
server = '' # www.example.com:80
host = '' # www.example.com
port = '' # 80
fullpath = '' # some/app?and&its#params
path = '' # some/app
query = '' # and&its#params
def __init__(self, url=''):
if url:
self.parse(url)
def _expand_server(self):
'''set host, port'''
host = port = ''
if ':' in self.server:
host, port = self.server.split(':', 1)
else:
host = self.server
# avoiding recursion from __setattr__()
super(urlpath, self).__setattr__('host', host)
super(urlpath, self).__setattr__('port', port)
def _expand_fullpath(self):
'''set path, query'''
path = query = ''
if '?' in self.fullpath:
path, query = self.fullpath.split('?', 1)
else:
path = self.fullpath
# setting attributes directly to avoid
# recursion from __setattr__()
super(urlpath, self).__setattr__('path', path)
super(urlpath, self).__setattr__('query', query)
def parse(self, url):
# protocol
if '://' in url:
self.protocol, url2 = url.split('://', 1)
else:
url2 = url
# server
if '/' not in url2:
self.server = url2
#self._expand_server()
#^ called by __setattr__
return
self.server, url3 = url2.split('/', 1)
#self._expand_server()
#^ called by __setattr__
# fullpath
self.fullpath = url3.lstrip('/')
#self._expand_fullpath()
#^ called by __setattr__
def __str__(self):
out = ''
if self.protocol:
out += self.protocol + '://'
out += self.server + "/" + self.fullpath
return out
def __setattr__(self, name, value):
super(urlpath, self).__setattr__(name, value)
if name == 'server':
self._expand_server()
if name == 'fullpath':
self._expand_fullpath()
if name in ('host', 'port'):
# update server value
server = self.host
if self.port:
server += ':' + self.port
super(urlpath, self).__setattr__('server', server)
if name in ('path', 'query'):
fullpath = self.path
if self.query:
fullpath += '?' + self.query
super(urlpath, self).__setattr__('fullpath', fullpath)
if __name__ == '__main__':
# self-test
u = urlpath("http://localhost:8917/demo/path?with&all=this#stuff5")
print(u)
print("protocol: " + u.protocol)
print("server: " + u.server)
print(" host: " + u.host)
print(" port: " + u.port)
print("fullpath: " + u.fullpath)
print(" path: " + u.path)
print(" query: " + u.query)
u.server = 'example.com'
print("\nchange server to example.com")
print("server: " + u.server)
print(" host: " + u.host)
print(" port: " + u.port)
u.port = '8080'
print("\nchange port to 8080")
print("server: " + u.server)
print(" host: " + u.host)
print(" port: " + u.port)
u.fullpath = 'production?param='
print("\nchange fullpath to production?param=")
print("fullpath: " + u.fullpath)
print(" path: " + u.path)
print(" query: " + u.query)
u.path = ''
print("\nchange path to ''")
print("fullpath: " + u.fullpath)
print(" path: " + u.path)
print(" query: " + u.query)
print(u)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment