Spaces:
Runtime error
Runtime error
Download backend/app/support/corpus.py from firebird-technologies/NoteStack-Test: direct link, hf CLI and curl.
- Browser
- Download file 5.06 kB
-
https://huggingface.co/spaces/firebird-technologies/NoteStack-Test/resolve/main/backend/app/support/corpus.py
- Command line
-
hf download hf://spaces/firebird-technologies/NoteStack-Test/backend/app/support/corpus.py
-
curl -L -o corpus.py https://huggingface.co/spaces/firebird-technologies/NoteStack-Test/resolve/main/backend/app/support/corpus.py
5.06 kB
| """The help corpus: markdown files in support/docs, one topic each, loaded once per process. | |
| Each file starts with a small frontmatter block (title, route, keywords, questions, related). The bot answers only | |
| from these files, so a feature is documented here before the bot can talk about it. | |
| """ | |
| import logging | |
| import re | |
| from dataclasses import dataclass | |
| from pathlib import Path | |
| log = logging.getLogger("notestack.support") | |
| DOCS_DIR = Path(__file__).parent / "docs" | |
| _FRONTMATTER = re.compile(r"\A---\n(.*?)\n---\n", re.S) | |
| class Doc: | |
| id: str | |
| title: str | |
| route: str | |
| keywords: tuple[str, ...] | |
| questions: tuple[str, ...] | |
| related_paths: tuple[str, ...] | |
| headings: tuple[str, ...] | |
| body: str | |
| def high_signal_text(self) -> str: | |
| return "\n".join([self.title, *self.keywords, *self.headings, *self.questions]) | |
| def _parse(path: Path) -> Doc: | |
| raw = path.read_text(encoding="utf-8") | |
| match = _FRONTMATTER.match(raw) | |
| meta: dict[str, list[str] | str] = {} | |
| body = raw | |
| if match: | |
| body = raw[match.end():] | |
| key = "" | |
| for line in match.group(1).splitlines(): | |
| if line.startswith(" - ") and key: | |
| meta.setdefault(key, []).append(line[4:].strip()) # type: ignore[union-attr] | |
| elif ":" in line: | |
| key, _, value = line.partition(":") | |
| key, value = key.strip(), value.strip() | |
| meta[key] = value if value else [] | |
| as_list = lambda k: tuple(meta.get(k) or ()) # noqa: E731 | |
| return Doc( | |
| id=path.stem, | |
| title=str(meta.get("title") or path.stem.replace("-", " ").title()), | |
| route=str(meta.get("route") or ""), | |
| keywords=as_list("keywords"), | |
| questions=as_list("questions"), | |
| related_paths=as_list("related"), | |
| headings=tuple(re.findall(r"^#{1,3}\s+(.+)$", body, re.M)), | |
| body=body.strip(), | |
| ) | |
| def _plans_doc() -> Doc: | |
| """Built from services/plans.py so prices and limits can never drift from what the app enforces.""" | |
| from app.services.plans import PLANS, annual_prices, plan_order | |
| order = plan_order() # the plans table's (editable without a deploy), so the names and count come from it too | |
| names = [PLANS[pid].name for pid in order] | |
| listed = ", ".join(names[:-1]) + f" and {names[-1]}" if len(names) > 1 else "".join(names) | |
| lines = ["# Plans", f"Notestack has {len(names)} plans: {listed}. Prices are in US dollars."] | |
| for pid in order: | |
| p = PLANS[pid] | |
| price = "free" if not p.price_monthly_usd else f"${p.price_monthly_usd:g} a month" | |
| if p.price_monthly_usd: | |
| monthly, yearly = annual_prices(p) | |
| price += f", or ${monthly:g} a month billed yearly (${yearly:g} a year)" | |
| per = "in total, never renewing," if p.lifetime else "a month" | |
| def count(n: int) -> str: | |
| return "unlimited" if n < 0 else str(n) | |
| audio = f"{count(p.audio_overviews)} audio overviews in total, any length" if p.audio_overviews >= 0 \ | |
| else f"{p.audio_minutes} minutes of audio a month" | |
| lines += [ | |
| f"## {p.name}", | |
| f"{p.tagline}. Price: {price}.", | |
| f"Limits: {p.sources} sources, {p.indexed_posts} indexed posts across every source, {audio}, " | |
| f"{p.videos} videos {'a month' if p.videos_monthly else 'in total, never renewing'}, " | |
| f"{count(p.launch_kits)} Launch Kits {per}, {count(p.infographics)} infographics {per}, " | |
| f"{count(p.reports)} reports a month. " | |
| f"Voice cloning: {'yes' if p.voice_cloning else 'no'}.", | |
| "Includes: " + "; ".join(p.features) + ".", | |
| ] | |
| lines += [ | |
| "## Billing", | |
| "Upgrade, change plan or manage billing from Settings under Plan and usage. " | |
| "Annual billing is cheaper than monthly. Checkout may be switched off while billing is being finished, " | |
| "in which case every workspace gets Studio limits.", | |
| "Refunds and billing problems are handled by the team: use the Talk to a human button in this chat.", | |
| ] | |
| body = "\n".join(lines) | |
| return Doc( | |
| id="plans-and-billing", title="Plans, pricing and billing", route="/pricing", | |
| keywords=("price", "pricing", "plan", "plans", "free", "writer", "studio", "cost", "billing", "upgrade", | |
| "limits", "annual", "monthly", "subscription", "refund", "cancel", "usage", "reports", "infographics"), | |
| questions=("How much does Notestack cost?", "What is in the free plan?", "What are the plan limits?", | |
| "How do I upgrade?", "Is there annual billing?"), | |
| related_paths=("/app/settings",), headings=tuple(re.findall(r"^#{1,3}\s+(.+)$", body, re.M)), body=body, | |
| ) | |
| _docs: list[Doc] | None = None | |
| def get_corpus() -> list[Doc]: | |
| global _docs | |
| if _docs is None: | |
| _docs = [_parse(p) for p in sorted(DOCS_DIR.glob("*.md"))] + [_plans_doc()] | |
| log.info("support corpus: %d docs", len(_docs)) | |
| return _docs | |