mirror of
https://github.com/migatu/astrololo.git
synced 2026-07-14 13:34:38 +00:00
Ranking siły (LOG-21) + grupowanie identycznych opisów + geolokalizacja
Punktacja siły (LOG-21): - scoring.py: siła fasety z sygnałów obliczalnych (typ fasety, rodzaj aspektu, ciasnota orbu). Konfigurowalne wagi. Hook na przyszłość: kolumny countas*/level* z SIGNIFICATORS KEY (obecnie puste). - aspekty niosą orb+allowed; fasety dostają "score"; ranking faset malejąco. Grupowanie: - opcja group: zwija próbki po opisie (ten sam efekt = jedna grupa z listą sygnifikatorów i licznikiem). Checkbox "grupuj identyczne opisy" w /interpret. Geolokalizacja (bajer): - "Tu i teraz" (widok Horoskop i Interpretacje) uzupełnia lat/lon z przeglądarki (navigator.geolocation; wymaga zgody, https/localhost). Zweryfikowano na realnym main_base.xlsx: ranking sensowny (ciasna opozycja z Saturn 9.59 > szeroka koniunkcja z Moon 6.25 > znak/dom 5.0); grupowanie zwija powtórzone opisy. 41 testów przechodzi. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -44,9 +44,11 @@ class LogicClient:
|
||||
r.raise_for_status()
|
||||
return r.json()
|
||||
|
||||
def report(self, when_utc_iso: str, lat: float, lon: float, limit: int = 5000) -> dict[str, Any]:
|
||||
def report(
|
||||
self, when_utc_iso: str, lat: float, lon: float, limit: int = 5000, group: bool = False
|
||||
) -> dict[str, Any]:
|
||||
"""Sygnifikatory z obliczeń szukane w bazie — woła logic /chart/report."""
|
||||
payload = {"when_utc": when_utc_iso, "lat": lat, "lon": lon, "limit": limit}
|
||||
payload = {"when_utc": when_utc_iso, "lat": lat, "lon": lon, "limit": limit, "group": group}
|
||||
with httpx.Client(timeout=max(settings.http_timeout, 30.0)) as client:
|
||||
r = client.post(f"{self.base_url}/chart/report", json=payload)
|
||||
r.raise_for_status()
|
||||
|
||||
@@ -114,13 +114,15 @@ def interpret_run(
|
||||
tz_offset: float = Form(0.0),
|
||||
lat: float = Form(0.0),
|
||||
lon: float = Form(0.0),
|
||||
group: bool = Form(False),
|
||||
):
|
||||
form = {"date": date, "time": time, "tz_offset": tz_offset, "lat": lat, "lon": lon}
|
||||
form = {"date": date, "time": time, "tz_offset": tz_offset,
|
||||
"lat": lat, "lon": lon, "group": group}
|
||||
ctx: dict = {"form": form, "result": None, "error": None, "moment": None}
|
||||
try:
|
||||
iso_utc, label = _build_utc(date, time, tz_offset)
|
||||
ctx["moment"] = label
|
||||
ctx["result"] = logic.report(when_utc_iso=iso_utc, lat=lat, lon=lon)
|
||||
ctx["result"] = logic.report(when_utc_iso=iso_utc, lat=lat, lon=lon, group=group)
|
||||
except httpx.HTTPError as e:
|
||||
ctx["error"] = _logic_error(e)
|
||||
except ValueError as e:
|
||||
|
||||
@@ -61,4 +61,6 @@ tr:last-child td { border-bottom: none; }
|
||||
.samples td.nowrap { color: var(--accent); padding-right: 1rem; }
|
||||
.facet { margin: .4rem 0 .6rem 1rem; }
|
||||
.facet-head { color: var(--ink); font-size: .9rem; }
|
||||
.badge { display: inline-block; font-size: .72rem; padding: .05rem .4rem; border-radius: 6px;
|
||||
background: #2a2d4a; color: var(--accent); margin-left: .3rem; }
|
||||
.samples td.sig { color: var(--accent); padding-right: 1rem; cursor: help; }
|
||||
|
||||
@@ -119,6 +119,13 @@
|
||||
d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate());
|
||||
document.querySelector('input[name=time]').value = pad(d.getHours()) + ':' + pad(d.getMinutes());
|
||||
document.querySelector('input[name=tz_offset]').value = (-d.getTimezoneOffset() / 60);
|
||||
// bajer: lokalizacja z przeglądarki (wymaga zgody; działa na https/localhost)
|
||||
if (navigator.geolocation) {
|
||||
navigator.geolocation.getCurrentPosition(function (pos) {
|
||||
document.querySelector('input[name=lat]').value = pos.coords.latitude.toFixed(4);
|
||||
document.querySelector('input[name=lon]').value = pos.coords.longitude.toFixed(4);
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
<input type="number" name="lon" step="0.0001" value="{{ form.lon if form.lon is not none else 0 }}">
|
||||
</label>
|
||||
</div>
|
||||
<div class="opts">
|
||||
<label><input type="checkbox" name="group" value="true" {{ 'checked' if form.group else '' }}> grupuj identyczne opisy</label>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button type="button" id="nowBtn" class="ghost">Tu i teraz</button>
|
||||
<button type="submit">Szukaj interpretacji</button>
|
||||
@@ -51,8 +54,20 @@
|
||||
{% for f in o.facets %}
|
||||
<div class="facet">
|
||||
<div class="facet-head">{{ f.label }} — <strong>{{ f.count }}</strong> dopasowań
|
||||
<span class="badge" title="siła (LOG-21)">siła {{ f.score }}</span>
|
||||
<span class="muted small">[{{ f.token }}]</span></div>
|
||||
{% if f.samples %}
|
||||
{% if f.groups %}
|
||||
<table class="samples">
|
||||
<tbody>
|
||||
{% for g in f.groups %}
|
||||
<tr>
|
||||
<td>{{ g.effect }}{% if g.count > 1 %} <span class="badge">×{{ g.count }}</span>{% endif %}</td>
|
||||
<td class="sig small">{{ g.significators | join('; ') }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% elif f.samples %}
|
||||
<table class="samples">
|
||||
<tbody>
|
||||
{% for s in f.samples %}
|
||||
@@ -75,6 +90,13 @@
|
||||
d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate());
|
||||
document.querySelector('input[name=time]').value = pad(d.getHours()) + ':' + pad(d.getMinutes());
|
||||
document.querySelector('input[name=tz_offset]').value = (-d.getTimezoneOffset() / 60);
|
||||
// bajer: lokalizacja z przeglądarki (wymaga zgody; działa na https/localhost)
|
||||
if (navigator.geolocation) {
|
||||
navigator.geolocation.getCurrentPosition(function (pos) {
|
||||
document.querySelector('input[name=lat]').value = pos.coords.latitude.toFixed(4);
|
||||
document.querySelector('input[name=lon]').value = pos.coords.longitude.toFixed(4);
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user