Spaces:
Running on Zero
Running on Zero
| """Email signup for Microfactory updates. | |
| Lightweight, privacy-first opt-in collection. Stores one JSONL row per signup: | |
| {ts, email, consent, source, app_version}. Local runs write to data/signups.jsonl. | |
| Space runs can additionally push to a private HF dataset via CommitScheduler if | |
| SIGNUPS_DATASET and HF_TOKEN are set. Never writes without explicit consent. | |
| """ | |
| from __future__ import annotations | |
| import json | |
| import os | |
| import re | |
| import threading | |
| from datetime import datetime, timezone | |
| from pathlib import Path | |
| from typing import Any | |
| SIGNUPS_FILE = Path(__file__).resolve().parent.parent / "data" / "signups.jsonl" | |
| SIGNUPS_DATASET = os.environ.get("SIGNUPS_DATASET", "kylebrodeur/microfactory-signups").strip() | |
| FLUSH_MINUTES = 5 | |
| _scheduler: Any = None | |
| _lock = threading.Lock() | |
| _EMAIL_RE = re.compile(r"^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$") | |
| def _get_scheduler(): | |
| """Lazy-init CommitScheduler for the private signup dataset.""" | |
| global _scheduler | |
| token = os.environ.get("HF_TOKEN", "").strip() | |
| if not token: | |
| return None | |
| if not SIGNUPS_DATASET or "/" not in SIGNUPS_DATASET: | |
| return None | |
| if _scheduler is None: | |
| with _lock: | |
| if _scheduler is None: | |
| try: | |
| from huggingface_hub import CommitScheduler | |
| except ImportError: | |
| return None | |
| SIGNUPS_FILE.parent.mkdir(parents=True, exist_ok=True) | |
| if not SIGNUPS_FILE.exists(): | |
| SIGNUPS_FILE.write_text("", encoding="utf-8") | |
| _scheduler = CommitScheduler( | |
| repo_id=SIGNUPS_DATASET, | |
| repo_type="dataset", | |
| folder_path=str(SIGNUPS_FILE.parent), | |
| every=FLUSH_MINUTES, | |
| token=token, | |
| allow_patterns=["signups.jsonl"], | |
| ) | |
| return _scheduler | |
| def is_active() -> bool: | |
| """True if signup syncing to HF is configured and active.""" | |
| return _get_scheduler() is not None | |
| def validate_email(email: str) -> str | None: | |
| """Return normalized email or None if invalid.""" | |
| if not email: | |
| return None | |
| email = email.strip().lower() | |
| if not _EMAIL_RE.match(email): | |
| return None | |
| return email | |
| def record_signup(email: str, consent: bool, source: str = "local") -> tuple[bool, str]: | |
| """Record one signup. Returns (ok, message). | |
| Requires explicit consent. Email is validated. Writes locally always; | |
| pushes to HF only when HF_TOKEN + SIGNUPS_DATASET are present. | |
| """ | |
| if not consent: | |
| return False, "Please check the box to opt in before submitting." | |
| normalized = validate_email(email) | |
| if normalized is None: | |
| return False, "Enter a valid email address." | |
| row = { | |
| "ts": datetime.now(timezone.utc).isoformat(), | |
| "email": normalized, | |
| "consent": True, | |
| "source": source, | |
| "app_version": os.environ.get("CHIEF_ENGINEER_VERSION", "0.1.0"), | |
| } | |
| try: | |
| SIGNUPS_FILE.parent.mkdir(parents=True, exist_ok=True) | |
| with _lock: | |
| with SIGNUPS_FILE.open("a", encoding="utf-8") as f: | |
| f.write(json.dumps(row, ensure_ascii=False) + "\n") | |
| sched = _get_scheduler() | |
| if sched is not None: | |
| try: | |
| sched.trigger() | |
| except Exception: | |
| pass | |
| return True, "You're on the list. Microfactory updates will hit that inbox." | |
| except Exception as e: | |
| return False, f"Could not save signup: {e}" | |
| def privacy_notice() -> str: | |
| return ( | |
| "<div class='ce-sub' style='font-size:10px;opacity:0.7;margin-top:4px;'>" | |
| "📬 Microfactory updates: one email, no spam, unsub any time. " | |
| "We store only your email and this timestamp. No print data, no uploaded files.</div>" | |
| ) | |