darabonba/url.py (75 lines of code) (raw):
import re
from urllib.parse import urlparse, urlunparse, quote
PORT_MAP = {
"ftp": "21",
"gopher": "70",
"http": "80",
"https": "443",
"ws": "80",
"wss": "443"
}
class Url:
def __init__(self, url_str):
self._url = urlparse(url_str)
@staticmethod
def new_url(url_str):
try:
return Url(url_str)
except Exception as e:
raise e
def path(self):
if not self._url.query:
return self._url.path
return f"{self._url.path}?{self._url.query}"
def pathname(self):
return self._url.path
def protocol(self):
return self._url.scheme
def hostname(self):
return self._url.hostname
def host(self):
if self._url.port:
return f"{self._url.hostname}:{self._url.port}"
return self._url.hostname
def port(self):
if self._url.port:
return str(self._url.port)
return PORT_MAP.get(self.protocol(), "")
def hash(self):
return self._url.fragment
def search(self):
return self._url.query
def href(self):
return urlunparse(self._url)
def auth(self):
if self._url.username or self._url.password:
return f"{self._url.username}:{self._url.password or ''}"
return ""
@staticmethod
def parse(url_str):
return Url.new_url(url_str)
@staticmethod
def url_encode(url_str):
if not url_str:
return ""
parts = url_str.split('/')
encoded_parts = [quote(part, safe='') for part in parts]
encoded_url = '/'.join(encoded_parts)
encoded_url = encoded_url.replace("+", "%20").replace("*", "%2A").replace("%7E", "~")
return encoded_url
@staticmethod
def percent_encode(uri):
if not uri:
return ""
encoded_uri = quote(uri, safe='')
encoded_uri = encoded_uri.replace("+", "%20").replace("*", "%2A").replace("%7E", "~")
return encoded_uri
@staticmethod
def path_encode(path):
if not path or path == "/":
return path
parts = path.split('/')
encoded_parts = [quote(part, safe='') for part in parts]
encoded_path = '/'.join(encoded_parts)
encoded_path = encoded_path.replace("+", "%20").replace("*", "%2A").replace("%7E", "~")
return encoded_path