Rename src CoreLibs to corelibs

This commit is contained in:
Clemens Schwaighofer
2025-07-08 09:58:33 +09:00
34 changed files with 1 additions and 1 deletions

View File

View File

@@ -0,0 +1,37 @@
"""
Format bytes
"""
def format_bytes(byte_value: float | int | str) -> str:
"""
Format a byte value to a human readable string
Arguments:
byte_value {float | int | str} -- _description_
Returns:
str -- _description_
"""
# if string exit
if isinstance(byte_value, str):
return byte_value
# empty byte value is set to 0
if not byte_value:
byte_value = float(0)
# if not float, convert to flaot
if isinstance(byte_value, int):
byte_value = float(byte_value)
# loop through valid extensions
for unit in ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB"]:
# never go into the negativ and check if it is smaller than next set
# if it is, print out return string
if abs(byte_value) < 1024.0:
return f"{byte_value:,.2f} {unit}"
# divided for the next loop check
byte_value /= 1024.0
# if it is too big, return YB
return f"{byte_value:,.2f} YB"
# __NED__

View File

@@ -0,0 +1,63 @@
"""
Various string based date/time helpers
"""
from math import floor
import time
def convert_timestamp(timestamp: float | int, show_micro: bool = True) -> str:
"""
format timestamp into human readable format
Arguments:
timestamp {float} -- _description_
Keyword Arguments:
show_micro {bool} -- _description_ (default: {True})
Returns:
str -- _description_
"""
# cut of the ms, but first round them up to four
__timestamp_ms_split = str(round(timestamp, 4)).split(".")
timestamp = int(__timestamp_ms_split[0])
try:
ms = int(__timestamp_ms_split[1])
except IndexError:
ms = 0
timegroups = (86400, 3600, 60, 1)
output: list[int] = []
for i in timegroups:
output.append(int(floor(timestamp / i)))
timestamp = timestamp % i
# output has days|hours|min|sec ms
time_string = ""
if output[0]:
time_string = f"{output[0]}d"
if output[0] or output[1]:
time_string += f"{output[1]}h "
if output[0] or output[1] or output[2]:
time_string += f"{output[2]}m "
time_string += f"{output[3]}s"
if show_micro:
time_string += f" {ms}ms" if ms else " 0ms"
return time_string
def create_time(timestamp: float, timestamp_format: str = "%Y-%m-%d %H:%M:%S") -> str:
"""
just takes a timestamp and prints out humand readable format
Arguments:
timestamp {float} -- _description_
Keyword Arguments:
timestamp_format {_type_} -- _description_ (default: {"%Y-%m-%d %H:%M:%S"})
Returns:
str -- _description_
"""
return time.strftime(timestamp_format, time.localtime(timestamp))
# __END__

View File

@@ -0,0 +1,226 @@
"""
Format double byte strings to exact length
"""
import unicodedata
class DoubleByteFormatString:
"""
Format a string to exact length
"""
def __init__(
self,
string: str,
cut_length: int,
format_length: int | None = None,
placeholder: str = '..',
format_string: str = '{{:<{len}}}'
):
"""
shorts a string to exact cut length and sets it to format length
after "cut_length" cut the "placeholder" will be added, so that the new cut_length is never
larget than the cut_length given (".." is counted to cut_length)
if format_length if set and outside format_length will be set
the cut_length is adjusted to format_length if the format_length is shorter
Example
"Foo bar baz" 10 charcters -> 5 cut_length -> 10 format_length
"Foo.. "
use class.get_string_short() for cut length shortend string
use class.get_string_short_formated() to get the shorted string to format length padding
creates a class that shortens and sets the format length
to use with a print format run the format needs to be pre set in
the style of {{:<{len}}} style
self.get_string_short_formated() for the "len" parameter
Args:
string (str): string to work with
cut_length (int): width to shorten to
format_length (int | None): format length. Defaults to None
placeholder (str, optional): placeholder to put after shortened string. Defaults to '..'.
format_string (str, optional): format string. Defaults to '{{:<{len}}}'
"""
# output variables
self.string_short: str = ''
self.string_width_value: int = 0
self.string_short_width: int = 0
self.format_length_value: int = 0
# internal varaibles
self.placeholder: str = placeholder
# original string
self.string: str = ''
# width to cut string to
self.cut_length: int = 0
# format length to set to
self.format_length: int = 0
# main string
self.string = str(string)
self.format_string: str = format_string
# if width is > 0 set, else set width of string (fallback)
if cut_length > 0:
self.cut_length = cut_length
elif cut_length <= 0:
self.cut_length = self.__string_width_calc(self.string)
# format length set, if not set or smaller than 0, set to width of string
self.format_length = self.cut_length
if format_length is not None and format_length > 0:
self.format_length = format_length
# check that width is not larger then length if yes, set width to length
self.cut_length = min(self.cut_length, self.format_length)
# process the string shorten and format length calculation
self.process()
def process(self):
"""
runs all the class methods to set string length, the string shortened
and the format length
"""
# call the internal ones to set the data
if self.string:
self.__string_width()
self.__shorten_string()
if self.format_length:
self.__format_length()
def get_string_short(self) -> str:
"""
get the shortend string
Returns:
str -- _description_
"""
return self.string_short
def get_string_short_formated(self, format_string: str = '{{:<{len}}}') -> str:
"""
get the formatted string
Keyword Arguments:
format_string {_type_} -- _description_ (default: {'{{:<{len}}}'})
Returns:
str -- _description_
"""
if not format_string:
format_string = self.format_string
return format_string.format(
len=self.get_format_length()
).format(
self.get_string_short()
)
def get_format_length(self) -> int:
"""
get the format length for outside length set
Returns:
int -- _description_
"""
return self.format_length_value
def get_cut_length(self) -> int:
"""
get the actual cut length
Returns:
int -- _description_
"""
return self.cut_length
def get_requested_cut_length(self) -> int:
"""
get the requested cut length
Returns:
int -- _description_
"""
return self.cut_length
def get_requested_format_length(self) -> int:
"""
get the requested format length
Returns:
int -- _description_
"""
return self.format_length
def __string_width_calc(self, string: str) -> int:
"""
does the actual string width calculation
Args:
string (str): string to calculate from
Returns:
int: stringth width
"""
return sum(1 + (unicodedata.east_asian_width(c) in "WF") for c in string)
def __string_width(self):
"""
calculates the string width based on the characters
this is an internal method and should not be called on itself
"""
# only run if string is set and is valid string
if self.string:
# calculate width. add +1 for each double byte character
self.string_width_value = self.__string_width_calc(self.string)
def __format_length(self):
"""
set the format length based on the length for the format
and the shortend string
this is an internal method and should not be called on itself
"""
if not self.string_short:
self.__shorten_string()
# get correct format length based on string
if (
self.string_short and
self.format_length > 0 and
self.string_short_width > 0
):
# length: format length wanted
# substract the width of the shortend string - the length of the shortend string
self.format_length_value = self.format_length - (self.string_short_width - len(self.string_short))
else:
# if we have nothing to shorten the length, keep the old one
self.format_length_value = self.format_length
def __shorten_string(self):
"""
shorten string down to set width
this is an internal method and should not be called on itself
"""
# set string width if not set
if not self.string_width_value:
self.__string_width()
# if the double byte string width is larger than the wanted width
if self.string_width_value > self.cut_length:
cur_len = 0
self.string_short = ''
for char in str(self.string):
# set the current length if we add the character
cur_len += 2 if unicodedata.east_asian_width(char) in "WF" else 1
# if the new length is smaller than the output length to shorten too add the char
if cur_len <= (self.cut_length - len(self.placeholder)):
self.string_short += char
self.string_short_width = cur_len
# return string with new width and placeholder
self.string_short = f"{self.string_short}{self.placeholder}"
self.string_short_width += len(self.placeholder)
else:
# if string is same saze just copy
self.string_short = self.string
# __END__

View File

@@ -0,0 +1,40 @@
"""
Various hash helpers for strings and things
"""
import re
import hashlib
def crc32b_fix(crc: str) -> str:
"""
fix a CRC32B with wrong order (from old PHP)
Arguments:
crc {str} -- _description_
Returns:
str -- _description_
"""
# left pad with 0 to 8 chars
crc = ("0" * (8 - len(crc))) + crc
# flip two chars (byte hex)
crc = re.sub(
r"^([a-z0-9]{2})([a-z0-9]{2})([a-z0-9]{2})([a-z0-9]{2})$", r"\4\3\2\1", crc
)
return crc
def sha1_short(string: str) -> str:
"""
Return a 9 character long SHA1 part
Arguments:
string {str} -- _description_
Returns:
str -- _description_
"""
return hashlib.sha1(string.encode('utf-8')).hexdigest()[:9]
# __END__

View File

@@ -0,0 +1,86 @@
"""
String helpers
"""
from textwrap import shorten
def shorten_string(string: str, length: int, hard_shorten: bool = False, placeholder: str = " [~]") -> str:
"""
check if entry is too long and cut it, but only for console output
Note that if there are no spaces in the string, it will automatically use the hard split mode
Args:
string (str): _description_
length (int): _description_
hard_shorten (bool): if shorte should be done on fixed string lenght. Default: False
placeholder (str): placeholder string. Default: " [~]"
Returns:
str: _description_
"""
length = int(length)
string = str(string)
if len(string) > length:
if hard_shorten is True or " " not in string:
short_string = f"{string[:(length - len(placeholder))]}{placeholder}"
else:
short_string = shorten(string, width=length, placeholder=placeholder)
else:
short_string = string
return short_string
def left_fill(string: str, width: int, char: str = " ") -> str:
"""
left fill for a certain length to fill a max size
string is the original string to left padd, width is the maximum width
that needs to be filled, char is the filler character
Arguments:
string {str} -- _description_
width {int} -- _description_
Keyword Arguments:
char {str} -- _description_ (default: {" "})
Returns:
str -- _description_
"""
# the width needs to be string
if width < 0:
width = len(string)
# char can only be one length long
if len(char) != 1:
char = " "
return (
"{:"
f"{char}>{width}"
"}"
).format(string)
def format_number(number: float, precision: int = 0) -> str:
"""
format numbers, current trailing zeros does not work
use {:,} or {:,.f} or {:,.<N>f} <N> = number instead of this
Arguments:
number {float} -- _description_
Keyword Arguments:
precision {int} -- _description_ (default: {0})
Returns:
str -- _description_
"""
if precision < 0 and precision > 100:
precision = 0
return (
"{:,."
f"{str(precision)}"
"f}"
).format(number)
# __END__