73 lines
2.3 KiB
Python
73 lines
2.3 KiB
Python
"""Backfill workout active_calories / steps from notes via regex."""
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
|
|
|
from sqlalchemy import select
|
|
|
|
from app.db.base import SessionLocal
|
|
from app.db.models import WorkoutLog
|
|
|
|
ACTIVE_PATTERNS = [
|
|
re.compile(r"(?:active|активн(?:ые|ых)?)\s*(?:калор|kcal|ккал)[^\d]*(\d+(?:[.,]\d+)?)", re.I),
|
|
re.compile(r"(\d+(?:[.,]\d+)?)\s*(?:ккал|kcal)\s*(?:active|актив)", re.I),
|
|
re.compile(r"актив[^\d]{0,20}(\d+(?:[.,]\d+)?)", re.I),
|
|
]
|
|
TOTAL_PATTERNS = [
|
|
re.compile(r"(?:total|всего|сожжено|burned)[^\d]*(\d+(?:[.,]\d+)?)\s*(?:ккал|kcal)", re.I),
|
|
re.compile(r"(\d+(?:[.,]\d+)?)\s*(?:ккал|kcal)\s*(?:total|всего)", re.I),
|
|
]
|
|
STEPS_PATTERNS = [
|
|
re.compile(r"(?:шаг|step)s?\s*[:\-]?\s*(\d+)", re.I),
|
|
re.compile(r"(\d+)\s*(?:шаг|steps)", re.I),
|
|
]
|
|
|
|
|
|
def _first(patterns: list[re.Pattern[str]], text: str, *, as_int: bool = False):
|
|
for pat in patterns:
|
|
m = pat.search(text)
|
|
if not m:
|
|
continue
|
|
raw = m.group(1).replace(",", ".")
|
|
return int(float(raw)) if as_int else float(raw)
|
|
return None
|
|
|
|
|
|
def main() -> None:
|
|
db = SessionLocal()
|
|
updated = 0
|
|
try:
|
|
rows = db.scalars(select(WorkoutLog)).all()
|
|
for row in rows:
|
|
text = f"{row.title or ''}\n{row.notes or ''}"
|
|
changed = False
|
|
if row.active_calories is None:
|
|
val = _first(ACTIVE_PATTERNS, text)
|
|
if val is not None:
|
|
row.active_calories = float(val)
|
|
changed = True
|
|
if row.total_calories is None:
|
|
val = _first(TOTAL_PATTERNS, text)
|
|
if val is not None:
|
|
row.total_calories = float(val)
|
|
changed = True
|
|
if row.steps is None:
|
|
val = _first(STEPS_PATTERNS, text, as_int=True)
|
|
if val is not None:
|
|
row.steps = int(val)
|
|
changed = True
|
|
if changed:
|
|
updated += 1
|
|
db.commit()
|
|
print(f"updated {updated} workout rows")
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|