Updating git
This commit is contained in:
70
src/core/fasthtml_helper.py
Normal file
70
src/core/fasthtml_helper.py
Normal file
@@ -0,0 +1,70 @@
|
||||
from fastcore.basics import NotStr
|
||||
|
||||
from core.utils import merge_classes
|
||||
|
||||
attr_map = {
|
||||
"cls": "class",
|
||||
"_id": "id",
|
||||
}
|
||||
|
||||
|
||||
def to_html(item):
|
||||
if item is None:
|
||||
return ""
|
||||
elif isinstance(item, str):
|
||||
return item
|
||||
elif isinstance(item, (int, float, bool)):
|
||||
return str(item)
|
||||
elif isinstance(item, MyFt):
|
||||
return item.to_html()
|
||||
elif isinstance(item, NotStr):
|
||||
return str(item)
|
||||
else:
|
||||
raise Exception(f"Unsupported type: {type(item)}, {item=}")
|
||||
|
||||
|
||||
class MyFt:
|
||||
def __init__(self, name, *args, **kwargs):
|
||||
self.name = name
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
|
||||
def to_html(self):
|
||||
body_items = [to_html(item) for item in self.args]
|
||||
return f"<{self.name} {' '.join(f'{attr_map.get(k, k)}="{v}"' for k, v in self.kwargs.items())}>{' '.join(body_items)}</div>"
|
||||
|
||||
def __ft__(self):
|
||||
return NotStr(self.to_html())
|
||||
|
||||
|
||||
class MyDiv(MyFt):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__("div", *args, **kwargs)
|
||||
|
||||
|
||||
class MySpan(MyFt):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__("span", *args, **kwargs)
|
||||
|
||||
|
||||
def mk_my_ellipsis(txt: str, cls='', **kwargs):
|
||||
merged_cls = merge_classes("truncate",
|
||||
cls,
|
||||
kwargs)
|
||||
return MyDiv(txt, cls=merged_cls, data_tooltip=txt, **kwargs)
|
||||
|
||||
|
||||
def mk_my_icon(icon, size=20, can_select=True, can_hover=False, cls='', tooltip=None, **kwargs):
|
||||
merged_cls = merge_classes(f"icon-{size}",
|
||||
'icon-btn' if can_select else '',
|
||||
'mmt-btn' if can_hover else '',
|
||||
cls,
|
||||
kwargs)
|
||||
return mk_my_tooltip(icon, tooltip, cls=merged_cls, **kwargs) if tooltip else MyDiv(icon, cls=merged_cls, **kwargs)
|
||||
|
||||
|
||||
def mk_my_tooltip(element, tooltip: str, cls='', **kwargs):
|
||||
merged_cls = merge_classes("mmt-tooltip",
|
||||
cls,
|
||||
kwargs)
|
||||
return MyDiv(element, cls=merged_cls, data_tooltip=tooltip, **kwargs)
|
||||
@@ -1,12 +1,15 @@
|
||||
import ast
|
||||
import base64
|
||||
import cProfile
|
||||
import hashlib
|
||||
import importlib
|
||||
import inspect
|
||||
import pkgutil
|
||||
import re
|
||||
import time
|
||||
import types
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
from io import BytesIO
|
||||
from urllib.parse import urlparse
|
||||
@@ -420,6 +423,62 @@ def split_host_port(url):
|
||||
return host, port
|
||||
|
||||
|
||||
def timed(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
start = time.perf_counter()
|
||||
result = func(*args, **kwargs)
|
||||
end = time.perf_counter()
|
||||
|
||||
# get class name
|
||||
class_name = None
|
||||
if args:
|
||||
# check the first argument to see if it's a class'
|
||||
if inspect.isclass(args[0]):
|
||||
class_name = args[0].__name__ # class method
|
||||
elif hasattr(args[0], "__class__"):
|
||||
class_name = args[0].__class__.__name__ # instance method
|
||||
|
||||
if class_name:
|
||||
print(f"[PERF] {class_name}.{func.__name__} took {end - start:.4f} sec")
|
||||
else:
|
||||
print(f"[PERF] {func.__name__} took {end - start:.4f} sec")
|
||||
|
||||
return result
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def profile_function(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
profiler = cProfile.Profile()
|
||||
profiler.enable()
|
||||
result = func(*args, **kwargs)
|
||||
profiler.disable()
|
||||
|
||||
# Determine class name if any
|
||||
class_name = None
|
||||
if args:
|
||||
if inspect.isclass(args[0]):
|
||||
class_name = args[0].__name__ # class method
|
||||
elif hasattr(args[0], "__class__"):
|
||||
class_name = args[0].__class__.__name__ # instance method
|
||||
|
||||
# Compose filename with timestamp
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
if class_name:
|
||||
filename = f"{class_name}_{func.__name__}_{timestamp}.prof"
|
||||
else:
|
||||
filename = f"{func.__name__}_{timestamp}.prof"
|
||||
|
||||
# Dump stats to file
|
||||
profiler.dump_stats(filename)
|
||||
print(f"[PROFILE] Profiling data saved to {filename}")
|
||||
|
||||
return result
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
class UnreferencedNamesVisitor(ast.NodeVisitor):
|
||||
"""
|
||||
Try to find symbols that will be requested by the ast
|
||||
@@ -464,4 +523,3 @@ class UnreferencedNamesVisitor(ast.NodeVisitor):
|
||||
"""
|
||||
self.names.add(node.arg)
|
||||
self.visit_selected(node, ["value"])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user