92 lines
2.4 KiB
Python
92 lines
2.4 KiB
Python
|
|
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
|