import os
import sys
import re
from functools import reduce
from json import dumps
from html import escape
from ipaddress import IPv4Network, IPv6Network
from urllib.parse import quote, unquote, urljoin
from lib.core.settings import (
INVALID_CHARS_FOR_WINDOWS_FILENAME,
INVALID_FILENAME_CHAR_REPLACEMENT,
IS_WINDOWS,
URL_SAFE_CHARS,
SCRIPT_PATH,
TEXT_CHARS,
)
from lib.utils.file import FileUtils
def get_config_file():
return os.environ.get("DIRSEARCH_CONFIG") or FileUtils.build_path(SCRIPT_PATH, "config.ini")
def safequote(string_: str) -> str:
return quote(string_, safe=URL_SAFE_CHARS)
def _strip_and_uniquify_callback(array, item):
item = item.strip()
if not item or item in array:
return array
return array + [item]
def strip_and_uniquify(array, type_=list):
return type_(reduce(_strip_and_uniquify_callback, array, []))
def lstrip_once(string, pattern):
if string.startswith(pattern):
return string[len(pattern):]
return string
def rstrip_once(string, pattern):
if string.endswith(pattern):
return string[:-len(pattern)]
return string
def get_valid_filename(string):
for char in INVALID_CHARS_FOR_WINDOWS_FILENAME:
string = string.replace(char, INVALID_FILENAME_CHAR_REPLACEMENT)
return string
def get_readable_size(num):
base = 1024
units = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
for unit in units:
if -base < num < base:
return f"{num}{unit}"
num = round(num / base)
return f"{num}TB"
def is_binary(bytes) -> bool:
return bool(bytes.translate(None, TEXT_CHARS))
def is_ipv6(ip):
return ip.count(":") >= 2
def iprange(subnet):
network = IPv4Network(subnet)
if is_ipv6(subnet):
network = IPv6Network(subnet)
return [str(ip) for ip in network]
def merge_path(url, path):
parts = url.split("/")
path = urljoin("/", path).lstrip("/")
parts[-1] = path
return "/".join(parts)
def read_stdin():
buffer = sys.stdin.read()
try:
if IS_WINDOWS:
tty = "CON:"
else:
tty = os.ttyname(sys.stdout.fileno())
sys.stdin = open(tty)
except OSError:
pass
return buffer
def replace_path(string, path, replace_with):
def sub(string, to_replace, replace_with):
regex = re.escape(to_replace) + "(?=[^\\w]|$)"
return re.sub(regex, replace_with, string)
path = "/" + path
string = sub(string, quote(path), replace_with)
string = sub(string, quote(quote(path)), replace_with)
string = sub(string, unquote(path), replace_with)
string = sub(string, unquote(unquote(path)), replace_with)
string = sub(string, escape(path), replace_with)
string = sub(string, dumps(path), replace_with)
return sub(string, path, replace_with)