Spaces:
Running
Running
| import re | |
| from litestar.response import Response | |
| from litestar.enums import MediaType | |
| # ββ Number parsing ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def parse_human_number(val: str) -> float: | |
| """ | |
| Parse shorthand notation into a float. | |
| Supports k/m/b/t suffixes (case-insensitive), comma separators, a | |
| leading minus sign, and trailing '%' or 'x' so the function is safe | |
| to call on inputs that may come from mixed-type filter boxes. | |
| Examples: | |
| '5m' β 5_000_000 | |
| '100k' β 100_000 | |
| '1.5b' β 1_500_000_000 | |
| '-2b' β -2_000_000_000 | |
| '0' β 0.0 | |
| """ | |
| if not val: | |
| return 0.0 | |
| val = str(val).strip() | |
| negative = val.startswith('-') | |
| val = val.lower().replace(',', '').replace('x', '').replace('%', '').lstrip('-') | |
| parts = re.findall(r'(\d+\.?\d*)([kmbt]?)', val) | |
| mults = {'k': 1_000, 'm': 1_000_000, 'b': 1_000_000_000, 't': 1_000_000_000_000} | |
| total = sum(float(num) * mults.get(unit, 1) for num, unit in parts) | |
| return -total if negative else total | |
| # ββ HTMX HTML helpers βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def html_response(content: str, headers: dict | None = None) -> Response: | |
| """Return a minimal HTML fragment response for HTMX swap targets.""" | |
| return Response(content=content, media_type=MediaType.HTML, headers=headers or {}) | |
| def msg_fragment(text: str, color: str = "red") -> str: | |
| """Render a small Tailwind-styled status message paragraph.""" | |
| return f'<p class="text-{color}-400 font-semibold text-sm">{text}</p>' | |
| # ββ Number & price formatting βββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def format_price(price: float | None) -> str: | |
| if price is None: | |
| return "N/A" | |
| if price >= 10_000: | |
| return f"${price:,.0f}" | |
| if price >= 1: | |
| return f"${price:,.2f}" | |
| if price >= 0.001: | |
| return f"${price:.4f}" | |
| return f"${price:.6f}" | |
| def format_large_number(val: float | None) -> str: | |
| """ | |
| Format a large USD value with a T/B/M/K suffix. | |
| Returns "β" for None (no data). Returns "$0" for an explicit zero | |
| so callers can distinguish a missing value from a zero-valued one. | |
| """ | |
| if val is None: | |
| return "β" | |
| if val >= 1e12: | |
| return f"${val/1e12:.2f}T" | |
| if val >= 1e9: | |
| return f"${val/1e9:.2f}B" | |
| if val >= 1e6: | |
| return f"${val/1e6:.1f}M" | |
| if val >= 1e3: | |
| return f"${val/1e3:.1f}K" | |
| return f"${val:,.0f}" | |
| def format_pct(val: float | None) -> str: | |
| if val is None: | |
| return "β" | |
| return f"{val:+.1f}%" | |
| def color_class(val: float | None) -> str: | |
| if val is None: | |
| return "text-gray-400" | |
| if val > 0: | |
| return "text-green-400" | |
| if val < 0: | |
| return "text-red-400" | |
| return "text-gray-400" | |
| def vtmr_class(vtmr: float) -> str: | |
| if vtmr >= 1.0: | |
| return "text-green-300 font-bold" | |
| if vtmr >= 0.5: | |
| return "text-yellow-400" | |
| return "text-gray-500" | |
| # ββ Token enrichment ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def enrich_token(raw: dict, *, starred: bool = False) -> dict: | |
| """ | |
| Return a display-ready shallow copy of a raw or scanner-enriched coin dict. | |
| The copy is intentionally shallow β callers must not mutate nested objects. | |
| The shared in-memory cache is never modified by this function. | |
| VTMR is extracted with an `is not None` guard so that a scanner-computed | |
| value of 0.0 is preserved rather than discarded in favour of a live | |
| recalculation, keeping filter and display values in sync. | |
| """ | |
| t = dict(raw) | |
| mcap = t.get("market_cap") or 0.0 | |
| vol24 = t.get("total_volume") or 0.0 | |
| _vtmr_raw = t.get("vtmr_raw") | |
| vtmr = _vtmr_raw if _vtmr_raw is not None else ( | |
| (vol24 / mcap) if mcap > 0 else 0.0 | |
| ) | |
| p24 = t.get("price_change_percentage_24h_in_currency") | |
| p7d = t.get("price_change_percentage_7d_in_currency") | |
| p30d = t.get("price_change_percentage_30d_in_currency") | |
| p1y = t.get("price_change_percentage_1y_in_currency") | |
| t.update( | |
| fmt_price = format_price(t.get("current_price")), | |
| fmt_mcap = format_large_number(mcap if t.get("market_cap") is not None else None), | |
| fmt_volume = format_large_number(vol24 if t.get("total_volume") is not None else None), | |
| fmt_24h = format_pct(p24), | |
| cls_24h = color_class(p24), | |
| fmt_7d = format_pct(p7d), | |
| cls_7d = color_class(p7d), | |
| fmt_30d = format_pct(p30d), | |
| cls_30d = color_class(p30d), | |
| fmt_1y = format_pct(p1y), | |
| cls_1y = color_class(p1y), | |
| vtmr_raw = vtmr, | |
| vtmr_display = f"{vtmr:.3f}x", | |
| vtmr_class = vtmr_class(vtmr), | |
| starred = starred, | |
| ) | |
| return t | |