Spaces:
Sleeping
Sleeping
File size: 4,527 Bytes
a98fb2d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | import json
import time
from pathlib import Path
from typing import Dict, Any, Optional
# Prosty storage w pliku JSON (działa w Space tak długo, jak instancja żyje)
STORAGE_PATH = Path(__file__).resolve().parent.parent / "storage" / "habits.json"
STORAGE_PATH.parent.mkdir(parents=True, exist_ok=True)
# Opcjonalne: zaawansowany pipeline z reels-agent (transkrypcja, summary, Nebius)
try:
from . import transcriber, summarizer # type: ignore
except Exception:
transcriber = None
summarizer = None
def _load_db() -> Dict[str, Any]:
if not STORAGE_PATH.exists():
return {}
try:
with STORAGE_PATH.open("r", encoding="utf-8") as f:
return json.load(f)
except Exception:
return {}
def _save_db(db: Dict[str, Any]) -> None:
with STORAGE_PATH.open("w", encoding="utf-8") as f:
json.dump(db, f, ensure_ascii=False, indent=2)
def _build_initial_step(link: str, category: str) -> str:
"""
Tu próbujemy użyć starego pipeline'u (reels-agent):
- transkrypcja
- summary → konkretna akcja
Jeśli te funkcje nie istnieją / wywalą się → fallback na prosty tekst.
"""
# Fallback – zawsze działa
fallback = "Obejrzyj materiał i zapisz 1 konkretną rzecz, którą dziś wdrożysz."
# Jeśli nie ma modułów – wracamy fallback
if transcriber is None or summarizer is None:
return fallback
try:
# PRZYKŁADOWA KONWENCJA – dopasujesz w razie czego u siebie:
# transcriber.transcribe_link(link) -> str (pełna transkrypcja)
# summarizer.summarize_to_action(text, category) -> str (krótka akcja)
if hasattr(transcriber, "transcribe_link") and hasattr(summarizer, "summarize_to_action"):
text = transcriber.transcribe_link(link) # type: ignore[attr-defined]
action = summarizer.summarize_to_action(text, category) # type: ignore[attr-defined]
if isinstance(action, str) and action.strip():
return action.strip()
except Exception:
# Nie zabijamy Space’a – po prostu wracamy prostą wersję
return fallback
return fallback
def create_contract(uid: str, link: str, category: str) -> Dict[str, Any]:
"""
Tworzy / nadpisuje kontrakt nawyku:
- uid: ID usera (np. szef_1_career)
- link: IG/YT/TikTok
- category: 'career' / 'health' / 'relationships' / ...
Zwraca dict gotowy do wysłania jako JSON przez MCP.
"""
db = _load_db()
initial_step = _build_initial_step(link, category)
contract = {
"uid": uid,
"link": link,
"category": category,
"created_at": int(time.time()),
"streak": 0,
"last_done_at": None,
"next_step": initial_step,
"history": [], # lista wykonanych kroków
}
db[uid] = contract
_save_db(db)
return contract
def get_contract(uid: str) -> Optional[Dict[str, Any]]:
db = _load_db()
return db.get(uid)
def complete_step(uid: str, note: Optional[str] = None) -> Dict[str, Any]:
"""
User zrobił zadanie → zwiększamy streak, dopisujemy do historii
i generujemy kolejny krok (na razie prosty).
"""
db = _load_db()
if uid not in db:
raise ValueError(f"Contract with uid={uid} not found")
contract = db[uid]
now = int(time.time())
# aktualizacja streak
contract["streak"] = int(contract.get("streak") or 0) + 1
contract["last_done_at"] = now
# dopisanie historii
contract.setdefault("history", [])
contract["history"].append(
{
"ts": now,
"done_step": contract.get("next_step"),
"note": note,
}
)
# nowy krok - tutaj możesz później wpiąć bardziej zaawansowany plan_generator
link = contract.get("link", "")
category = contract.get("category", "general")
contract["next_step"] = _build_initial_step(link, category)
db[uid] = contract
_save_db(db)
return contract
def get_next_step(uid: str) -> Dict[str, Any]:
"""
Zwraca aktualny kontrakt i next_step dla danego uid.
"""
contract = get_contract(uid)
if not contract:
raise ValueError(f"Contract with uid={uid} not found")
return {
"uid": contract["uid"],
"link": contract["link"],
"category": contract["category"],
"streak": contract.get("streak", 0),
"next_step": contract.get("next_step"),
"last_done_at": contract.get("last_done_at"),
} |