|
import inspect |
|
import sys |
|
|
|
|
|
system_encoding = sys.getdefaultencoding() |
|
|
|
if system_encoding != "utf-8": |
|
|
|
def make_safe(string): |
|
|
|
|
|
return string.encode(system_encoding, errors="replace").decode(system_encoding) |
|
|
|
else: |
|
|
|
def make_safe(string): |
|
|
|
return string |
|
|
|
|
|
def str_to_valid_type(val: str): |
|
if len(val) == 0: |
|
return None |
|
if '/' in val: |
|
return [a.split('*') if '*' in a else a for a in val.split('/')] |
|
try: |
|
val = float(val) if '.' in val else int(val) |
|
except ValueError: |
|
pass |
|
finally: |
|
return val |
|
|
|
|
|
def get_func_parameters(func): |
|
return inspect.signature(func).parameters.keys() |
|
|
|
|
|
def isolate_useful_options(options: dict, method, pop: bool = False) -> dict: |
|
_get = dict.pop if pop else dict.get |
|
return {k: _get(options, k) for k in get_func_parameters(method) if k in options} |
|
|
|
|
|
def safe_print(msg: str, _print=None): |
|
if msg: |
|
(_print or print)(make_safe(msg)) |
|
|
|
|
|
def format_timestamp( |
|
seconds: float, always_include_hours: bool = False, decimal_marker: str = "." |
|
): |
|
assert seconds >= 0, "non-negative timestamp expected" |
|
milliseconds = round(seconds * 1000.0) |
|
|
|
hours = milliseconds // 3_600_000 |
|
milliseconds -= hours * 3_600_000 |
|
|
|
minutes = milliseconds // 60_000 |
|
milliseconds -= minutes * 60_000 |
|
|
|
seconds = milliseconds // 1_000 |
|
milliseconds -= seconds * 1_000 |
|
|
|
hours_marker = f"{hours:02d}:" if always_include_hours or hours > 0 else "" |
|
return ( |
|
f"{hours_marker}{minutes:02d}:{seconds:02d}{decimal_marker}{milliseconds:03d}" |
|
) |
|
|
|
|
|
class UnsortedException(Exception): |
|
|
|
def __init__(self, message: str = None, data: dict = None): |
|
if not message: |
|
message = 'Timestamps are not in ascending order. If data is produced by Stable-ts, please submit an issue.' |
|
super().__init__(message) |
|
self.data = data |
|
|
|
def get_data(self): |
|
return self.data |
|
|