Source code for urldb.Urldb

import re
import zlib
from urllib import parse
import ujson
import pyperclip


[docs]class UrlDB: """ A "database" class that is really just an alternative representation of the data. *Аргументы* :param base: link to add query string :type base: ``str``, optional :param setdb: convert URL to urlDB class :type setdb: ``str``, URL, optional :param compress: compressing data in URL :type compress: ``bool`` """ def __init__(self, base: str = None, setdb: str = None, compress: bool = None): self.link_data = "" self.data = dict() if setdb: if "#c" in setdb: if compress is None or compress is True: self.compress = True self._parse_link_to_db(setdb) else: self.compress = False self.data = self._decode_with_decompress(setdb) else: self.compress = False self._parse_link_to_db(setdb) else: self.compress = True if compress else False if base and self._is_base_url(base): self.base = base self._url = self.base else: self.base = "https://urldb.pfel.cc/data" self._url = self.base def _is_base_url(self, url): if re.match(r"(https?:\/\/)([a-zA-Z0-9\-\_.?]+)(\/?[a-zA-Z0-9\/]+)", url): return True else: return False def _parse_link_to_db(self, to_parse): if len(to_parse.split("?")) > 1: self.base = to_parse.split("?")[0] self.data = self._decode(to_parse.split("?")[-1].split("#")[0]) self._update_link() def _encode(self, data): if self.compress: return self._encode_with_compress(data) else: return self._encode_without_compress(data) def _decode(self, to): if self.compress: return self._decode_with_decompress(to) else: return self._decode_without_decompress(to) def _encode_without_compress(self, to_encode: dict): pd = [] for k, v in to_encode.items(): pd.append(f"{parse.quote(ujson.dumps(k))}={parse.quote(ujson.dumps(v))}") enc = "&".join(pd) return enc def _encode_with_compress(self, to_encode: dict): return parse.quote(zlib.compress(ujson.dumps(to_encode).encode("utf-8"))) def _decode_with_decompress(self, to_decode: str): return ujson.loads(zlib.decompress(parse.unquote_to_bytes(to_decode)).decode()) def _to_value(self, arg): if arg.isdigit(): return int(arg) else: try: return ujson.loads(arg) except ValueError as e: return ujson.loads(f'"{arg}"') def _decode_without_decompress(self, to_decode: str): data = dict() pd = to_decode.split("&") for i in pd: tmp = i.split("=") k, v = parse.unquote(tmp[0]), parse.unquote(tmp[1]) k, v = self._to_value(k), self._to_value(v) data[k] = v return data def _update_link(self): if len(self.__dict__): self.link_data = self._encode(self.data) self._url = f"{self.base}?{self.link_data}#{'c' if self.compress else 'n'}" else: self._url = f"{self.base}"
[docs] def to_clipboard(self): """ Copy to clipboard """ pyperclip.copy(self._url)
def __setitem__(self, key, item): self.data[key] = item self._update_link() def __getitem__(self, key): return self.data[key] def __repr__(self): return f"<urlDB {self._url}>" def __len__(self): return len(self.data) def __delitem__(self, key): del self.data[key] self._update_link()
[docs] def clear(self): """ Clear the data dict :return: clear URL (``str``) """ self.data.clear() return self.url
[docs] def copy(self): """ Make a copy of the data dict :return: ``dict`` """ return self.data.copy()
[docs] def has_key(self, k): """ :param k: key to check :return: ``bool`` """ return k in self.data
def update(self, *args, **kwargs): self.data.update(*args, **kwargs) self._update_link() return self.data.update({})
[docs] def keys(self): """ :return: ``list`` of keys """ return self.data.keys()
[docs] def values(self): """ :return: ``list`` of values """ return self.data.values()
[docs] def items(self): """ :return: ``list`` of tuple (key, value) """ return self.data.items()
[docs] def pop(self, *args): """ :param: key of pop item :return: value of pop item """ x = self.data.pop(*args) self._update_link() return x
def __cmp__(self, dict_): return self.__cmp__(self.data, dict_) def __contains__(self, item): return item in self.data def __iter__(self): return iter(self.data) @property def url(self): self._update_link() return self.url