From 861b11297be97bc4cecf08e4c03b47c738d4889e Mon Sep 17 00:00:00 2001 From: Md Hishaam Akhtar Date: Sat, 24 Oct 2026 20:54:30 +0530 Subject: [PATCH] Share routes, show both frontiers, explain each step, harden the API Sharing: /?from=&to= opens or runs a route and carries per-route Open Graph tags; /api/og.png draws the route with Pillow and the bundled JetBrains Mono. Found routes are kept 30 days under route:{start}:{end}. Search input: title suggestions (/api/suggest, resolved redirects, disambiguation flagged), example routes and "Surprise me". Visible algorithm: progress carries per-side counts and the pages each frontier read last; the wait scene draws both sides growing toward each other. Results name the meeting page and per-side totals. Link context: /api/context quotes the sentence in each article that links to the next step, parsed from wikitext (app/wikitext.py). Robustness: progress streams over SSE (/tasks/stream/) with polling as the fallback, so Gunicorn runs gthread workers. Per-IP rate limits in Redis, ProxyFix for the real client IP, hub link lists cached a week. Deploy: the Dockerfile copies entrypoint.sh once (executable in git) and pins uv; railway.toml no longer repeats the start command. Quality: CI (format, lint, types, script syntax, tests at 95% coverage, Docker build), pre-commit hooks, README architecture and measured benchmark. Also an adaptive SVG favicon, touch icons, manifest, a real 404 page, root robots.txt/favicon.ico (previously redirected to /), and nosniff/referrer headers. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/ci.yml | 48 +++ .pre-commit-config.yaml | 21 + DESIGN.md | 17 +- Dockerfile | 12 +- PRODUCT.md | 4 +- README.md | 83 +++- app/__init__.py | 11 +- app/config.py | 26 ++ app/errors.py | 19 + app/fonts/JetBrainsMono-Regular.ttf | Bin 0 -> 273900 bytes app/fonts/JetBrainsMono-SemiBold.ttf | Bin 0 -> 277092 bytes app/fonts/OFL.txt | 93 ++++ app/pathfinding.py | 41 +- app/routes.py | 242 ++++++++++- app/share.py | 266 ++++++++++++ app/store.py | 7 + app/tasks.py | 55 ++- app/wikipedia.py | 103 ++++- app/wikitext.py | 182 ++++++++ entrypoint.sh | 16 +- pyproject.toml | 1 + railway.toml | 2 +- static/404.html | 56 +++ static/apple-touch-icon.png | Bin 0 -> 6600 bytes static/favicon-dark.svg | 39 -- static/favicon-light.svg | 39 -- static/favicon.ico | Bin 0 -> 4723 bytes static/favicon.svg | 50 +-- static/icon-192.png | Bin 0 -> 5659 bytes static/icon-512.png | Bin 0 -> 15044 bytes static/index.html | 101 +++-- static/robots.txt | 6 +- static/script.js | 618 +++++++++++++++++++++++++-- static/site.webmanifest | 13 + static/styles.css | 342 ++++++++++++++- tests/conftest.py | 22 +- tests/test_api.py | 211 ++++++++- tests/test_pathfinding.py | 39 ++ tests/test_tasks.py | 32 ++ tests/test_wikipedia.py | 114 +++++ tests/test_wikitext.py | 92 ++++ uv.lock | 64 +++ 42 files changed, 2839 insertions(+), 248 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .pre-commit-config.yaml create mode 100644 app/fonts/JetBrainsMono-Regular.ttf create mode 100644 app/fonts/JetBrainsMono-SemiBold.ttf create mode 100644 app/fonts/OFL.txt create mode 100644 app/share.py create mode 100644 app/wikitext.py mode change 100644 => 100755 entrypoint.sh create mode 100644 static/404.html create mode 100644 static/apple-touch-icon.png delete mode 100644 static/favicon-dark.svg delete mode 100644 static/favicon-light.svg create mode 100644 static/favicon.ico create mode 100644 static/icon-192.png create mode 100644 static/icon-512.png create mode 100644 static/site.webmanifest create mode 100644 tests/test_wikitext.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..8465c25 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,48 @@ +name: CI + +on: + push: + branches: [master] + pull_request: + +permissions: + contents: read + +jobs: + check: + name: Lint, types, tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: astral-sh/setup-uv@v6 + with: + # Same uv as the Dockerfile, so CI resolves what production builds + version: "0.10.11" + enable-cache: true + + - name: Install + run: uv sync --locked --dev + + - name: Format + run: uv run ruff format --check . + + - name: Lint + run: uv run ruff check . + + - name: Type check + run: uv run ty check + + - name: Script syntax + run: node --check static/script.js + + - name: Tests + run: uv run pytest --cov=app --cov-report=term-missing --cov-fail-under=95 + + docker: + name: Docker image builds + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Build + run: docker build --tag iris:ci . diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..0949974 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,21 @@ +# Runs the same checks as CI, with the tool versions pinned in uv.lock. +# Install once with: uvx pre-commit install +repos: + - repo: local + hooks: + - id: ruff-format + name: ruff format + entry: uv run ruff format + language: system + types: [python] + - id: ruff-check + name: ruff check + entry: uv run ruff check --fix + language: system + types: [python] + - id: ty + name: ty check + entry: uv run ty check + language: system + types: [python] + pass_filenames: false diff --git a/DESIGN.md b/DESIGN.md index b9e5571..4dc268b 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -216,10 +216,10 @@ The page is flat. Depth is conveyed by tone (Raised Ground for chips) and by the ### Shadow Vocabulary - **Focus ring** (`box-shadow: 0 0 0 2px #0d1117, 0 0 0 4px #58a6ff`): every `:focus-visible`; inputs instead swap their underline to blue with a 1px blue under-shadow. - **Knock-out ring** (`box-shadow: 0 0 0 3px #0d1117`): step marks, so the rail appears to pass behind them. -- **Tooltip lift** (`box-shadow: 0 8px 24px rgba(1, 4, 9, 0.6)`): the graph tooltip only. +- **Tooltip lift** (`box-shadow: 0 8px 24px rgba(1, 4, 9, 0.6)`): the graph tooltip and the title suggestion list, the two surfaces that float over other content. ### Named Rules -**The Flat Ground Rule.** Nothing on the page casts a shadow except the pointer tooltip. Do not lift sections, buttons or chips. +**The Flat Ground Rule.** Nothing on the page casts a shadow except what floats above it: the pointer tooltip and the suggestion list. Do not lift sections, buttons or chips. ## Shapes @@ -242,6 +242,12 @@ Restrained and exact: one filled action, everything else outlined or bare. - **Hover:** underline lifts to Faint Ink. - **Error:** `aria-invalid="true"` turns the underline To Red with the same 1px under-shadow. +### Suggestions +A listbox hung from the bottom of a route field while typing (ARIA combobox; the input keeps focus). Raised Ground with a 1px Strong Hairline border, no top border so it reads as the field's continuation, square corners and the tooltip lift. Each option is a 44px row ruled by a Hairline: the title at Body 500, the Wikipedia short description below in Label Faint Ink. The active option takes Sunken Fill and a Path Blue title. A disambiguation page in the To field is muted and says to pick a specific article. + +### Examples +Under the route actions, one Small line: "Try" in Faint Ink, three example routes as Path Blue in-text actions (shuffled per visit), and "Surprise me" in Muted Ink. Each is a 44px target. + ### Notice The error and "stopped" message, ruled not boxed. A three-column row: 20px stroked icon in the tone colour, body, actions. A tone rule on top (the tone at 55% via `color-mix`), a Hairline below, 16px vertical padding, no fill, no radius. The title names the problem (To Red Ink, 600), the message adds a new fact (Ink, Small), the hint gives recovery (Muted Ink, Small); empty lines collapse. The neutral variant swaps the tone to Faint Ink and the title to Ink. It enters with a 4px drop-in over 0.35s. @@ -252,13 +258,18 @@ The masthead is a 64px bar ruled below: the wordmark (24px logo plus "Iris" at T The signature of the instrument: a row of figures separated by vertical Hairlines, no boxes. Four equal columns plus a double-width "Reading" column holding the page currently being read as a Path Blue link (Faint Ink and inert when empty). Labels are 12px Faint Ink; values are Reading type. Depth is shown as a row of 8px circles: hollow (Strong Hairline), active (blue outline, beating), completed (blue fill). Above the readings a 1px activity track carries a blue sweep while searching. ### The Field (graph plot) -A dot field (1px dots at 16% grey on a 20px grid) framed by corner registration marks, 360px minimum height (300px on phones). While searching it shows only the two ends as label chips joined by a dashed 1px line with a travelling blue highlight; when the path arrives the D3 graph replaces it. Nodes are blue with a 2px ground stroke; the start and end nodes take their signal colour with a translucent 5px halo of the same hue. Path edges are 2.5px Path Blue with a single SVG arrowhead; other edges are 2px Strong Hairline at 60%. Label chips are Raised Ground with a 1px Strong Hairline border and 4px corners. +A dot field (1px dots at 16% grey on a 20px grid) framed by corner registration marks, 360px minimum height (300px on phones). While searching it shows the two frontiers: each end as a label chip, under it the pages that side read last (Label size, newest first in Ink, older ones fading to 26%), and a count ("214 pages · 2 links out") in Faint Ink. Between them a dashed 1px line carries a travelling blue highlight, and each side fills the line with solid Path Blue from its own end as it goes deeper, scaled to the whole depth budget so the two fills meet mid-line. Under 640px the scene stacks: start on top, end at the bottom reading upward, three pages per side. When the path arrives the D3 graph replaces it. Nodes are blue with a 2px ground stroke; the start and end nodes take their signal colour with a translucent 5px halo of the same hue. Path edges are 2.5px Path Blue with a single SVG arrowhead; other edges are 2px Strong Hairline at 60%. Label chips are Raised Ground with a 1px Strong Hairline border and 4px corners. The force simulation is tuned and fixed: link distance spans the available axis with strength 1; charge -240 (horizontal) or -160 (vertical); x/y position forces 0.22/0.10 (horizontal) or 0.16/0.22 (vertical); collision strength 0.8; alphaDecay 0.03; velocityDecay 0.45. These values are part of the system, not tuning knobs. ### Route List The found route as a ruled ordered list: each step is a 52px row ruled on top, with a 9px mark, a 36px index column, the title and a stroked open-arrow. A 1px blue rail at 45% opacity threads the marks, starting at the first mark and ending at the last; first mark green, last red, the rest blue. Hover turns the title Path Blue and nudges the arrow 2px up-right. +Above the list, the "Route" title shares its row with a "Copy link" text button (the system share sheet on touch devices). Under the summary, one Small Muted sentence explains the search: pages read on each side and where the frontiers met; that step carries a Faint "Frontiers met" tag. Under every step but the last hangs the sentence from that article which links to the next, as a quotation in Small Muted Ink aligned with the titles, the linked words in Path Blue and the section name in Faint Ink. A link found only in an infobox or navigation box says so in Faint Ink instead. + +### 404 +The same shell, masthead and colophon. The lead carries "404" at Reading size in To Red Ink, the display line "No page here.", one line of copy and the primary button back to the search. + ## Do's and Don'ts ### Do: diff --git a/Dockerfile b/Dockerfile index a521873..b61d255 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ FROM python:3.13-slim -# Install uv -COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ +# Pinned so a uv release can never change a build that the repo did not +COPY --from=ghcr.io/astral-sh/uv:0.10.11 /uv /uvx /bin/ WORKDIR /app @@ -9,15 +9,11 @@ WORKDIR /app COPY pyproject.toml uv.lock ./ RUN uv sync --frozen --no-dev -# Copy application code +# Copy application code (entrypoint.sh is executable in git) COPY . . -# Copy and set up entrypoint -COPY entrypoint.sh /entrypoint.sh -RUN chmod +x /entrypoint.sh - # Make the venv's binaries available (gunicorn, celery, etc.) ENV PATH="/app/.venv/bin:$PATH" # SERVICE_TYPE=worker runs celery, anything else runs gunicorn -CMD ["/entrypoint.sh"] +CMD ["/app/entrypoint.sh"] diff --git a/PRODUCT.md b/PRODUCT.md index 53d1cee..5ff3655 100644 --- a/PRODUCT.md +++ b/PRODUCT.md @@ -24,7 +24,7 @@ The implementation is itself part of the point. The project stands as a demonstr ## Operating Context -- Single page, no accounts, no persistence beyond the browser. A visitor types two titles and presses one button. +- Single page, no accounts. A visitor types two titles (with suggestions) or picks an example, and presses one button. A found route is kept for thirty days so a shared link can show it. - Searches run as background Celery tasks and are polled by the UI; a search survives a page refresh because the latest one is kept in `localStorage`. - Deployed publicly at `iris.hishaam.dev` (Railway, Docker; `entrypoint.sh` switches role on `SERVICE_TYPE`). It is live but not actively promoted, so traffic is incidental and stakes are low — strangers can still arrive cold with no context. - A run takes seconds to a couple of minutes. Waiting is a normal part of the experience, not an error state. @@ -46,7 +46,7 @@ The implementation is itself part of the point. The project stands as a demonstr ## Brand Commitments - Name: **Iris**; full title "Iris: Wikipedia Path Finder". -- Existing identity assets, all in `static/`: `logo.svg`, `favicon-dark.svg` / `favicon-light.svg` (switched on `prefers-color-scheme`), `og-image.svg` / `og-image.png`. +- Existing identity assets, all in `static/`: `logo.svg`, `favicon.svg` (its lines follow `prefers-color-scheme` from inside the SVG), `favicon.ico`, `apple-touch-icon.png`, `icon-192.png` / `icon-512.png` (web manifest), `og-image.svg` / `og-image.png`. - The GitHub-dark palette and JetBrains Mono are binding: the README and OG image are built on them, so a change to the theme is a change to published assets. - GPL-3.0 licensed (see `LICENSE`), open source at `github.com/mdhishaamakhtar/iris`. - Built by Md Hishaam Akhtar and Sharanya Mukherjee under DSC VIT; the README carries that attribution. diff --git a/README.md b/README.md index 4597527..a88d67b 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ ## Iris Wikipedia Pathfinder +[![CI](https://github.com/mdhishaamakhtar/iris/actions/workflows/ci.yml/badge.svg)](https://github.com/mdhishaamakhtar/iris/actions/workflows/ci.yml) + Iris finds a path between any two Wikipedia pages by traversing their links. You give it two page titles — say, "Banana" and "Shah Rukh Khan" — and it walks Wikipedia's link graph using BFS until it finds the connection. Results are visualized as an interactive graph you can drag around. @@ -21,9 +23,77 @@ It uses **bidirectional BFS** (default) which searches simultaneously from both ## What It Does - Find Wikipedia paths via **bidirectional BFS** (default) or standard forward-only BFS -- Async task processing — searches run in the background, results polled live -- Real-time progress updates during search (aggregated from both search frontiers) -- Interactive D3.js graph visualization of the path +- **Watch both frontiers grow** — each side shows the pages it is reading and how deep it has gone, streamed over Server-Sent Events +- **Every step explained** — the route quotes the sentence in each article that links to the next one +- **Shareable routes** — `/?from=Banana&to=Shah%20Rukh%20Khan` opens (or runs) that search, and unfurls in Slack, Discord or a social feed as an image of the route +- **Title suggestions** as you type, with disambiguation pages flagged before they fail +- Interactive D3.js graph of the path, and a ruled route list + +## How It Works + +```mermaid +flowchart LR + B[Browser] -- "POST /getPath" --> W[Flask / Gunicorn] + W -- "queue task" --> R[(Redis)] + R -- "task" --> C[Celery worker] + C -- "links + backlinks" --> WP[Wikipedia API] + C -- "frontiers, progress, caches" --> R + W -- "GET /tasks/stream/id (SSE)" --> B + R -- "task state" --> W +``` + +The web process never searches. It queues a Celery task and streams the task's +state back to the browser. The worker runs one breadth-first search over one +or two *frontiers*: forward from the start page through its links, and backward +from the end page through its backlinks, always expanding whichever side is +smaller. When a page turns up in both, the path is read back out of the parent +pointers. Every piece of search state — queues, visited sets, parent pointers — +lives in Redis, namespaced per search and deleted when it ends. + +Link lists are cached in Redis. Hub articles (500+ links: countries, years, +broad topics) are cached for a week rather than a day, because nearly every +search passes through them. + +The route found is the first one, not a proven shortest: Wikipedia caps how +many links one request returns, and Iris follows at most three continuations +per article. + +## Performance + +Search time is Wikipedia's request latency times the number of requests in +flight, not computation. Measured with `scripts/benchmark.py` on 24 October +2026: bidirectional search, production settings, a cold cache, one run each, +from a developer laptop. + +| Route | Time | Wikipedia requests | Pages explored | Path | +| --- | ---: | ---: | ---: | --- | +| Pizza → Byzantine Empire | 0.97 s | 2 | 1 | 2 pages | +| Mount Everest → Jazz | 2.79 s | 6 | 2 | 3 pages | +| Kangaroo → Fourier transform | 5.44 s | 33 | 22 | 4 pages | +| Pikachu → Quantum chromodynamics | 5.93 s | 37 | 22 | 4 pages | +| Taylor Swift → Photosynthesis | 7.37 s | 40 | 22 | 4 pages | +| Barack Obama → Mathematics | 8.70 s | 54 | 22 | 4 pages | + +A repeated search is answered from the path cache in milliseconds. Run +`uv run python scripts/benchmark.py` (needs local Redis and network) to +measure your own; `--compare` prints before/after. + +## API + +| Method | Path | Purpose | +| --- | --- | --- | +| `POST` | `/getPath` | Start a search: `{start, end, algorithm?}` → `202` with `task_id` | +| `GET` | `/tasks/stream/` | Progress and result as Server-Sent Events | +| `GET` | `/tasks/status/` | The same status body, polled | +| `DELETE` | `/tasks/` | Stop a search | +| `GET` | `/api/suggest?q=` | Title suggestions | +| `GET` | `/api/context?from=&to=` | The sentence in one article that links to the next | +| `GET` | `/api/og.png?from=&to=` | Share image for a route | +| `GET` | `/health` | Redis connectivity | + +Full schemas are in Swagger at `/api/docs`. The API is public and +unauthenticated, so it is rate-limited per client: 10 searches a minute, 120 +requests a minute to the lighter endpoints (`429` with `Retry-After` beyond). ## Tech Stack @@ -58,7 +128,7 @@ Swagger docs at [http://localhost:9020/api/docs](http://localhost:9020/api/docs) | Script | When to use | |--------|-------------| | `dev.sh` | Local development — starts Redis (if needed), Flask, and Celery in one terminal | -| `entrypoint.sh` | Docker/Railway container entry — switches on `SERVICE_TYPE` env var | +| `entrypoint.sh` | The Docker image's `CMD` — runs Gunicorn, or Celery when `SERVICE_TYPE=worker` | ## Dev @@ -69,8 +139,13 @@ uv run pytest --cov=app --cov-report=html # generate HTML coverage re uv run ruff format . # format uv run ruff check . # lint uv run ty check # type check +uvx pre-commit install # run format, lint and types on every commit ``` +CI runs the same checks on every push and pull request, requires 95% test +coverage, and builds the Docker image. Tests run against `fakeredis` with only +Wikipedia stubbed, so the search, the Redis store and the HTTP API run for real. + ## Contributors - **Md Hishaam Akhtar** — [GitHub](https://github.com/mdhishaamakhtar) · [LinkedIn](https://www.linkedin.com/in/md-hishaam-akhtar-812a3019a/) diff --git a/app/__init__.py b/app/__init__.py index 05ef26c..2628c97 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -18,6 +18,7 @@ from flask import Flask, Response, current_app, g, jsonify, request from marshmallow import ValidationError from werkzeug.exceptions import HTTPException +from werkzeug.middleware.proxy_fix import ProxyFix from app.config import Settings from app.errors import ErrorCode, IrisError @@ -77,6 +78,10 @@ def create_app(settings: Settings | None = None) -> Flask: settings = settings or Settings.from_env() app = Flask(__name__, static_folder="../static", static_url_path="/static") + # Railway terminates TLS in front of Gunicorn. Trusting one proxy hop is + # what makes request.remote_addr the client (for rate limits) and + # request.url_root https (for absolute share-preview URLs). + app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1) # type: ignore[method-assign] app.config.update( SECRET_KEY=settings.secret_key, DEBUG=settings.debug, @@ -119,6 +124,8 @@ def finish_request(response: Response) -> Response: response.headers["Access-Control-Allow-Origin"] = "*" response.headers["Access-Control-Allow-Methods"] = "GET, POST, DELETE, OPTIONS" response.headers["Access-Control-Allow-Headers"] = "Content-Type" + response.headers["X-Content-Type-Options"] = "nosniff" + response.headers["Referrer-Policy"] = "strict-origin-when-cross-origin" if request.path.startswith(("/static/", "/flasgger_static/")): return response logger.info("request_completed", extra={"http_status": response.status_code}) @@ -150,7 +157,9 @@ def on_iris_error(exc: IrisError): logger.warning( "application_error", extra={"code": exc.code, "error": exc.message} ) - return problem(exc.message, exc.code, exc.status) + response, status = problem(exc.message, exc.code, exc.status) + response.headers.update(exc.headers) + return response, status @app.errorhandler(HTTPException) def on_http_error(exc: HTTPException): diff --git a/app/config.py b/app/config.py index 01f979c..53980af 100644 --- a/app/config.py +++ b/app/config.py @@ -69,10 +69,36 @@ class Settings: # Cache lifetimes, in seconds links_cache_ttl: int = 86_400 + hub_cache_ttl: int = 604_800 + """Link lists that reach ``hub_link_threshold`` belong to hub articles + (countries, years, broad topics). Nearly every search passes through them + and their link sets barely move, so they are kept a week, not a day.""" + hub_link_threshold: int = 500 path_cache_ttl: int = 3_600 page_cache_ttl: int = 7_200 search_state_ttl: int = 3_600 """Safety net so per-search Redis keys expire even if cleanup is skipped.""" + share_ttl: int = 2_592_000 + """How long a found route stays available to shared links and their + preview images: thirty days, long after the path cache has let it go.""" + context_cache_ttl: int = 604_800 + suggest_cache_ttl: int = 86_400 + + # Rate limits, per client IP per window + search_rate_limit: int = 10 + """Searches started per window. Each one fans out to hundreds of + Wikipedia requests, so this is what keeps one script from getting the + whole service throttled.""" + api_rate_limit: int = 120 + """Requests per window to the lighter endpoints (suggestions, link + context, progress streams, share images).""" + rate_window: int = 60 + + # Progress streaming + stream_interval: float = 0.5 + stream_max_seconds: int = 120 + """A stream closes after this long and the browser reconnects, so a + stream for a task that never starts cannot hold a thread forever.""" # Pathfinding max_search_depth: int = 6 diff --git a/app/errors.py b/app/errors.py index c4c9f08..82dbd81 100644 --- a/app/errors.py +++ b/app/errors.py @@ -19,6 +19,7 @@ class ErrorCode(StrEnum): PAGE_NOT_FOUND = "PAGE_NOT_FOUND" DISAMBIGUATION_PAGE = "DISAMBIGUATION_PAGE" PATH_NOT_FOUND = "PATH_NOT_FOUND" + RATE_LIMITED = "RATE_LIMITED" WIKIPEDIA_API_ERROR = "WIKIPEDIA_API_ERROR" CONFIGURATION_ERROR = "CONFIGURATION_ERROR" INTERNAL_ERROR = "INTERNAL_ERROR" @@ -36,6 +37,11 @@ def __init__(self, message: str, code: ErrorCode | None = None) -> None: if code is not None: self.code = code + @property + def headers(self) -> dict[str, str]: + """Extra response headers the error needs, such as ``Retry-After``.""" + return {} + class InvalidRequestError(IrisError): code = ErrorCode.INVALID_REQUEST @@ -52,6 +58,19 @@ class ConflictError(IrisError): status = 409 +class RateLimitedError(IrisError): + code = ErrorCode.RATE_LIMITED + status = 429 + + def __init__(self, retry_after: int) -> None: + super().__init__(f"Too many requests. Try again in {retry_after} seconds.") + self.retry_after = retry_after + + @property + def headers(self) -> dict[str, str]: + return {"Retry-After": str(self.retry_after)} + + class PageNotFoundError(IrisError): code = ErrorCode.PAGE_NOT_FOUND status = 404 diff --git a/app/fonts/JetBrainsMono-Regular.ttf b/app/fonts/JetBrainsMono-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..dff66cc50702c75abd025dcf49f62a4dcc2d72de GIT binary patch literal 273900 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 z

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≦fXo=WUuIA1w6wc ze~u{Wb9+aAvsl~X_C7Z%y?9g7;~Om*Y2NJVomZXf_|uD${+1m5eV$(Co5AnzN_)iO zk$!cK{^^8XB#Pf|ReI_g>7U8bAN2I%hmHA_(u)Ts{h=KF;e=lO6#e&@)F53$FBT-#1w4#e0(;y$~(rx=ejI`&Up%eY&ep_joO?K6-ez zZ;d?Mke@c%aGy@gbI z$L}*w?_iv6ru7>UdX)z)CFBucK4MkIU7z>Mf*0FI{6)F)w4$V?KO%liwtvCJ4iDcg z_;DVu;}uA3opm|*k{o|O|GA?ff6V`+eY%R!`k5wvrmK&BobZjlK387X$m+d`=PH@I z1;!toyoHn8@fYEq2fJvuUK2j-C3r;2RiWTX`D8x+2T$P{G9~{PKo*R{csXgi_yk`1;L;*n zu4#}j9#7NcqBqxpaA`dSl2aGmRf-4W=y;mTgpbg>zPP&F$jOQ>C&$L>91@1kp|t3N z?%3F$zRbhesr_e;#?JhVV~%+OK(AA~5aQvF4JLDA#UKi02W>~F;z{`Rx8t1_?57GGZHnfb25qGv4sLJr1xj<;J* zqciQp$t?S)+RpMgw@K(#%d_;qaP;19yxs5vskO00GBWE{AL;y5%O`g0SgJmL6Tsx` z@K9HueoMdv!y5FQL1)mnE4|<-U#ym#UG;WW`YSra{^E>6@syzG5%C3u1Wx3UnrAxa z$RF!G(Ca)SKR=%2V$2)T8gFTS=EhQSe^Q+4g*ojYT|MH4inCsg9fIx`{H#%kbBo-R z+L&t;a=P?sl?V5yls5UPU&L5=U7$ROk=Al7vpB+94p9T9WKJlZ zuSe#nXszbEdW1f|PiRlHz^~sij&6Q4rbXG}om=?y^OQMN#611nq^(VBlh?nGJ)cAa zk18M9O=+DmpCtYEwgMzlm+BDf!cNA?MkAMA0v-Ylb}7=wWKS?7)jl1Ol>aizg<7@I zm=zga`JTh64cO+!&i9eE`2NA3s|9!3tkNf?$lr}iddz)nk8vr#H)VPs>Xh~)O|8=! zc&mYFMh0El*?-B`(|Dy34fgc3Zl0bidhI`aTQXwmS+dq int: @@ -87,9 +99,10 @@ class _Counters: lock: threading.Lock = field(default_factory=threading.Lock) nodes_explored: int = 0 depth_by_side: dict[str, int] = field(default_factory=dict) + explored_by_side: dict[str, int] = field(default_factory=dict) - def record(self, side: str, depth: int) -> tuple[int, int]: - """Count one fetched page; return (total explored, combined depth). + def record(self, side: str, depth: int) -> tuple[int, int, SideStats]: + """Count one fetched page; return (total explored, combined depth, sides). Combined depth sums both sides because a bidirectional search meeting at forward depth 2 and backward depth 2 has covered four hops of path. @@ -97,7 +110,19 @@ def record(self, side: str, depth: int) -> tuple[int, int]: with self.lock: self.nodes_explored += 1 self.depth_by_side[side] = max(self.depth_by_side.get(side, 0), depth) - return self.nodes_explored, sum(self.depth_by_side.values()) + self.explored_by_side[side] = self.explored_by_side.get(side, 0) + 1 + return ( + self.nodes_explored, + sum(self.depth_by_side.values()), + self.sides(), + ) + + def sides(self) -> SideStats: + # Expanding a page at depth d reaches pages d + 1 links out. + return { + side: {"explored": explored, "depth": self.depth_by_side[side] + 1} + for side, explored in self.explored_by_side.items() + } class PathFinder: @@ -127,7 +152,9 @@ def find( if not start or not end: raise InvalidRequestError("Start and end pages are required") if start == end: - return PathResult(path=[start], nodes_explored=1, search_time=0.0) + return PathResult( + path=[start], nodes_explored=1, search_time=0.0, meeting=start + ) started = time.monotonic() counters = _Counters() @@ -154,6 +181,8 @@ def find( path=path, nodes_explored=counters.nodes_explored, search_time=time.monotonic() - started, + meeting=meeting, + sides=counters.sides(), ) finally: self.store.delete(*all_keys) @@ -327,7 +356,7 @@ def _page_reporter( ) def page_fetched(title: str, _titles: list[str]) -> None: - explored, combined_depth = counters.record(side.name, depth) + explored, combined_depth, sides = counters.record(side.name, depth) if report is None: return report( @@ -337,6 +366,8 @@ def page_fetched(title: str, _titles: list[str]) -> None: current_depth=combined_depth, last_node=title, elapsed=round(time.monotonic() - started, 2), + side=side.name, + sides=sides, ) ) diff --git a/app/routes.py b/app/routes.py index 217cca1..b2cd8a2 100644 --- a/app/routes.py +++ b/app/routes.py @@ -7,8 +7,13 @@ from __future__ import annotations +import json import logging +import time import uuid +from collections.abc import Iterator +from dataclasses import asdict +from pathlib import Path from typing import Any from celery import states @@ -17,21 +22,32 @@ Response, current_app, jsonify, - redirect, request, url_for, ) from marshmallow import Schema, ValidationError, fields, validate, validates_schema from app import celery, services -from app.errors import ConflictError, ErrorCode, NotFoundError +from app.errors import ( + ConflictError, + ErrorCode, + InvalidRequestError, + NotFoundError, + RateLimitedError, +) from app.pathfinding import ALGORITHMS, BIDIRECTIONAL -from app.tasks import PROGRESS, find_path_task +from app.share import describe, render_card, with_share_meta +from app.tasks import PROGRESS, find_path_task, route_key logger = logging.getLogger(__name__) api = Blueprint("api", __name__) +MAX_TITLE = 255 +TERMINAL = (states.SUCCESS, states.FAILURE, states.REVOKED) +KEEPALIVE_SECONDS = 15 +"""An idle stream sends a comment this often, so proxies do not close it.""" + class SearchSchema(Schema): """Validates POST /getPath.""" @@ -83,7 +99,10 @@ def start_search() -> tuple[Response, int]: description: Search accepted; poll poll_url for progress and the result 400: description: Validation error + 429: + description: Too many searches from this address; see Retry-After """ + _rate_limit("search", services().settings.search_rate_limit) data = SearchSchema().load(request.get_json(silent=True) or {}) start, end = data["start"].strip(), data["end"].strip() @@ -122,8 +141,66 @@ def search_status(task_id: str) -> Response: description: Malformed task ID """ _require_task_id(task_id) + return jsonify(_status(task_id)) + + +@api.get("/tasks/stream/") +def stream_status(task_id: str) -> Response: + """Stream a search's progress as Server-Sent Events. + --- + tags: [Pathfinding] + summary: Stream task status + description: > + Each event's data is the same JSON body GET /tasks/status/{task_id} + returns, sent whenever it changes. The stream ends after a terminal + status (SUCCESS, FAILURE or REVOKED), or after a couple of minutes, when + an EventSource reconnects by itself. + produces: [text/event-stream] + parameters: + - name: task_id + in: path + required: true + type: string + responses: + 200: + description: An event stream of status bodies + 404: + description: Malformed task ID + 429: + description: Too many requests from this address + """ + _require_task_id(task_id) + _rate_limit("api", services().settings.api_rate_limit) + settings = services().settings + + def events() -> Iterator[str]: + yield f"retry: {int(settings.stream_interval * 2000)}\n\n" + last: dict[str, Any] | None = None + quiet = 0.0 + deadline = time.monotonic() + settings.stream_max_seconds + while True: + body = _status(task_id) + if body != last: + yield f"data: {json.dumps(body)}\n\n" + last, quiet = body, 0.0 + elif quiet >= KEEPALIVE_SECONDS: + yield ": keep-alive\n\n" + quiet = 0.0 + if body["status"] in TERMINAL or time.monotonic() >= deadline: + return + time.sleep(settings.stream_interval) + quiet += settings.stream_interval + + return Response( + events(), + mimetype="text/event-stream", + headers={"Cache-Control": "no-cache", "X-Accel-Buffering": "no"}, + ) + + +def _status(task_id: str) -> dict[str, Any]: task = find_path_task.AsyncResult(task_id) - body: dict[str, object] = {"task_id": task_id} + body: dict[str, Any] = {"task_id": task_id} if task.state == states.PENDING: body |= {"status": states.PENDING, "message": "Task is waiting to be processed"} @@ -135,8 +212,7 @@ def search_status(task_id: str) -> Response: body |= {"status": states.FAILURE, "error": str(task.info)} else: body |= {"status": task.state} - - return jsonify(body) + return body def _result(payload: dict[str, Any]) -> dict[str, Any]: @@ -223,6 +299,109 @@ def health() -> tuple[Response, int]: ) +# --- Search helpers ------------------------------------------------------- + + +@api.get("/api/suggest") +def suggest() -> Response: + """Suggest article titles for what has been typed so far. + --- + tags: [Pathfinding] + summary: Title suggestions + parameters: + - name: q + in: query + required: true + type: string + description: The start of a title + responses: + 200: + description: > + Up to eight articles, best match first. Redirects are resolved; + disambiguation pages are flagged, since they cannot be an end page. + 429: + description: Too many requests from this address + """ + _rate_limit("api", services().settings.api_rate_limit) + query = request.args.get("q", "").strip()[:MAX_TITLE] + titles = services().wikipedia.suggest(query) if query else [] + return jsonify({"query": query, "titles": [asdict(item) for item in titles]}) + + +@api.get("/api/context") +def link_context() -> Response: + """The sentence in one article that links to the next. + --- + tags: [Pathfinding] + summary: Link context for one step of a path + parameters: + - name: from + in: query + required: true + type: string + description: The article that contains the link + - name: to + in: query + required: true + type: string + description: The article it links to + responses: + 200: + description: > + "where" is "prose" when the link sits in running text, and then + before + link + after is the sentence with link as the linked words. + "template" means the link is in an infobox, table or template; + "elsewhere" means it is not in the article's own text at all + (usually a navigation box). + 400: + description: Missing from or to + 429: + description: Too many requests from this address + """ + _rate_limit("api", services().settings.api_rate_limit) + source, target = _route_args() + context = services().wikipedia.link_context(source, target) + return jsonify({"from": source, "to": target, **asdict(context)}) + + +# --- Sharing -------------------------------------------------------------- + + +@api.get("/api/og.png") +def share_image() -> Response: + """The preview image a shared route link unfurls into. + --- + tags: [Pathfinding] + summary: Share image for a route + produces: [image/png] + parameters: + - name: from + in: query + required: true + type: string + - name: to + in: query + required: true + type: string + responses: + 200: + description: > + A 1200x630 PNG of the route if it has been found recently, or of the + question if not. + 400: + description: Missing from or to + """ + _rate_limit("api", services().settings.api_rate_limit) + start, end = _route_args() + path = services().store.get(route_key(start, end)) + return Response( + render_card(start, end, path), + mimetype="image/png", + # Short when the route is unknown: it may be found a minute from now. + headers={"Cache-Control": f"public, max-age={86_400 if path else 300}"}, + ) + + # --- UI ------------------------------------------------------------------- API_PREFIXES = ("getPath", "tasks", "health", "api", "apispec") @@ -230,16 +409,36 @@ def health() -> tuple[Response, int]: @api.get("/") def index() -> Response: - """Serve the visualisation UI.""" - return current_app.send_static_file("index.html") + """Serve the UI; a shared route link gets that route's preview tags.""" + start = request.args.get("from", "").strip()[:MAX_TITLE] + end = request.args.get("to", "").strip()[:MAX_TITLE] + if not (start and end): + return current_app.send_static_file("index.html") + + path = services().store.get(route_key(start, end)) + route: dict[str, Any] = {"from": start, "to": end} + page = with_share_meta( + Path(current_app.static_folder or "", "index.html").read_text("utf-8"), + describe(start, end, path), + url=request.url, + image=url_for("api.share_image", _external=True, **route), + ) + return Response(page, mimetype="text/html") + + +@api.get("/favicon.ico") +@api.get("/robots.txt") +def root_file() -> Response: + """Files browsers and crawlers ask for at the root, not under /static.""" + return current_app.send_static_file(request.path.lstrip("/")) @api.get("/") -def catch_all(path: str) -> Response: - """Send unknown API paths to a 404 and everything else to the UI.""" +def catch_all(path: str) -> tuple[Response, int]: + """Answer unknown API paths with JSON and everything else with a page.""" if path.startswith(API_PREFIXES): raise NotFoundError("Endpoint not found") - return redirect(url_for("api.index")) # type: ignore[return-value] + return current_app.send_static_file("404.html"), 404 # --- Helpers -------------------------------------------------------------- @@ -254,5 +453,26 @@ def _require_task_id(task_id: str) -> None: ) from exc +def _route_args() -> tuple[str, str]: + source = request.args.get("from", "").strip()[:MAX_TITLE] + target = request.args.get("to", "").strip()[:MAX_TITLE] + if not (source and target): + raise InvalidRequestError("Both 'from' and 'to' are required") + return source, target + + +def _rate_limit(bucket: str, limit: int) -> None: + """Allow ``limit`` requests per client per window, counted in Redis. + + Fixed windows, keyed by the window's number, so every key expires on its + own and nothing needs sweeping. + """ + window = services().settings.rate_window + now = int(time.time()) + key = f"ratelimit:{bucket}:{request.remote_addr}:{now // window}" + if services().store.increment(key, ttl=window) > limit: + raise RateLimitedError(retry_after=window - now % window) + + def _wants_terminate() -> bool: return request.args.get("terminate", "true").lower() != "false" diff --git a/app/share.py b/app/share.py new file mode 100644 index 0000000..aff90fd --- /dev/null +++ b/app/share.py @@ -0,0 +1,266 @@ +"""Share previews: the image and the words a link unfurls into. + +A shared link (``/?from=A&to=B``) unfurls in Slack, Discord or a social feed +as a card showing that route. Crawlers do not run JavaScript, so both the +```` tags and the image are produced here, from the route kept in Redis +under ``route:{start}:{end}`` when the search finished. A link to a route that +was never searched (or has expired) still gets a card: it asks the question +instead of answering it. + +The card follows the published OG image: GitHub-dark ground, JetBrains Mono, +green start, red end, blue path, on a faint dot field. +""" + +from __future__ import annotations + +import html +import io +import re +from dataclasses import dataclass +from functools import cache +from pathlib import Path + +from PIL import Image, ImageDraw, ImageFont + +WIDTH, HEIGHT = 1200, 630 +SCALE = 2 +"""Drawn at twice the size and downsampled: Pillow does not antialias shapes.""" + +FONTS = Path(__file__).parent / "fonts" + +GROUND = "#0d1117" +RAISED = "#161b22" +RULE = "#21262d" +RULE_STRONG = "#30363d" +INK = "#f0f6fc" +INK_MUTED = "#9198a1" +INK_FAINT = "#7d8590" +BLUE = "#58a6ff" +GREEN = "#3fb950" +RED = "#f85149" +DOT = (139, 148, 158, 40) + +MAX_ROWS = 7 +SITE = "IRIS.HISHAAM.DEV" + + +@dataclass(frozen=True, slots=True) +class ShareMeta: + title: str + description: str + + +def describe(start: str, end: str, path: list[str] | None) -> ShareMeta: + if path: + hops = len(path) - 1 + links = f"{hops} link{'s' if hops != 1 else ''}" + return ShareMeta( + title=f"{start} → {end} in {links} · Iris", + description=f"{' → '.join(path)}. A route through Wikipedia, found live by Iris.", + ) + return ShareMeta( + title=f"{start} → {end} · Iris", + description=f"How does {start} lead to {end} on Wikipedia? Iris follows the links live and draws the route.", + ) + + +def with_share_meta(page: str, meta: ShareMeta, url: str, image: str) -> str: + """Point the page's title and Open Graph / Twitter tags at one route.""" + values = { + "og:title": meta.title, + "twitter:title": meta.title, + "og:description": meta.description, + "twitter:description": meta.description, + "description": meta.description, + "og:url": url, + "og:image": image, + "twitter:image": image, + } + for key, value in values.items(): + page = re.sub( + rf'([^<]*", + lambda _: f"{html.escape(meta.title)}", + page, + count=1, + ) + + +# --- The card ------------------------------------------------------------- + + +@cache +def _font(weight: str, size: int) -> ImageFont.FreeTypeFont: + return ImageFont.truetype(str(FONTS / f"JetBrainsMono-{weight}.ttf"), size * SCALE) + + +def render_card(start: str, end: str, path: list[str] | None) -> bytes: + image = Image.new("RGB", (WIDTH * SCALE, HEIGHT * SCALE), GROUND) + draw = ImageDraw.Draw(image, "RGBA") + + _dot_field(draw) + _masthead(draw) + if path: + _route(draw, path) + else: + _question(draw, start, end) + _footer(draw, "WIKIPEDIA PATH • FOUND LIVE" if path else "WIKIPEDIA PATH") + + image = image.resize((WIDTH, HEIGHT), Image.Resampling.LANCZOS) + buffer = io.BytesIO() + image.save(buffer, format="PNG", optimize=True) + return buffer.getvalue() + + +def _s(*values: float) -> list[float]: + """Scale card coordinates to the drawing surface.""" + return [v * SCALE for v in values] + + +def _xy(x: float, y: float) -> tuple[float, float]: + return x * SCALE, y * SCALE + + +def _dot_field(draw: ImageDraw.ImageDraw) -> None: + for x in range(20, WIDTH, 20): + for y in range(20, HEIGHT, 20): + draw.ellipse(_s(x - 0.75, y - 0.75, x + 0.75, y + 0.75), fill=DOT) + + +def _masthead(draw: ImageDraw.ImageDraw) -> None: + # The logo: start and end on top, the path node below, joined by lines. + a, b, c = (78, 52), (100, 52), (89, 72) + for p, q in ((a, b), (a, c), (b, c)): + draw.line(_s(*p, *q), fill=INK_MUTED, width=2 * SCALE) + for (x, y), colour in ((a, GREEN), (b, RED), (c, BLUE)): + draw.ellipse(_s(x - 5, y - 5, x + 5, y + 5), fill=colour) + _tracked(draw, (118, 50), "IRIS", _font("Regular", 18), INK_MUTED, 0.18) + + +def _footer(draw: ImageDraw.ImageDraw, left: str) -> None: + draw.line(_s(72, 548, WIDTH - 72, 548), fill=RULE, width=SCALE) + font = _font("Regular", 14) + _tracked(draw, (72, 566), left, font, INK_FAINT, 0.14) + width = _tracked_width(SITE, font, 0.14) + _tracked(draw, (WIDTH - 72 - width / SCALE, 566), SITE, font, BLUE, 0.14) + + +def _route(draw: ImageDraw.ImageDraw, path: list[str]) -> None: + rows = _rows(path) + top, bottom = 118, 520 + step = min(62, (bottom - top) / max(len(rows), 1)) + first_y = (top + bottom) / 2 - step * (len(rows) - 1) / 2 + last_y = first_y + step * (len(rows) - 1) + + # The rail, then a ruled row and a mark per step, as in the route list. + rail_x = 80 + draw.line( + _s(rail_x, first_y, rail_x, last_y), fill=(88, 166, 255, 115), width=SCALE + ) + title_font = _font("SemiBold", 26 if len(rows) <= 5 else 23) + index_font = _font("Regular", 16) + for i, (number, title) in enumerate(rows): + y = first_y + i * step + if i: + draw.line(_s(104, y - step / 2, 760, y - step / 2), fill=RULE, width=SCALE) + colour = GREEN if i == 0 else RED if i == len(rows) - 1 else BLUE + if number is None: + colour = RULE_STRONG + r = 7 + draw.ellipse( + _s(rail_x - r - 4, y - r - 4, rail_x + r + 4, y + r + 4), fill=GROUND + ) + draw.ellipse(_s(rail_x - r, y - r, rail_x + r, y + r), fill=colour) + label = f"{number:02d}" if number is not None else "··" + draw.text(_xy(110, y), label, font=index_font, fill=INK_FAINT, anchor="lm") + text = _fit(title, title_font, 600) + draw.text( + _xy(160, y), + text, + font=title_font, + fill=INK if number is not None else INK_FAINT, + anchor="lm", + ) + + hops = len(path) - 1 + figure = str(hops) + draw.text( + _xy(1128, 300), figure, font=_font("SemiBold", 168), fill=INK, anchor="rs" + ) + caption = "link" if hops == 1 else "links" + draw.text( + _xy(1128, 344), caption, font=_font("Regular", 26), fill=INK_MUTED, anchor="rs" + ) + draw.text( + _xy(1128, 380), + f"{len(path)} pages", + font=_font("Regular", 18), + fill=INK_FAINT, + anchor="rs", + ) + + +def _rows(path: list[str]) -> list[tuple[int | None, str]]: + """Every step when they fit; otherwise both ends and an elision between.""" + numbered: list[tuple[int | None, str]] = [ + (i + 1, title) for i, title in enumerate(path) + ] + if len(numbered) <= MAX_ROWS: + return numbered + hidden = len(path) - (MAX_ROWS - 1) + head, tail = numbered[:3], numbered[-(MAX_ROWS - 4) :] + return [*head, (None, f"{hidden} more"), *tail] + + +def _question(draw: ImageDraw.ImageDraw, start: str, end: str) -> None: + font = _font("SemiBold", 40) + for y, title, colour in ((236, start, GREEN), (396, end, RED)): + draw.ellipse(_s(72, y - 8, 88, y + 8), fill=colour) + draw.text(_xy(110, y), _fit(title, font, 980), font=font, fill=INK, anchor="lm") + # The dashed connector the page draws while a search is running. + for y in range(262, 372, 12): + draw.line(_s(80, y, 80, y + 6), fill=RULE_STRONG, width=2 * SCALE) + draw.text( + _xy(110, 316), + "How does one lead to the other?", + font=_font("Regular", 22), + fill=INK_MUTED, + anchor="lm", + ) + + +# --- Text helpers ----------------------------------------------------------- + + +def _fit(text: str, font: ImageFont.FreeTypeFont, max_width: float) -> str: + if font.getlength(text) <= max_width * SCALE: + return text + while len(text) > 1 and font.getlength(text + "…") > max_width * SCALE: + text = text[:-1] + return text.rstrip() + "…" + + +def _tracked_width(text: str, font: ImageFont.FreeTypeFont, tracking: float) -> float: + gap = font.size * tracking + return sum(font.getlength(ch) for ch in text) + gap * (len(text) - 1) + + +def _tracked( + draw: ImageDraw.ImageDraw, + at: tuple[float, float], + text: str, + font: ImageFont.FreeTypeFont, + fill: str, + tracking: float, +) -> None: + """Letter-spaced capitals, as the published OG image sets its labels.""" + x, y = at[0] * SCALE, at[1] * SCALE + gap = font.size * tracking + for ch in text: + draw.text((x, y), ch, font=font, fill=fill) + x += font.getlength(ch) + gap diff --git a/app/store.py b/app/store.py index d946579..be2e971 100644 --- a/app/store.py +++ b/app/store.py @@ -49,6 +49,13 @@ def delete(self, *keys: str) -> None: def expire(self, key: str, seconds: int) -> None: self._redis.expire(key, seconds) + def increment(self, key: str, ttl: int) -> int: + """Add one to a counter, starting its expiry when it is created.""" + count = int(self._redis.incr(key)) # type: ignore[arg-type] + if count == 1: + self._redis.expire(key, ttl) + return count + # --- Sets ------------------------------------------------------------- def set_add(self, key: str, *values: str) -> None: diff --git a/app/tasks.py b/app/tasks.py index ae71d06..ac8114b 100644 --- a/app/tasks.py +++ b/app/tasks.py @@ -10,6 +10,7 @@ from __future__ import annotations import logging +from collections import deque from collections.abc import Callable from dataclasses import asdict from typing import Any, NotRequired, TypedDict @@ -41,6 +42,21 @@ RETRYABLE = (requests.RequestException, redis.RedisError, WikipediaAPIError) +RECENT_PER_SIDE = 6 +"""Pages each frontier shows the UI while it runs: the ones it read last.""" + + +def route_key(start_page: str, end_page: str) -> str: + """Where a found route is kept for shared links, whichever algorithm ran.""" + return f"route:{start_page}:{end_page}" + + +class FrontierStats(TypedDict): + explored: int + depth: int + recent: list[str] + """Newest first.""" + class SearchStats(TypedDict, total=False): """The progress payload the UI renders. Field names are part of the API.""" @@ -54,6 +70,12 @@ class SearchStats(TypedDict, total=False): end_page: str final_depth: int search_completed: bool + algorithm: str + frontier: dict[str, FrontierStats] + """In flight: per-side counts and the pages each side read last.""" + meeting_page: str + sides: dict[str, dict[str, int]] + """Finished: per-side ``explored`` and ``depth``.""" class TaskResult(TypedDict): @@ -96,6 +118,7 @@ def publish(stage: str, stats: SearchStats, elapsed: float = 0.0) -> None: "start_page": start_page, "end_page": end_page, "max_depth": settings.max_search_depth, + "algorithm": algorithm, **stats, }, "search_time_elapsed": elapsed, @@ -121,7 +144,13 @@ def publish(stage: str, stats: SearchStats, elapsed: float = 0.0) -> None: }, ) + recent: dict[str, deque[str]] = { + "forward": deque(maxlen=RECENT_PER_SIDE), + "backward": deque(maxlen=RECENT_PER_SIDE), + } + def on_progress(progress: Progress) -> None: + recent[progress.side].appendleft(progress.last_node) publish( "Searching...", { @@ -129,6 +158,14 @@ def on_progress(progress: Progress) -> None: "queue_size": progress.queue_size, "current_depth": progress.current_depth, "last_node": progress.last_node, + "frontier": { + side: { + "explored": stats["explored"], + "depth": stats["depth"], + "recent": list(recent[side]), + } + for side, stats in progress.sides.items() + }, }, elapsed=progress.elapsed, ) @@ -178,6 +215,9 @@ def on_progress(progress: Progress) -> None: "nodes_explored": result.nodes_explored, "final_depth": max(result.length - 1, 0), "search_completed": True, + "algorithm": algorithm, + "meeting_page": result.meeting, + "sides": result.sides, }, } @@ -233,9 +273,14 @@ def _find_path( logger.info( "path_cache_hit", extra={"start_page": start_page, "end_page": end_page} ) - return PathResult(**cached) - - finder = PathFinder(app.wikipedia, app.store, app.settings, on_progress) - result = finder.find(start_page, end_page, algorithm) - app.store.set(cache_key, asdict(result), ttl=app.settings.path_cache_ttl) + result = PathResult(**cached) + else: + finder = PathFinder(app.wikipedia, app.store, app.settings, on_progress) + result = finder.find(start_page, end_page, algorithm) + app.store.set(cache_key, asdict(result), ttl=app.settings.path_cache_ttl) + + # Shared links outlive the path cache; every hit renews the route. + app.store.set( + route_key(start_page, end_page), result.path, ttl=app.settings.share_ttl + ) return result diff --git a/app/wikipedia.py b/app/wikipedia.py index 5ba9e2b..7a48cc2 100644 --- a/app/wikipedia.py +++ b/app/wikipedia.py @@ -27,6 +27,7 @@ from app.config import Settings from app.errors import WikipediaAPIError from app.store import RedisStore +from app.wikitext import LinkContext, find_link_context logger = logging.getLogger(__name__) @@ -38,6 +39,8 @@ links out of the 500-link allowance, and keeps titles that merely contain a colon ("Star Wars: Episode IV – A New Hope") in.""" +SUGGESTION_LIMIT = 8 + PageFetched = Callable[[str, list[str]], None] """Called with (title, titles-found) as each page arrives. Runs on worker threads.""" @@ -49,6 +52,13 @@ class PageStatus: is_disambiguation: bool +@dataclass(frozen=True, slots=True) +class Suggestion: + title: str + description: str + is_disambiguation: bool + + @dataclass(frozen=True, slots=True) class LinkQuery: """One of the two directions the graph can be walked in.""" @@ -136,6 +146,10 @@ def backlinks( def page_status(self, title: str) -> PageStatus: ... + def suggest(self, prefix: str) -> list[Suggestion]: ... + + def link_context(self, source: str, target: str) -> LinkContext: ... + class WikipediaClient: """Fetches page links, with a shared rate limit and a Redis-backed cache.""" @@ -182,6 +196,87 @@ def page_status(self, title: str) -> PageStatus: self.cache.set(cache_key, asdict(status), ttl=self.settings.page_cache_ttl) return status + def suggest(self, prefix: str) -> list[Suggestion]: + """Articles whose titles start with ``prefix``, best match first. + + Redirects are resolved, so "usa" offers "United States" rather than the + redirect page; disambiguation pages are flagged so the UI can say so + before they are rejected as an end page. + """ + prefix = prefix.strip() + if not prefix: + return [] + cache_key = f"suggest:{prefix.casefold()}" + if self.cache and (cached := self.cache.get(cache_key)) is not None: + return [Suggestion(**item) for item in cached] + + query = self._request( + { + "generator": "prefixsearch", + "gpssearch": prefix, + "gpslimit": SUGGESTION_LIMIT, + "gpsnamespace": ARTICLE_NAMESPACE, + "prop": "description|pageprops", + "ppprop": "disambiguation", + "formatversion": 2, + } + ).get("query", {}) + + # Two prefix hits can redirect to one article; keep its best rank. + ranked = sorted(query.get("pages", []), key=lambda page: page.get("index", 0)) + seen: set[str] = set() + suggestions: list[Suggestion] = [] + for page in ranked: + title = page.get("title", "") + if not title or title in seen or "missing" in page: + continue + seen.add(title) + suggestions.append( + Suggestion( + title=title, + description=page.get("description", ""), + is_disambiguation="disambiguation" in page.get("pageprops", {}), + ) + ) + + if self.cache: + self.cache.set( + cache_key, + [asdict(item) for item in suggestions], + ttl=self.settings.suggest_cache_ttl, + ) + return suggestions + + def link_context(self, source: str, target: str) -> LinkContext: + """The sentence in ``source`` that carries its link to ``target``.""" + cache_key = f"context:{source}:{target}" + if self.cache and (cached := self.cache.get(cache_key)): + return LinkContext(**cached) + + response = self._request( + { + "titles": source, + "prop": "revisions", + "rvprop": "content", + "rvslots": "main", + "formatversion": 2, + } + ) + pages = response.get("query", {}).get("pages", []) + revisions = pages[0].get("revisions", []) if pages else [] + wikitext = ( + revisions[0].get("slots", {}).get("main", {}).get("content", "") + if revisions + else "" + ) + context = find_link_context(wikitext, target) + + if self.cache: + self.cache.set( + cache_key, asdict(context), ttl=self.settings.context_cache_ttl + ) + return context + def _page_status(self, title: str) -> PageStatus: query = self._request( {"titles": title, "prop": "info|categories", "cllimit": "max"} @@ -276,13 +371,19 @@ def _fetch_many( self.cache.set( f"{query.cache_prefix}:{title}", found, - ttl=self.settings.links_cache_ttl, + ttl=self._links_ttl(found), ) if on_page: on_page(title, found) return results + def _links_ttl(self, found: list[str]) -> int: + """Hubs are cached longer: see ``Settings.hub_cache_ttl``.""" + if len(found) >= self.settings.hub_link_threshold: + return self.settings.hub_cache_ttl + return self.settings.links_cache_ttl + def _fetch_one(self, query: LinkQuery, title: str) -> list[str]: """Fetch one page, following continuations up to the configured limit.""" params: dict[str, str | int] = {"titles": title, **query.params} diff --git a/app/wikitext.py b/app/wikitext.py new file mode 100644 index 0000000..c708fc3 --- /dev/null +++ b/app/wikitext.py @@ -0,0 +1,182 @@ +"""Find the sentence in an article's wikitext that links to another article. + +A path step says "A links to B"; this is what makes it say *why*. The link is +looked for in the article's prose, after templates, references, tables and +file captions are stripped away, and the sentence around it is returned as +plain text, split around the link's own words. + +Where the link is not in prose, the answer says so rather than guessing: +``template`` when it sits inside an infobox, table or other template in the +wikitext itself, and ``elsewhere`` when it is not in the wikitext at all — +the usual case for navigation boxes, which are transcluded at render time. +""" + +from __future__ import annotations + +import re +from dataclasses import dataclass +from typing import Literal + +Where = Literal["prose", "template", "elsewhere"] + +MAX_SENTENCE = 320 +"""Characters kept, link included, when a sentence runs long.""" + +ANCHOR_OPEN, ANCHOR_CLOSE = "\x01", "\x02" +"""Marks the target link's words while the line is reduced to plain text.""" + +_COMMENT = re.compile(r"", re.DOTALL) +_REF = re.compile(r"/]*/>|]*>.*?", re.DOTALL | re.IGNORECASE) +_TEMPLATE = re.compile(r"\{\{[^{}]*\}\}") +_TABLE = re.compile(r"\{\|[^{]*?\|\}", re.DOTALL) +_FILE = re.compile(r"\[\[(?:File|Image):[^\[\]]*(?:\[\[[^\]]*\]\][^\[\]]*)*\]\]", re.I) +_LINK = re.compile(r"\[\[([^\[\]|]+)(?:\|([^\[\]]*))?\]\]") +_LINK_WITH_TRAIL = re.compile(_LINK.pattern + r"([a-z]*)") +"""Letters straight after ``]]`` render as part of the link: [[plantain]]s.""" +_EXTERNAL = re.compile(r"\[https?://\S+\s*([^\]]*)\]") +_TAG = re.compile(r"<[^>]+>") +_HEADING = re.compile(r"^(={2,6})\s*(.*?)\s*\1\s*$") +_SENTENCE_END = re.compile(r"(?<=[.!?])[\"”’)]*\s+(?=[\"“(\[A-Z0-9])") + + +@dataclass(frozen=True, slots=True) +class LinkContext: + """The sentence as three runs, so no client has to count characters: + ``before + link + after`` is the sentence and ``link`` is the linked words.""" + + where: Where + before: str = "" + link: str = "" + after: str = "" + section: str | None = None + """The heading the sentence sits under; ``None`` for the lead.""" + + +def find_link_context(wikitext: str, target: str) -> LinkContext: + if not wikitext or not target: + return LinkContext(where="elsewhere") + + raw = _COMMENT.sub("", wikitext) + if not _links_to(raw, target): + return LinkContext(where="elsewhere") + + prose = _strip_structure(raw) + section: str | None = None + for line in prose.splitlines(): + if heading := _HEADING.match(line.strip()): + section = _plain(heading.group(2)) or None + continue + if not _links_to(line, target): + continue + text = _plain(_mark_target(line.lstrip("*#:; "), target)) + if runs := _sentence_around_anchor(text): + before, link, after = runs + return LinkContext( + where="prose", before=before, link=link, after=after, section=section + ) + + return LinkContext(where="template") + + +# --- Matching ------------------------------------------------------------- + + +def _same_title(written: str, target: str) -> bool: + """MediaWiki's title equality: first letter and spaces/underscores loose.""" + + def norm(title: str) -> str: + title = re.sub(r"[\s_]+", " ", title.split("#", 1)[0]).strip() + return title[:1].upper() + title[1:] + + return bool(written.strip()) and norm(written) == norm(target) + + +def _links_to(text: str, target: str) -> bool: + return any(_same_title(m.group(1), target) for m in _LINK.finditer(text)) + + +def _mark_target(line: str, target: str) -> str: + """Wrap the first link to ``target`` in anchor marks; leave the rest.""" + marked = False + + def replace(match: re.Match[str]) -> str: + nonlocal marked + if marked or not _same_title(match.group(1), target): + return match.group(0) + marked = True + words = (match.group(2) or match.group(1).split("#", 1)[0]) + match.group(3) + return f"{ANCHOR_OPEN}{words}{ANCHOR_CLOSE}" + + return _LINK_WITH_TRAIL.sub(replace, line) + + +# --- Reduction to plain text --------------------------------------------- + + +def _strip_structure(text: str) -> str: + """Remove everything that is not running prose.""" + text = _REF.sub("", text) + text = _remove_nested(_FILE, text) + text = _remove_nested(_TEMPLATE, text) + return _remove_nested(_TABLE, text) + + +def _remove_nested(pattern: re.Pattern[str], text: str) -> str: + """Delete innermost matches until none remain, so nesting unwinds.""" + while True: + reduced = pattern.sub("", text) + if reduced == text: + return text + text = reduced + + +def _plain(text: str) -> str: + text = _LINK.sub(lambda m: m.group(2) or m.group(1).split("#", 1)[0], text) + text = _EXTERNAL.sub(lambda m: m.group(1), text) + text = _TAG.sub("", text) + text = text.replace("'''", "").replace("''", "") + text = text.replace(" ", " ").replace("–", "–").replace("—", "—") + text = re.sub(r"\s+", " ", text) + # Removed references and templates leave stray gaps before punctuation. + text = re.sub(r"\s+([,.;:!?)])", r"\1", text) + text = re.sub(r"\(\s*\)", "", text) + return text.strip() + + +def _sentence_around_anchor(text: str) -> tuple[str, str, str] | None: + start = text.find(ANCHOR_OPEN) + end = text.find(ANCHOR_CLOSE, start) + if start < 0 or end < 0: + return None + + boundaries = [0, *(m.end() for m in _SENTENCE_END.finditer(text)), len(text)] + begin = max(b for b in boundaries if b <= start) + finish = min(b for b in boundaries if b > end) + + before = text[begin:start].lstrip() + link = text[start + 1 : end] + after = text[end + 1 : finish].rstrip() + if not link.strip(): + return None + return _trim(before, link, after) + + +def _trim(before: str, link: str, after: str) -> tuple[str, str, str]: + """Shorten a long sentence to a window around the link, at word breaks.""" + spare = MAX_SENTENCE - len(link) + if len(before) + len(after) <= spare: + return before, link, after + if spare <= 0: + return "…", link[:MAX_SENTENCE], "…" + + keep_before = min(len(before), max(spare // 2, spare - len(after))) + keep_after = spare - keep_before + if keep_before < len(before): + cut = before[-keep_before:] if keep_before else "" + cut = cut.split(" ", 1)[1] if " " in cut else cut + before = "…" + cut + if keep_after < len(after): + cut = after[:keep_after] + cut = cut.rsplit(" ", 1)[0] if " " in cut else cut + after = cut + "…" + return before, link, after diff --git a/entrypoint.sh b/entrypoint.sh old mode 100644 new mode 100755 index a9265f3..a31671a --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,13 +1,16 @@ #!/bin/sh # -# entrypoint.sh — Docker container entrypoint +# entrypoint.sh — the container's CMD (see Dockerfile) # -# Switches between web and worker modes based on the SERVICE_TYPE env var. -# Used by the Dockerfile and railway.toml for Railway deployments. +# One image runs both services; SERVICE_TYPE picks the role: # # SERVICE_TYPE=worker → Celery worker # SERVICE_TYPE= → Gunicorn web server (default) # +# The web server uses threaded workers because GET /tasks/stream/ holds a +# connection open for the length of a search; a sync worker would be pinned to +# one viewer. --timeout bounds a stuck worker, not a long request, under gthread. +# # Port is read from PORT env var (default: 8080, Railway sets this automatically). set -e @@ -20,5 +23,10 @@ if [ "$SERVICE_TYPE" = "worker" ]; then --concurrency=2 else echo "Starting Gunicorn on port ${PORT:-8080}..." - exec gunicorn --bind "0.0.0.0:${PORT:-8080}" --workers 2 --timeout 120 run:app + exec gunicorn --bind "0.0.0.0:${PORT:-8080}" \ + --workers 2 \ + --worker-class gthread \ + --threads 16 \ + --timeout 120 \ + run:app fi diff --git a/pyproject.toml b/pyproject.toml index cf5502f..c5afd55 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,6 +8,7 @@ dependencies = [ "flask>=3.1.1", "gunicorn>=23.0.0", "marshmallow>=3.22.0", + "pillow>=11.0.0", "python-dotenv>=1.1.1", "redis>=6.2.0", "requests>=2.32.4", diff --git a/railway.toml b/railway.toml index 7b5fa0e..c9a2770 100644 --- a/railway.toml +++ b/railway.toml @@ -1,8 +1,8 @@ +# The start command is the Dockerfile's CMD; it is not repeated here. [build] builder = "DOCKERFILE" dockerfilePath = "Dockerfile" [deploy] -startCommand = "/entrypoint.sh" restartPolicyType = "ON_FAILURE" restartPolicyMaxRetries = 3 diff --git a/static/404.html b/static/404.html new file mode 100644 index 0000000..c2e542e --- /dev/null +++ b/static/404.html @@ -0,0 +1,56 @@ + + + + + + Page not found · Iris + + + + + + + + + + + + +

+
+ + + Iris + + +
+ +
+
+

404

+

No page here.

+

+ Nothing links to this address. Iris is a single page, + and Wikipedia has the other seven million. +

+ +
+
+ + +
+ + diff --git a/static/apple-touch-icon.png b/static/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0f4a82187862b54c878014d59670d60521884610 GIT binary patch literal 6600 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 - - - - - - - - - - - - - - diff --git a/static/favicon-light.svg b/static/favicon-light.svg deleted file mode 100644 index 7e506fc..0000000 --- a/static/favicon-light.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/static/favicon.ico b/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..c26873064c7579fbb112e134b2e1bf8a33cf9b53 GIT binary patch literal 4723 zcmai2Wl$6hw_fR#)CUADq>-gNmRPz(x-&8(_t%}dXXebwIlrEn=bQroJOW??$jJeJg&8o61ptWr>oNZ~=D`C1u(1JvmoNVt z%M$_se1A1UT~&dU=o!)9EUDr<*$;p1zZ1v_{`LcyP9IDG0IUQ>S@1`X3|IKD-A8Nc zUjMBY_d|cUV3@uT0{yW8cuw_6QUW{+#AsV(NcI3UZ6@Ekp>k}FQk+6BN zvf3t+g;0Ru0qV=8GWX%It3;?gibZxxUQ4JtDx8P6lgIl32;U(Zc-%Uc~_R0c5$9`zJ)f14b}geN6(c@wg~f8EH{Fp&C-($Dk7h% zaW#6F2j>d9hufnP_1#lFBveZb*lgv?P#YDl`ioJ|6TC283knZShBk*+A2T5XYIa9I z;hJ$eQ)Y{gOR?Xe-M^9w_4E!G)^Qm7eS9mR8u~+E6uz+4-W^U=Bs#!RSKp@XW6qjx zLA6uwL(f0{tBtMaeBcZHi-x9&S4Az#O|?Pxk0@jW4RoF*%>4AZd%%@dZc=s#y}hgw zp*(rHTqjEjfqY&O{v|VMH2h8ago&%1&O&qlMEEaE0g7^}vK0`Mp#KBR%zw+w{{gd$ zm)98pfP4I3F!vkPzv-gImpMwTt`3NXuov zn7iAn8k>1SiydtDt$ndk&-;hd=3m}8%z+jb7Cz(0lTv(V$pPGPBgTU0Z-A|kCt+(Z zuXV{$52Gf;H9EWwvoZPE;C{O3(&@Bwau$*dKxVTlFQbFdlBedn^Auqp)eDw&Qavt~ zWrW@y>!t+*OF@|GQk0BuayzOHb_}5yQDzk#D%V11)6IRfmOvsW_|U`-)FLK z$>mDKku(}WC^>=mA!;%4EmF`evv+IR!g+-Rsjhguq(L%*O2v&|k$qp4ulbAghi+Y~ zY)%K0$Gr-q*=+%f>k273C;St?=ag&^Mh=jGV z;fckRq1keQKdU~Ok`LlC?6__X z=V+QDYd55;Q7pntB;lmld8;U8(4$ryy{qNi+85`(d9`Y1%^N6$XSjM+OpwQ%=cEyF zf&#AG5Cron6_+Rm!mwrT)7$O9$=^ zjCZ->`w}Cw(npsH&)Rm2+V4U>Ni6g5^Yd3f0&HuN;y8ynURaB?-`Yr5m=ngEu@Up3g}_oGTe*x|n2tma*CWLUqi??oojf zU(vB3iKqQ{RLdKOO>yo|pu`K0oMrD@%iLbH7rZ$>302zfM@FFk-RYvwQC(WIix1hD z&o9n3`>G1}yxD5wKqPS>R=wim^VrxTwZcwUDtLx{hy+al(o+yu;~@*$;VM?IV|}!* zo9B?deHpN=*|8hU4Nt^bA?$UFT2rwMw`1^onArO1WEJD>wxqxbZ`t={DJW>E?RN3^ z3A9f~U{#8cMD)~XaM91O=RgMD=a31y^V)u#K6QzH1PqskkF!zNHVrMYJp-Aby3letn47obP zrM4s97w13FY7fMYt=YMbJ&E?cAxKk6*jn?V)jP*C_S_e!S9M&uiDfF7`?QRaGNq?# zA;WlYwkLLfq2G-Z&hkCfbz5>LTWGM~I@{-_yHQD(9vRT!67#yHaa(#2JL$nvY)0%E zgD2JX%GeEhI=He|myiw{=%c&f?1xP`@1_>xMg|VEERR(auhKG126>lP`(%^NjOp0= zO3_0=RxA8MDGfx+blYIGId(s~daYY~K-`s@C?lBocx9Yb|8Pmh{>07pltCOyk!dA+ z015j!_*m*9^;ar+nBIzvJ6J;+-nIclL#Gb2Tnfl}mxA}&_L+rVFTssL{Emwx~IGbp_p zbD|8T!i9jjp!IZA47z0#2S%SOuhi_j-;i;84kw^keVX8lnnk4w=bOXAXuixT?BE}g z!-DYg>7>Dyd-iU&E7AFrBg3mP)M5N>Q!Wvgx4aL`kH=YT8^XIRZ`uZY5(f-bPR^x< z3In{*Y{19+jnWI-FzK_h)X#OBOB_#-s1P)7_!-_$ezVW+ z9m5;2d|6vMktgA2pfROaROfi+_8#UQO+b1p9 z_Pcd)>9ECv70bCeXA)9{Q}W*CQ8aZScZo>3Z2ob1T{$NLEu!~9r6A#LBtpyFI8V5$ zJUZ!q;#pxL<)lcfoMf?ym>dQ9x{;gX(ZxnXTdIwf8`YL@6 zwRL%GrR4-<%=u)aD7@WYhvyOl%;PfcDgJS3N0;3`dP=CuYGe_Y40b6>J*=R z`@bVtsUqbux;Kn|KU`juwjQmTy)&O={q6If7_P0%woS5#>ZJN7jgZt-q~LtIrX)L+ z6%`_^5opLu7wVH+l~pIG&z%5)*wdRXG!GUP&TEr2?(GloW{>Un($j7W(`@$z7ZxSw z*Zr1|iKd`-#g75ER267{oY*9{S`G%MrH(M!);<=F z>m`Vo_JZZu!B04@KF5ebH~%1M+Q2_?boiKnwFwzFvtB{Jkm22CVWcpe?>*7eC?(EM z5%T>uAzM~J)kj6*;l;AOmMRBi5q2`{w3bU-hNPmrFd-!q)DO8NLvd4$QtGqP`%Y_7 zT%OhnFPW!}alOwGp-<|~&hsh6rT3Rxx2AJ^?RIwGsN+;f&vuBl8oT9|o(3fZ{R57u zP-plWy+ZSY*fZ#*1}l!Li8wb(nO}(?HwQe!M*HTx;LZ zx*BVBUOayO&>-J%Lbd9`H_-ZmPcca}QuRW+(*m+w-6`i|2FVYaMl81-k&0|+0hKR~ zfeh|-;1W0T1!L;al)&Vz>^?D90cQwvofLiJa`-$~l}f|YwhJb=r&wkX5?!N@0-y@n z=leqwt=ERy@|ftjYO`sg#5}hASKUMcZsk`mz-r4_q9k3V<)$J)Ayl`Gk5 z$#)uVAJX^uaxJ=xw7Dy6?206{nfWcJ=HE>dDYq?gow}tRxVOk$wu!$C?2Wt$FMgYV zGlVecsN^>oy|sDz?Zw6)+2QX7x@ehomx4_cNA;oU*~ZXwrPxOD$ty-rdym5jhbL{V znNN|g4q3GFIZN-^89(;ZB!H;Q;Cta}r81ysaq>U0r0FRx_b?;Rn&=lVT1j+E3~fia zaC#ttTdy4~&>W|p`FG|O`pw@;vf3}%nbwJ#vq4QxiqrhtgBL&tFp}y5%t0m9Q6x9+ z2#Z@t+gQfO*STs}BFf#&^K@xkLC_5#CNTG7sdJt8(-XgjUu%Ci>F7D-w!vKaN^iDE zde1Gw*Fs{1m^QHETML%pUGdTg1|Y9523Ma*QH`@pkWR#DN;_$+)mxhQDKE2qVz_LK zIQfsYgb$NFYqu^#Ppq=NIY%A6LN<;oScvy5?MrjoHknHGZm?9tPzGRBkL7H$k z6`}S~6kh&^_NMo|jMl%iBqbXCT85^y`CBq9jSW?s%%z)V_w?NR9zEeT=$@&(PjiV= zVDe13V0cpuWnWZ{!DAy{eKy9k9-@-|(_-oKlAkpQTGdA|YL}%S=j(V~MaEvc3^r;;^P>@L<^ZJka#6X!mNNHUY8BANd%P`7n zpy~3~?2!@vwDfcWg_Rrg(g0tY7zLBPEY?fM53nuC-FzvYv5nHM*gq#>X_w+c`tui5 zvGd;rpMV6LfKET;w1DK$%)v!{f2d-wqTJ1%^G?v*CMNVbH7xkl@m}~il+b}hlL!4! zhIP>_jJkYz0DV0!dQJipkVV?y$JZnl$l|l8lv|7HzL8HDwN?A`7#JPZEowhqxb4)4 zEfvT^%VpQMJQA<=1MA}LLgW;cU0PIC(RtlsXR9Xnip2p?kdfNy#aGh+o-?f|W01JL z!SdfEkW7GCvJ=9z6T1YF=ix4S_SurIV_;qY5|a;{y&H!Y=lRCc$TWo>xP;-#ty%PG zl3^h!F7#y!|{OrDEw|+ zGA{xlP~{^XvlC>_{v)s?NTM`_4ra5`L+ODQ-}+z-?@ z09)T*5IIEk>jUlRO=0OmK}Gv()+snruV%GnB$>lqb - - - - - - - - - - - - - + + + + + + + + + + diff --git a/static/icon-192.png b/static/icon-192.png new file mode 100644 index 0000000000000000000000000000000000000000..037a1c3796f112f2f1f8cc3e3089a58792d23ae8 GIT binary patch literal 5659 zcmd6LPtC>(+WH><}x0z~50E2M|z@Vu?UaLF*MROJT8FuqfH6rgE<*I(SmFvqY z=Ufl7%EWvSu6-{d2%K~s#bjfA(Ak(Dok*WJ))vL_V=f9gEHDK&9vF`Tk5c;oW`Z3= zyV0zdUxP!Af*pqYDD!Db?xL->4c_qypQcuz))99snx&&+k|R-A%gYBbof2{OZw>b} zNpydVClKJHyd8$uN)>EFN9^2w966muV~8UI(Z2R}@d^8T*!3i?d+L0K8wB}wV-s<) zO~5;mo}EF>&W+@LHxGG&)=!V|T+Wt6oT2rnlPtBKvm=C`jyfk+RnweQ_meR8a$Tp_E6LNm4O{6qnQZmSj0B+Y*o*Z7fTFgpd6m!(fE6Z_%RAI{>3&B)> z(7}Wl$pP*lGsVmCCvpA`g42%FK|Zg|If;_ZUZ{ELw}ngioqtr{8Jtwq*2cUkRXRB7 z@QTCr#tlAq-me4Rbgjes=wlAFiJLS6exmq4mt176XPh_T7f}(TuF)%pdBdSo=EvA| ziB+cy#;=dY-hxf9p8eNbNzC;}TzQ)VwQpcSHYA94>@Y9l^l2zNE&fuiHHa2em7~Zq z#L2dcC8&=TTB@IFT$kxpZY(Xp&|dNBzVVZY=A3fmh>f1{$&+I)fFj>EW&1(G?;9%H zfnQfAOTNc;#}FMQ{#8n$yPvb~Nd{s$5*Q@Z_E#;dvVN!D6zQEg1RN9@z5JjN$(>UX;tIC^D4tTTqnse}gr?kR zpxBp>tx&V=HfxD@xM7+^$({9H*+sA+}ab~P1GmtEd-8OY)uWh@sf%chz@#$Z%4lV!MBO^ zv~OrseGr$}4XNm!ylj4*o|mDrrlZ^JM}=V{)zrXn35rKQ4zks^G0ff1c4J4Lz@Dee z%pF;;9oYy~#@SvF1de}1Eb>X`YsH9*M}T)nMCCB_q-4ugFJ36Hp&hTIoDsb zo|7nJT50hKMG><$LAKRE}7NO|bG~(H_w5H^O zPSz;GP4fU!t!u81M{ynGBOUt-#yP^wlp<%Ed6DF3W!;iNX`ynze+E_+Xxe2H zfnXrUHTB4*J&1jw$w$i21_epEGZSmHo~A#Q-Cq67Yru6xIX7kI2m?K_?_a&N{n;5d z{v-qGR>Y=b9 zd=*ZR-VzLO+)4W%2R{zGOBct*CSMfHZP)Jtf$}FPevQLlE-9bPZF=+5yfs8fJ@03h zZ;Eu;psF8IH1~>AOrXH;6vu!4_pDY#^Bk-~wEY2u^r4Y}vIEbXuwhQBH{xTHPbfsI z1u}0x4}^mJvx{9VqJJ~PUoPNAoct|}f3>&J+v_2zWNgz^rm1)C7<%|LNpSCCissD! z7f*+-FH5WqsHH%idG=89%P>bWi@jcC)(G$C8Q2w0*L^Z?_Vr{hT^yBaVIZip=glq< zB`ZbcGMjsAcs$7b*Pu2izL=t#m7_=+Khu!~7HyQb5;jt22YU)3IP!9Ge_h%-T^OSk zJIKh$|||TSLR7k71aw z{$Q>2zB#5s#U2McUG=3unHzeTkXKXn#wPi=FzIjVS-inSumD5el~rmVi^CS7GRKuw zcDZJe6x@N&!mT?i%?PL2s_DKD2TGUnXrwkCCFT8@_V*O0 zLX^o860}+h+Es}nOunijgQ+ZE`dKjMt(*vjBHbL< z)7BbB^_f1bYb&(xtf%-QoJZC~on=hvEqA|8h7|aOf$pO`4mTt)7A7`dh13v;BSu+U zv!Kb*x53amG*H)$Se)okKL%BYd$M1iblD$A^t_kcDJONU;nhp*$NX_p@8|jJZ|-^G zq!^MUsjICg)twslSQ;&Ey$9ZZwRI9Z97!6a^Q+w_RySx)9lzE+lFk!yfD6vsLge>zF~Vg&3Q91lqri$|AKL_P=Y7!&a92KOPFZ@%;Ds` z6!B~B@b4y|WG#$BV~q-fov7;s#DZgoOkrWk+Ue0?YvFkr z^5%Ld$6^xN-TDSQ#XEB53OW01a#F9L{}_tDG#$kO&~zWX&>L>E?s1d9`>a&|J%gLb|sXJn-lP_=(~Q|9^_pcInh*D>2GNkbZ+>C{#V+o zZ{A^t$V6G9f;bd2x0O-~4>y8JthA!+dg+<529^wqzcncVGQEpDi_aF~gY*?Bapg7pIWef4b5}-Il3vPxJp~@`;`iKTcSs z%DVta)H~XTK~aOa)YzZi+Gb9OzDBnDZ}8pBhN=BKmH%i@9yUKhg`e4ekDO-CBI1MF zOzj$eo_|m_S|)t&syTFJTwge%Ds<>fhOD z*ZMbw&2?U`ofW}PZZO7sn+b%LA;OIv zQ9}rjFGpx}2gKv!dRB?S-A?&S%hOD%pL)Lts{|ArJNRNVU_)3E2G1r%NKjL<3$-Xt!u@vVzonw3z%I z%Uv`qX_sefSwOrSDzM#I;6~HddhVYU1L+5dMwfV za&_XoC42xXMjKy)AbMTM)!k?qyKhi`+^^vmcH>&~?*4efcq5Ou~!RK6*@9}CZQt>4Nsa+cav2j%o19igd7 zlpYAB0}G}3_^()uZ+TblFqp}-`_tub|FPcrMche&24`Tw^R!CAJjo*5%=v1p50C-+ z?qY;U_t{S>9CxQRTXJGn%L^ZlQ|sGOCi*@(SSB|JgsCtLL-qb75`4Cdt`Q%YyEDr6 zI@7=DzeEc_5^50H#JTvYIiszYGX`Gh9;m5>z;mKZI0^0s_aQ_Z)G&isWEo8?F#U`nD}w9UTKZB)LPa`Yu?F-Sh!E+ z*Q7aPymX!@^UqAxCLK5;QWXg@mC~8sB>Fwh_#zHEH_r7|oCMTD%`Vmk)=v!9D@1e( zv4;jbG5jtqU*Oj2uT({(SBY!T(Sjpu2+$>Q>t&0DU%c#*V3_LjuB7HKt7?5>)_JkD zJm*lsrGK(r-;E;e_By;By3EYuRI*(0tbs3&=H^Vz!>eCILi2#|%OfW>3lqzB_#D;o z{NlminJnlxsI#U3NC0POh$qE`?BMduSJF&VcG4^tyUN@8Ef)+HMS5?CmznfOp7Cw*%27Wt} ztk5|^j+!Zx1wVHLicm^dNegZjd#C-zo0qg-xfUkSD`9gPhW(8zDs<9&GbM*gGO9?d z#oRK0MdGT7jXZQhiC$;v6p&<1iCum(p!?`0`B|)orRN&bI#D#89GKGUdi<{5B+2{w zp66XgK0gSdrL5m{c3SfB{PEfVx3UTzAC9WWR?^fq zJ>)kr+DJ*;)v=TUQS2E=P#?BXEARJ z`L75#*`RzM`9agLfr&9#d;i{*_d$sOv@a3 z110t8L}7aE1ZlsS+rJy&QDDW*gspuOzObE3TxSN*mV)g$qRiNlHB%~b3i>XxQ4k!r zDq1~H!p4GkTik;+blf<75w9KDgB*;jZ`}o$e`ey~%}dopSQy6>u@bRMqcLO^Z)|

hfTh*p*@Bw-!=DA$`)J?b^GTLt@-iuUIAuYZ6GS7~xGg-?p0PWwu`5 z2f)n+UTu)%sPzMIbLTGj>!26b-%#L|q^hs%$ml*oFV*yog2k2ot@W(_zrmXwr-d^Y zR05X)p#{zso$1`Mwu5K#y3qJ2$%!w5%AzXh-oYB=18 zlP}*roq!N0JxCVO>#k?cwzz5CFN{6jaJ3w{9QQKGE?_ZU&vazy>D#y~&RhGO$kMA8 z5eaDe?eK`KoKSvoXdq*j-(uy6dC()~X?8$lgMjkrm_TaI7d91jU#iQ{UzvzrL;LFDqEYRtLX^Qcca7p zlSr2})uFFTK`961rV^oTESjaoZu%bZO>g)u;Y#+Fy08-*LS=#9Fyo6n{usYA<~C~= ycoL3xH>&6{kV;^|{QuLW{9p1uLu}XXu^{wS3{Pg!?;cEFETwnqa%D0mLH`3HmaoVF literal 0 HcmV?d00001 diff --git a/static/icon-512.png b/static/icon-512.png new file mode 100644 index 0000000000000000000000000000000000000000..b69dcfb1e23cadf0ea86b7de48a0de33bde65589 GIT binary patch literal 15044 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 b50I!m9!xi#TnF|V0)ILhhL5Y%pGN&J5n85z literal 0 HcmV?d00001 diff --git a/static/index.html b/static/index.html index 7fb4df8..3284096 100644 --- a/static/index.html +++ b/static/index.html @@ -19,12 +19,11 @@ - + + + + + - @@ -108,17 +94,17 @@

Watch
- The readings update as each page is fetched: - depth reached, pages explored, the frontier - still queued, and the page being read now. + Each side shows the pages it is reading and + how deep it has gone; the readings count + pages explored and the frontier still queued.
Explore
- Drag nodes to rearrange the graph; open any - step on Wikipedia. Your last search survives - a refresh. + Each step quotes the sentence that links it + to the next. Drag the graph, open any step on + Wikipedia, or copy a link to the route.
@@ -141,7 +127,7 @@

>
- + autocapitalize="off" spellcheck="false" enterkeyhint="next" + role="combobox" + aria-autocomplete="list" + aria-expanded="false" + aria-controls="startPageSuggestions" required /> +
- + autocapitalize="off" spellcheck="false" enterkeyhint="go" + role="combobox" + aria-autocomplete="list" + aria-expanded="false" + aria-controls="endPageSuggestions" required /> +
@@ -195,6 +201,14 @@

+

+ Try + + +

+ diff --git a/static/robots.txt b/static/robots.txt index 669f404..009da2a 100644 --- a/static/robots.txt +++ b/static/robots.txt @@ -1,5 +1,7 @@ User-agent: * Allow: / -Disallow: /api/docs +Allow: /api/og.png +Disallow: /api/ Disallow: /apispec.json -Disallow: /cache/clear +Disallow: /tasks/ +Disallow: /getPath diff --git a/static/script.js b/static/script.js index db79f15..920ea81 100644 --- a/static/script.js +++ b/static/script.js @@ -13,6 +13,25 @@ const NODE_R = 14; const SVG_NS = "http://www.w3.org/2000/svg"; +// Suggestions start after two characters, once typing pauses +const SUGGEST_MIN_CHARS = 2; +const SUGGEST_DELAY_MS = 140; + +// Routes known to resolve, for a visitor who arrives with nothing in mind +const EXAMPLES = [ + ["Banana", "Shah Rukh Khan"], + ["Python (programming language)", "Monty Python"], + ["Coffee", "Moon"], + ["Chess", "Ancient Egypt"], + ["Jazz", "Mount Everest"], + ["Pizza", "Albert Einstein"], + ["Tea", "Black hole"], + ["Ballet", "Volcano"], +]; +const EXAMPLES_SHOWN = 3; + +const TERMINAL = new Set(["SUCCESS", "FAILURE", "REVOKED"]); + const $ = (id) => document.getElementById(id); const formatSeconds = (seconds) => @@ -21,6 +40,33 @@ const formatSeconds = (seconds) => const wikipediaUrl = (page) => `https://en.wikipedia.org/wiki/${encodeURIComponent(page)}`; +// A route as a link anyone can open: /?from=…&to=… +function shareUrl(start, end) { + const url = new URL("/", window.location.origin); + url.searchParams.set("from", start); + url.searchParams.set("to", end); + return url.toString(); +} + +function sharedRoute() { + const params = new URLSearchParams(window.location.search); + const start = params.get("from")?.trim(); + const end = params.get("to")?.trim(); + return start && end ? { start, end } : null; +} + +const plural = (count, word) => + `${count.toLocaleString()} ${count === 1 ? word : `${word}s`}`; + +function shuffled(items) { + const copy = [...items]; + for (let i = copy.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [copy[i], copy[j]] = [copy[j], copy[i]]; + } + return copy; +} + function openWikipediaPage(page) { if (page && page !== "-") window.open(wikipediaUrl(page), "_blank"); } @@ -97,6 +143,189 @@ function debounce(fn, wait) { }; } +// Title suggestions under one route field: the ARIA combobox pattern, with +// the input keeping focus and the active option named by +// aria-activedescendant. Picking an option fills the field exactly, so the +// search starts from a real title instead of a guess. +class Autocomplete { + constructor(input, list, { onPick, isEnd }) { + this.input = input; + this.list = list; + this.onPick = onPick; + this.isEnd = isEnd; + this.options = []; + this.active = -1; + this.timer = null; + this.controller = null; + this.cache = new Map(); + + input.addEventListener("input", () => this.schedule()); + input.addEventListener("keydown", (e) => this.onKey(e)); + // iOS Safari can blur the input before a tapped option's click lands, + // so closing waits a beat; focus coming back cancels it. + input.addEventListener("blur", () => { + this.blurTimer = setTimeout(() => this.close(), 150); + }); + input.addEventListener("focus", () => clearTimeout(this.blurTimer)); + // Keep focus in the input while an option is pressed + list.addEventListener("pointerdown", (e) => e.preventDefault()); + } + + schedule() { + clearTimeout(this.timer); + const query = this.input.value.trim(); + if (query.length < SUGGEST_MIN_CHARS) { + this.close(); + return; + } + this.timer = setTimeout(() => this.fetch(query), SUGGEST_DELAY_MS); + } + + async fetch(query) { + const key = query.toLowerCase(); + if (this.cache.has(key)) { + this.render(this.cache.get(key)); + return; + } + this.controller?.abort(); + this.controller = new AbortController(); + try { + const response = await fetch( + `${API_BASE}/api/suggest?q=${encodeURIComponent(query)}`, + { signal: this.controller.signal }, + ); + if (!response.ok) return; + const { titles } = await response.json(); + this.cache.set(key, titles); + // Typing moved on while this was in flight + if (this.input.value.trim().toLowerCase() !== key) return; + this.render(titles); + } catch { + /* suggestions are a convenience; the field still works without them */ + } + } + + render(titles) { + if (document.activeElement !== this.input) return; + // Nothing to add when the only match is what is already typed + const typed = this.input.value.trim(); + if (!titles.length || (titles.length === 1 && titles[0].title === typed)) { + this.close(); + return; + } + + this.options = titles; + this.active = -1; + this.list.replaceChildren( + ...titles.map((item, index) => { + const option = document.createElement("li"); + option.id = `${this.list.id}-${index}`; + option.className = "suggestion"; + option.setAttribute("role", "option"); + option.setAttribute("aria-selected", "false"); + + const title = document.createElement("span"); + title.className = "suggestion-title"; + title.textContent = item.title; + option.appendChild(title); + + const note = item.is_disambiguation + ? this.isEnd + ? "Disambiguation page: pick a specific article" + : "Disambiguation page" + : item.description; + if (note) { + const detail = document.createElement("span"); + detail.className = "suggestion-note"; + detail.textContent = note; + option.appendChild(detail); + } + option.classList.toggle( + "is-ambiguous", + Boolean(item.is_disambiguation && this.isEnd), + ); + + option.addEventListener("click", () => this.pick(index)); + return option; + }), + ); + this.list.classList.remove("hidden"); + this.input.setAttribute("aria-expanded", "true"); + } + + onKey(event) { + const open = !this.list.classList.contains("hidden"); + switch (event.key) { + case "ArrowDown": + case "ArrowUp": { + if (!open) { + this.schedule(); + return; + } + event.preventDefault(); + const step = event.key === "ArrowDown" ? 1 : -1; + const count = this.options.length; + // Positions run 0..count, where 0 is the typed text itself + const position = (this.active + 1 + step + count + 1) % (count + 1); + this.highlight(position - 1); + break; + } + case "Enter": + if (open && this.active >= 0) { + event.preventDefault(); + this.pick(this.active); + } else { + this.close(); + } + break; + case "Escape": + if (open) { + event.preventDefault(); + this.close(); + } + break; + case "Tab": + this.close(); + break; + } + } + + // -1 means back to what was typed, with no option active + highlight(index) { + this.active = index; + [...this.list.children].forEach((option, i) => { + option.setAttribute("aria-selected", String(i === index)); + }); + const current = this.list.children[index]; + if (current) { + this.input.setAttribute("aria-activedescendant", current.id); + current.scrollIntoView({ block: "nearest" }); + } else { + this.input.removeAttribute("aria-activedescendant"); + } + } + + pick(index) { + clearTimeout(this.blurTimer); + const item = this.options[index]; + if (!item) return; + this.input.value = item.title; + this.close(); + this.onPick(item); + } + + close() { + clearTimeout(this.timer); + this.controller?.abort(); + this.options = []; + this.active = -1; + this.list.classList.add("hidden"); + this.list.replaceChildren(); + this.input.setAttribute("aria-expanded", "false"); + this.input.removeAttribute("aria-activedescendant"); + } +} + // Turn any failure into what the visitor needs: what happened, which field // (if one is at fault), and what to try next. Server messages are shown only // when they are written for people; internal ones stay in the server logs. @@ -146,6 +375,13 @@ function describeFailure({ code, message, details }, route) { hint: "This is usually brief. Try again in a minute.", retry: true, }; + case "RATE_LIMITED": + return { + title: "Too many searches at once", + message: "Iris limits how many searches one visitor can start each minute.", + hint: "Wait a minute, then try again.", + retry: true, + }; case "TIMEOUT": return { title: "The search took too long", @@ -180,12 +416,64 @@ class PathFinderUI { this.taskStartTime = null; this.pollTimeoutId = null; this.abortController = null; + this.eventSource = null; + this.watchdogId = null; + // Bumped per rendered route, so late link-context replies for an older + // route are dropped instead of written into the new one + this.routeGeneration = 0; this.initializeGraph(); + this.setupAutocomplete(); + this.renderExamples(); this.setupEventListeners(); this.restoreStateFromStorage(); } + setupAutocomplete() { + const fields = [ + ["startPage", false], + ["endPage", true], + ]; + for (const [id, isEnd] of fields) { + new Autocomplete($(id), $(`${id}Suggestions`), { + isEnd, + onPick: () => { + $(id).removeAttribute("aria-invalid"); + this.saveCurrentState(); + this.updateButtonState(); + // Picking the start moves on to the end; picking the end is ready + if (!isEnd && !$("endPage").value.trim()) $("endPage").focus(); + }, + }); + } + } + + renderExamples() { + $("examplesList").replaceChildren( + ...shuffled(EXAMPLES) + .slice(0, EXAMPLES_SHOWN) + .map(([start, end]) => { + const button = document.createElement("button"); + button.type = "button"; + button.className = "example"; + button.textContent = `${start} → ${end}`; + button.addEventListener("click", () => this.runRoute(start, end)); + return button; + }), + ); + } + + runRoute(start, end) { + $("startPage").value = start; + $("endPage").value = end; + for (const id of ["startPage", "endPage"]) { + $(id).removeAttribute("aria-invalid"); + } + this.saveCurrentState(); + this.updateButtonState(); + this.findPath(); + } + initializeGraph() { const svg = d3.select("#graph"); svg.selectAll("*").remove(); @@ -215,6 +503,13 @@ class PathFinderUI { $("clearBtn").addEventListener("click", () => this.clearVisualization()); $("retryBtn").addEventListener("click", () => this.findPath()); $("dismissBtn").addEventListener("click", () => this.hideNotice()); + $("shareBtn").addEventListener("click", () => this.shareRoute()); + $("surpriseBtn").addEventListener("click", () => { + const { start, end } = this.route(); + const choices = EXAMPLES.filter(([a, b]) => a !== start || b !== end); + const [a, b] = choices[Math.floor(Math.random() * choices.length)]; + this.runRoute(a, b); + }); for (const id of ["startPage", "endPage"]) { $(id).addEventListener("input", () => { @@ -236,6 +531,24 @@ class PathFinderUI { restoreStateFromStorage() { const saved = StateManager.load(); + const shared = sharedRoute(); + + // A shared link names its route; it wins over whatever this browser + // last did, unless that is the very same route already found. + if (shared) { + const path = saved?.result?.path; + $("startPage").value = shared.start; + $("endPage").value = shared.end; + if (path && path[0] === shared.start && path.at(-1) === shared.end) { + this.showVisualizationSection(); + this.handlePathFound(saved.result); + } else { + this.findPath(); + } + this.updateButtonState(); + return; + } + if (saved) { if (saved.startPage) $("startPage").value = saved.startPage; if (saved.endPage) $("endPage").value = saved.endPage; @@ -246,7 +559,7 @@ class PathFinderUI { this.taskStartTime = saved.taskStartTime || Date.now(); this.showVisualizationSection(); this.showLoading(); - this.pollTaskStatus(); + this.watchTask(); } else if (saved.result?.path) { this.showVisualizationSection(); this.handlePathFound(saved.result); @@ -286,6 +599,7 @@ class PathFinderUI { clearTimeout(this.pollTimeoutId); this.pollTimeoutId = null; } + this.closeStream(); // Abort any in-flight fetch requests if (this.abortController) { this.abortController.abort(); @@ -382,6 +696,7 @@ class PathFinderUI { // Reset depth. The real budget arrives with the first progress update; // until then keep whatever count is already rendered. this.updateDepthIndicator(0, $("depthDots").children.length || 6); + this.updateFrontiers({}); } setLastNode(title) { @@ -407,6 +722,49 @@ class PathFinderUI { progress.search_time_elapsed || 0, ); this.setLastNode(stats.last_node); + this.updateFrontiers(stats); + } + + // Each end's chip carries the pages that side read last, a count, and a + // fill along the line for how deep it has gone. The fills are measured + // against the whole depth budget, so two sides that meet touch mid-line. + updateFrontiers(stats) { + const frontier = stats.frontier || {}; + const maxDepth = stats.max_depth || $("depthDots").children.length || 6; + const forwardOnly = stats.algorithm === "bfs"; + + for (const [side, suffix] of [ + ["forward", "Forward"], + ["backward", "Backward"], + ]) { + const state = frontier[side]; + this.renderTrail($(`trail${suffix}`), state?.recent || []); + + let count = "Starting"; + if (state) { + count = `${plural(state.explored, "page")} · ${plural(state.depth, "link")} out`; + } else if (side === "backward" && forwardOnly) { + count = "Waiting to be reached"; + } else if (!stats.frontier) { + count = ""; + } + $(`count${suffix}`).textContent = count; + + const reach = Math.min(1, (state?.depth || 0) / maxDepth); + $(`reach${suffix}`).style.setProperty("--reach", reach.toFixed(3)); + } + } + + renderTrail(list, titles) { + const before = new Set([...list.children].map((li) => li.textContent)); + list.replaceChildren( + ...titles.map((title) => { + const item = document.createElement("li"); + item.textContent = title; + if (!before.has(title)) item.className = "is-new"; + return item; + }), + ); } updateDepthIndicator(currentDepth, maxDepth) { @@ -445,6 +803,12 @@ class PathFinderUI { async findPath() { const { start, end } = this.route(); + // A different route than the address bar names: stop advertising it + const shared = sharedRoute(); + if (shared && (shared.start !== start || shared.end !== end)) { + history.replaceState(null, "", "/"); + } + if (!start || !end) { this.showNotice({ title: "Enter both pages", @@ -489,27 +853,76 @@ class PathFinderUI { this.taskId = data.task_id; this.taskStartTime = Date.now(); this.saveCurrentState(); - this.pollTaskStatus(); + this.watchTask(); } catch (error) { if (error.name === "AbortError") return; this.fail({ code: "OFFLINE" }); } } - async pollTaskStatus(pollErrors = 0) { - // Capture the task this poll chain belongs to. After every await, a - // mismatch means a cancel or new search happened and this chain must - // die silently. + // Follow the task over Server-Sent Events, falling back to polling when + // the browser has no EventSource or the stream cannot be kept open. + watchTask() { + if (!this.taskId) return; + if (!("EventSource" in window)) { + this.pollTaskStatus(); + return; + } + const taskId = this.taskId; - if (!taskId) return; + const source = new EventSource(`${API_BASE}/tasks/stream/${taskId}`); + this.eventSource = source; + let errors = 0; + + // The stream only speaks when something changes, so the ten-minute + // limit needs its own clock. + this.watchdogId = setInterval(() => { + if (this.taskId === taskId) this.checkTimeout(); + }, 5000); + + source.onmessage = (event) => { + if (this.taskId !== taskId) return; + errors = 0; + this.handleStatus(JSON.parse(event.data)); + }; + // An error with the source still CONNECTING is the browser retrying by + // itself (it does after every stream the server rotates); CLOSED, or a + // run of failures, means the stream is not coming back. + source.onerror = () => { + if (this.taskId !== taskId) return; + errors += 1; + if (source.readyState === EventSource.CLOSED || errors >= MAX_POLL_ERRORS) { + this.closeStream(); + this.pollTaskStatus(); + } + }; + } + + closeStream() { + this.eventSource?.close(); + this.eventSource = null; + clearInterval(this.watchdogId); + this.watchdogId = null; + } + + checkTimeout() { if ( this.taskStartTime && Date.now() - this.taskStartTime > MAX_TASK_POLL_MS ) { this.fail({ code: "TIMEOUT" }); - return; + return true; } + return false; + } + + async pollTaskStatus(pollErrors = 0) { + // Capture the task this poll chain belongs to. After every await, a + // mismatch means a cancel or new search happened and this chain must + // die silently. + const taskId = this.taskId; + if (!taskId || this.checkTimeout()) return; const pollAgain = (delay, errors = 0) => { this.pollTimeoutId = setTimeout(() => this.pollTaskStatus(errors), delay); @@ -524,34 +937,8 @@ class PathFinderUI { const data = await response.json(); if (this.taskId !== taskId) return; - switch (data.status) { - case "PENDING": - // Waiting for a worker; the route is already on screen - this.showProgressLoader(); - pollAgain(1000); - break; - - case "IN_PROGRESS": - this.showProgressLoader(); - this.updateProgressDisplay(data.progress); - pollAgain(1000); - break; - - case "SUCCESS": - this.handlePathFound(data.result); - break; - - case "FAILURE": - this.fail({ code: data.code, message: data.error }); - break; - - case "REVOKED": - this.fail({ code: "STOPPED" }); - break; - - default: - this.fail({}); - } + this.handleStatus(data); + if (!TERMINAL.has(data.status)) pollAgain(1000); } catch (error) { if (error.name === "AbortError") return; // Stale chain — don't clobber the new search's UI @@ -567,6 +954,37 @@ class PathFinderUI { } } + // One status body, from the stream or a poll + handleStatus(data) { + switch (data.status) { + case "PENDING": + // Waiting for a worker; the route is already on screen + this.showProgressLoader(); + break; + + case "IN_PROGRESS": + this.showProgressLoader(); + this.updateProgressDisplay(data.progress); + break; + + case "SUCCESS": + this.closeStream(); + this.handlePathFound(data.result); + break; + + case "FAILURE": + this.fail({ code: data.code, message: data.error }); + break; + + case "REVOKED": + this.fail({ code: "STOPPED" }); + break; + + default: + this.fail({}); + } + } + handlePathFound(result) { this.hideLoading(); @@ -582,6 +1000,12 @@ class PathFinderUI { const path = result.path; this.setRoute(path[0], path[path.length - 1]); + // The address bar now names this route, ready to be copied or shared + try { + history.replaceState(null, "", shareUrl(path[0], path.at(-1))); + } catch { + /* some embedded browsers refuse history changes */ + } $("runState").dataset.state = "found"; $("runState").textContent = `Found in ${formatSeconds(result.search_time)}`; @@ -1048,6 +1472,7 @@ class PathFinderUI { } displayPathList(path, result) { + const meeting = result.search_stats?.meeting_page; const explored = result.search_stats?.nodes_explored || result.nodes_explored || 0; const hops = path.length - 1; @@ -1088,6 +1513,12 @@ class PathFinderUI { const title = document.createElement("span"); title.className = "step-title"; title.textContent = page; + if (page === meeting && index > 0 && index < path.length - 1) { + const tag = document.createElement("span"); + tag.className = "step-tag"; + tag.textContent = "Frontiers met"; + title.append(" ", tag); + } const open = document.createElementNS(SVG_NS, "svg"); open.setAttribute("class", "step-open"); @@ -1099,11 +1530,124 @@ class PathFinderUI { step.append(mark, number, title, open); item.appendChild(step); + + // The sentence that carries this page's link to the next one + if (index < path.length - 1) { + const context = document.createElement("p"); + context.className = "step-context is-loading"; + context.textContent = "Finding the link…"; + item.appendChild(context); + } return item; }), ); + const explain = this.explainRoute(path, result); + $("routeExplain").textContent = explain; + $("routeExplain").classList.toggle("hidden", !explain); + $("pathStepsContainer").classList.remove("hidden"); + this.loadLinkContexts(path); + } + + // Say what the two searches did, in a sentence + explainRoute(path, result) { + const stats = result.search_stats || {}; + const sides = stats.sides; + const meeting = stats.meeting_page; + if (!sides?.forward || !meeting || path.length < 2) return ""; + + const start = path[0]; + const end = path.at(-1); + const forward = sides.forward.explored || 0; + const backward = sides.backward?.explored || 0; + if (stats.algorithm === "bfs" || !backward) { + return `Searching forward from ${start}, Iris read ${plural(forward, "page")} before it reached ${end}.`; + } + + const fromStart = path.indexOf(meeting); + const where = + fromStart <= 0 || fromStart >= path.length - 1 + ? `The two searches met at ${meeting}.` + : `The two searches met at ${meeting}, ${plural(fromStart, "link")} from the start.`; + return `Iris read ${plural(forward, "page")} forward from ${start} and ${plural(backward, "page")} backward from ${end}. ${where}`; + } + + loadLinkContexts(path) { + const generation = ++this.routeGeneration; + const contexts = $("pathSteps").querySelectorAll(".step-context"); + + path.slice(0, -1).forEach(async (source, index) => { + const element = contexts[index]; + const target = path[index + 1]; + try { + const query = new URLSearchParams({ from: source, to: target }); + const response = await fetch(`${API_BASE}/api/context?${query}`); + if (!response.ok) throw new Error(`HTTP ${response.status}`); + const context = await response.json(); + if (generation !== this.routeGeneration) return; + this.renderLinkContext(element, context); + } catch { + if (generation === this.routeGeneration) element.remove(); + } + }); + } + + renderLinkContext(element, context) { + element.classList.remove("is-loading"); + if (context.where !== "prose") { + element.classList.add("is-structural"); + element.textContent = + context.where === "template" + ? "Linked from an infobox, table or template on this page." + : "Linked from a navigation box or template on this page."; + return; + } + + const link = document.createElement("span"); + link.className = "step-context-link"; + link.textContent = context.link; + const quote = document.createElement("q"); + quote.append(context.before, link, context.after); + element.replaceChildren(quote); + + if (context.section) { + const section = document.createElement("span"); + section.className = "step-context-section"; + section.textContent = context.section; + element.append(" ", section); + } + } + + async shareRoute() { + const start = $("routeFrom").textContent; + const end = $("routeTo").textContent; + const url = shareUrl(start, end); + const touch = window.matchMedia("(pointer: coarse)").matches; + + // Phones get the system share sheet; desktops copy the link + if (touch && navigator.share) { + try { + await navigator.share({ title: `${start} → ${end} · Iris`, url }); + } catch { + /* dismissed */ + } + return; + } + + try { + await navigator.clipboard.writeText(url); + } catch { + window.prompt("Copy this link", url); + return; + } + $("shareLabel").textContent = "Link copied"; + $("shareStatus").textContent = `Link to ${start} → ${end} copied`; + clearTimeout(this.shareTimer); + this.shareTimer = setTimeout(() => { + $("shareLabel").textContent = "Copy link"; + $("shareStatus").textContent = ""; + }, 2000); } async cancelSearch() { @@ -1130,6 +1674,8 @@ class PathFinderUI { $("pathStepsContainer").classList.add("hidden"); $("visualizationSection").classList.remove("show"); + this.routeGeneration++; + history.replaceState(null, "", "/"); this.graph.svg.selectAll("*").remove(); this.graph.simulation?.stop(); this.graph.simulation = null; diff --git a/static/site.webmanifest b/static/site.webmanifest new file mode 100644 index 0000000..81a788a --- /dev/null +++ b/static/site.webmanifest @@ -0,0 +1,13 @@ +{ + "name": "Iris: Wikipedia Path Finder", + "short_name": "Iris", + "description": "Find a hyperlink path between any two Wikipedia pages.", + "start_url": "/", + "display": "standalone", + "background_color": "#0d1117", + "theme_color": "#0d1117", + "icons": [ + { "src": "/static/icon-192.png", "sizes": "192x192", "type": "image/png", "purpose": "any maskable" }, + { "src": "/static/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any maskable" } + ] +} diff --git a/static/styles.css b/static/styles.css index 883bc27..3f2e6f4 100644 --- a/static/styles.css +++ b/static/styles.css @@ -90,6 +90,15 @@ a { border-radius: 2px; } +.sr-only { + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + clip-path: inset(50%); + white-space: nowrap; +} + .skip-link { position: absolute; left: var(--sp-4); @@ -171,6 +180,14 @@ a { text-wrap: balance; } +/* 404: the code is a reading, so it takes the reading face */ +.lost-code { + margin-bottom: var(--sp-3); + font-size: var(--fs-reading); + font-weight: 500; + color: var(--danger-ink); +} + .lead-copy { margin-top: var(--sp-5); max-width: var(--measure); @@ -254,6 +271,10 @@ a { column-gap: var(--sp-6); } +.field { + position: relative; +} + .field label { display: inline-flex; align-items: center; @@ -322,6 +343,62 @@ a { box-shadow: 0 1px 0 var(--danger-red); } +/* Title suggestions float over the page like the graph tooltip: the one + raised, shadowed surface, because it sits above whatever is below it. */ +.suggestions { + position: absolute; + z-index: 20; + top: 100%; + left: 0; + right: 0; + max-height: min(360px, 60vh); + overflow-y: auto; + list-style: none; + border: 1px solid var(--rule-strong); + border-top: 0; + background: var(--bg-secondary); + box-shadow: 0 8px 24px rgba(1, 4, 9, 0.6); +} + +.suggestion { + display: flex; + flex-direction: column; + justify-content: center; + min-height: 44px; + padding: var(--sp-2) var(--sp-3); + border-top: 1px solid var(--rule); + cursor: pointer; +} + +.suggestion:first-child { + border-top: 0; +} + +.suggestion-title { + font-size: var(--fs-body); + font-weight: 500; + overflow-wrap: anywhere; +} + +.suggestion-note { + font-size: var(--fs-label); + color: var(--text-tertiary); + overflow-wrap: anywhere; +} + +.suggestion[aria-selected="true"], +.suggestion:hover { + background: var(--bg-tertiary); +} + +.suggestion[aria-selected="true"] .suggestion-title { + color: var(--accent-blue); +} + +.suggestion.is-ambiguous .suggestion-title { + color: var(--text-secondary); +} + .route-arrow { width: 22px; height: 22px; @@ -340,6 +417,44 @@ a { margin-top: var(--sp-6); } +/* Example routes: in-text actions, so Path Blue like "How it works" */ +.examples { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0 var(--sp-4); + margin-top: var(--sp-3); + font-size: var(--fs-small); + color: var(--text-tertiary); +} + +.examples-list { + display: contents; +} + +.example, +.examples-surprise { + min-height: 44px; + border: 0; + background: none; + font: inherit; + color: var(--accent-blue); + text-align: left; + cursor: pointer; + transition: color 0.15s ease; +} + +.example:hover, +.examples-surprise:hover { + color: var(--accent-blue-hover); + text-decoration: underline; + text-underline-offset: 3px; +} + +.examples-surprise { + color: var(--text-secondary); +} + /* --- Buttons ------------------------------------------------------------- */ .btn { @@ -355,6 +470,7 @@ a { font: inherit; font-size: 14px; font-weight: 600; + text-decoration: none; cursor: pointer; transition: background-color 0.15s ease, @@ -781,23 +897,36 @@ a { border-right-width: 1px; } -/* While searching the field shows only the two ends, joined by a line - that is still being drawn. */ +/* While searching, the field shows the two frontiers: each end with the + pages that side read last, joined by a line each side fills as it goes + deeper. The fills are scaled to the whole depth budget, so they meet. */ .wait { position: absolute; inset: 0; - display: flex; + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(64px, 320px) minmax(0, 1fr); align-items: center; - justify-content: center; gap: var(--sp-4); padding: var(--sp-10); } +.wait-side { + display: flex; + flex-direction: column; + align-items: flex-end; + gap: var(--sp-2); + min-width: 0; +} + +.wait-side.to { + align-items: flex-start; +} + .wait-end { display: inline-flex; align-items: center; gap: var(--sp-2); - max-width: 30%; + max-width: 100%; padding: var(--sp-1) var(--sp-3); border: 1px solid var(--rule-strong); border-radius: 4px; @@ -822,10 +951,52 @@ a { background: var(--danger-red); } +/* Newest first, fading with age */ +.wait-trail { + list-style: none; + display: flex; + flex-direction: column; + align-items: inherit; + max-width: 100%; + min-height: calc(6 * 20px); + font-size: var(--fs-label); + line-height: 20px; + color: var(--text-secondary); +} + +.wait-trail li { + max-width: 100%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.wait-trail li:nth-child(2) { opacity: 0.8; } +.wait-trail li:nth-child(3) { opacity: 0.65; } +.wait-trail li:nth-child(4) { opacity: 0.5; } +.wait-trail li:nth-child(5) { opacity: 0.38; } +.wait-trail li:nth-child(6) { opacity: 0.26; } + +.wait-trail li.is-new:first-child { + color: var(--text-primary); + animation: trail-in 0.3s var(--ease-out); +} + +@keyframes trail-in { + from { + opacity: 0; + transform: translateY(-4px); + } +} + +.wait-count { + min-height: 20px; + font-size: var(--fs-label); + color: var(--text-tertiary); +} + .wait-line { position: relative; - flex: 1; - max-width: 320px; height: 1px; background-image: linear-gradient( 90deg, @@ -836,7 +1007,24 @@ a { overflow: clip; } -.wait-line span { +.wait-reach { + position: absolute; + top: 0; + bottom: 0; + width: calc(var(--reach, 0) * 100%); + background: var(--accent-blue); + transition: width 0.5s var(--ease-out); +} + +.wait-reach.from { + left: 0; +} + +.wait-reach.to { + right: 0; +} + +.wait-sweep { position: absolute; inset: 0; width: 30%; @@ -863,6 +1051,28 @@ a { margin-top: var(--sp-10); } +.route-list-head { + display: flex; + align-items: center; + justify-content: space-between; + gap: var(--sp-4); +} + +.share-btn { + gap: var(--sp-2); + margin-right: calc(-1 * var(--sp-3)); +} + +.share-btn svg { + width: 16px; + height: 16px; + fill: none; + stroke: currentColor; + stroke-width: 1.6; + stroke-linecap: round; + stroke-linejoin: round; +} + .route-list-title { font-size: 16px; font-weight: 600; @@ -875,6 +1085,14 @@ a { color: var(--text-secondary); } +.route-explain { + margin-top: var(--sp-2); + max-width: var(--measure); + font-size: var(--fs-small); + color: var(--text-secondary); + text-wrap: pretty; +} + .route-summary span + span::before { content: "·"; margin: 0 var(--sp-2); @@ -912,8 +1130,10 @@ a { opacity: 0.45; } +/* From the first mark, which sits mid-row: a step can be taller than its + row once its link context is below it, so 50% of the item would miss. */ .steps li:first-child::before { - top: 50%; + top: 26px; } .steps li:last-child::before { @@ -983,6 +1203,58 @@ a { border-radius: 0; } +.step-tag { + font-size: var(--fs-label); + font-weight: 400; + color: var(--text-tertiary); + white-space: nowrap; +} + +.step-tag::before { + content: "·"; + margin-right: var(--sp-2); +} + +/* The sentence linking a step to the next, hung under its title */ +.step-context { + max-width: var(--measure); + margin: calc(-1 * var(--sp-1)) 0 0 calc(9px + 36px + 2 * var(--sp-3)); + padding-bottom: var(--sp-3); + font-size: var(--fs-small); + line-height: 1.6; + color: var(--text-secondary); + overflow-wrap: anywhere; + animation: context-in 0.3s var(--ease-out); +} + +.step-context.is-loading, +.step-context.is-structural { + color: var(--text-tertiary); +} + +.step-context q { + quotes: "“" "”"; +} + +.step-context-link { + color: var(--accent-blue); +} + +.step-context-section { + color: var(--text-tertiary); + white-space: nowrap; +} + +.step-context-section::before { + content: "— "; +} + +@keyframes context-in { + from { + opacity: 0; + } +} + /* --- Colophon ------------------------------------------------------------ */ .colophon { @@ -1168,18 +1440,40 @@ a { } .wait { - flex-direction: column; + grid-template-columns: minmax(0, 1fr); + grid-template-rows: auto 56px auto; + justify-items: center; + align-content: center; + gap: var(--sp-3); padding: var(--sp-6); } - .wait-end { + .wait-side, + .wait-side.to { + align-items: center; max-width: 100%; } + /* The end reads bottom-up, so its newest page sits nearest the line */ + .wait-side.to { + flex-direction: column-reverse; + } + + .wait-trail { + min-height: calc(3 * 20px); + } + + .wait-side.to .wait-trail { + flex-direction: column-reverse; + } + + .wait-trail li:nth-child(n + 4) { + display: none; + } + .wait-line { - flex: none; width: 1px; - height: 72px; + height: 100%; background-image: linear-gradient( 180deg, var(--rule-strong) 50%, @@ -1188,7 +1482,25 @@ a { background-size: 1px 8px; } - .wait-line span { + .wait-reach { + left: 0; + right: 0; + width: auto; + height: calc(var(--reach, 0) * 100%); + transition-property: height; + } + + .wait-reach.from { + top: 0; + bottom: auto; + } + + .wait-reach.to { + top: auto; + bottom: 0; + } + + .wait-sweep { width: 100%; height: 30%; background: linear-gradient( @@ -1238,7 +1550,7 @@ a { /* Searching must stay perceivable: swap travel for a slow fade instead of freezing it, which reads as broken. */ .activity-fill, - .wait-line span { + .wait-sweep { width: 100% !important; height: 100% !important; transform: none !important; diff --git a/tests/conftest.py b/tests/conftest.py index 0632b7a..7ac730b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -17,7 +17,8 @@ from app import Services, celery, create_app from app.config import Settings from app.store import RedisStore -from app.wikipedia import PageFetched, PageStatus +from app.wikipedia import PageFetched, PageStatus, Suggestion +from app.wikitext import LinkContext # A small, deliberately asymmetric graph. # @@ -78,6 +79,25 @@ def page_status(self, title: str) -> PageStatus: is_disambiguation=resolved in DISAMBIGUATION_PAGES, ) + def suggest(self, prefix: str) -> list[Suggestion]: + titles = sorted([*self.graph, *DISAMBIGUATION_PAGES]) + return [ + Suggestion( + title=title, + description="", + is_disambiguation=title in DISAMBIGUATION_PAGES, + ) + for title in titles + if title.casefold().startswith(prefix.casefold()) + ] + + def link_context(self, source: str, target: str) -> LinkContext: + if target not in self.graph.get(source, []): + return LinkContext(where="elsewhere") + return LinkContext( + where="prose", before=f"{source} relates to ", link=target, after="." + ) + @staticmethod def _respond( found: dict[str, list[str]], on_page: PageFetched | None diff --git a/tests/test_api.py b/tests/test_api.py index bf4f1f8..e3e433d 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -6,6 +6,8 @@ from __future__ import annotations +import json +from dataclasses import replace from unittest.mock import patch import pytest @@ -61,6 +63,36 @@ def test_rejects_a_body_that_is_not_json(client): assert response.status_code == 400 +def use_settings(app, **changes): + current = app.extensions["iris"] + app.extensions["iris"] = replace( + current, settings=replace(current.settings, **changes) + ) + + +def test_limits_how_many_searches_one_client_starts(app, client): + use_settings(app, search_rate_limit=2) + + statuses = [search(client).status_code for _ in range(3)] + + assert statuses == [202, 202, 429] + refused = search(client) + assert refused.get_json()["code"] == "RATE_LIMITED" + assert 0 < int(refused.headers["Retry-After"]) <= 60 + + +def test_rate_limits_are_per_client(app, client): + use_settings(app, search_rate_limit=1) + + assert search(client).status_code == 202 + other = client.post( + "/getPath", + json={"start": "Python", "end": "Mathematics"}, + environ_base={"REMOTE_ADDR": "10.0.0.2"}, + ) + assert other.status_code == 202 + + # --- Polling -------------------------------------------------------------- # # The status endpoint is a translation layer over Celery's task states. Driving @@ -164,6 +196,57 @@ def test_a_revoked_task_is_reported_as_revoked(client, task_state): assert client.get(f"/tasks/status/{TASK_ID}").get_json()["status"] == "REVOKED" +# --- Streaming ------------------------------------------------------------ + + +def events(response) -> list[dict]: + return [ + json.loads(line.removeprefix("data: ")) + for line in response.get_data(as_text=True).splitlines() + if line.startswith("data: ") + ] + + +def test_streams_status_changes_until_the_search_ends(app, client, monkeypatch): + use_settings(app, stream_interval=0) + progress = {"search_stats": {"nodes_explored": 3}} + states = iter( + [ + StubResult("PENDING"), + StubResult("PROGRESS", info=progress), + StubResult("PROGRESS", info=progress), + StubResult("SUCCESS", result={"status": "SUCCESS", "path": ["A", "B"]}), + ] + ) + monkeypatch.setattr( + "app.routes.find_path_task.AsyncResult", lambda _id: next(states) + ) + + response = client.get(f"/tasks/stream/{TASK_ID}") + + assert response.mimetype == "text/event-stream" + assert [e["status"] for e in events(response)] == [ + "PENDING", + "IN_PROGRESS", + "SUCCESS", + ], "an unchanged status is not sent twice" + assert events(response)[-1]["result"]["path"] == ["A", "B"] + + +def test_a_stream_closes_after_its_time_limit(app, client, task_state): + use_settings(app, stream_interval=0, stream_max_seconds=0) + task_state(state="PENDING") + + response = client.get(f"/tasks/stream/{TASK_ID}") + + assert [e["status"] for e in events(response)] == ["PENDING"] + assert response.get_data(as_text=True).startswith("retry: ") + + +def test_streaming_a_malformed_task_id_is_a_404(client): + assert client.get("/tasks/stream/not-a-uuid").status_code == 404 + + def test_rejects_a_malformed_task_id(client): response = client.get("/tasks/status/not-a-uuid") @@ -207,6 +290,101 @@ def test_cancelling_a_malformed_task_id_is_a_404(client): assert client.delete("/tasks/not-a-uuid").status_code == 404 +# --- Suggestions and link context --------------------------------------- + + +def test_suggests_titles_for_a_prefix(client): + body = client.get("/api/suggest?q=mer").get_json() + + assert body["query"] == "mer" + assert body["titles"] == [ + {"title": "Mercury", "description": "", "is_disambiguation": True} + ] + + +def test_an_empty_suggestion_query_returns_nothing(client): + assert client.get("/api/suggest?q=").get_json()["titles"] == [] + + +def test_explains_a_step_with_the_sentence_that_links_it(client): + body = client.get("/api/context?from=Python&to=Programming").get_json() + + assert body["from"] == "Python" + assert body["to"] == "Programming" + assert body["where"] == "prose" + assert body["before"] + body["link"] + body["after"] == ( + "Python relates to Programming." + ) + + +def test_context_needs_both_ends(client): + response = client.get("/api/context?from=Python") + + assert response.status_code == 400 + assert response.get_json()["code"] == "INVALID_REQUEST" + + +def test_lighter_endpoints_share_their_own_rate_limit(app, client): + use_settings(app, api_rate_limit=1) + + assert client.get("/api/suggest?q=py").status_code == 200 + assert client.get("/api/suggest?q=py").status_code == 429 + assert search(client).status_code == 202, "searches are counted separately" + + +# --- Sharing ---------------------------------------------------------------- + +PNG = b"\x89PNG\r\n\x1a\n" + + +def test_draws_a_share_image_for_a_found_route(client, store): + store.set("route:Python:Mathematics", ["Python", "Monty Python", "Mathematics"]) + + response = client.get("/api/og.png?from=Python&to=Mathematics") + + assert response.status_code == 200 + assert response.mimetype == "image/png" + assert response.data.startswith(PNG) + assert "max-age=86400" in response.headers["Cache-Control"] + + +def test_draws_a_share_image_for_a_route_not_yet_found(client): + response = client.get("/api/og.png?from=Python&to=Orphan") + + assert response.data.startswith(PNG) + assert "max-age=300" in response.headers["Cache-Control"], "may be found soon" + + +def test_a_shared_link_unfurls_into_its_own_route(client, store): + store.set("route:Python:Mathematics", ["Python", "Monty Python", "Mathematics"]) + + page = client.get("/?from=Python&to=Mathematics").get_data(as_text=True) + + assert "Python → Mathematics in 2 links · Iris" in page + assert ( + 'property="og:image" content="http://localhost/api/og.png?from=Python&to=Mathematics"' + in page + ) + assert "Python → Monty Python → Mathematics" in page + + +def test_share_tags_escape_what_the_link_carries(client): + page = client.get('/?from=x&to=a"b').get_data(as_text=True) + + assert "x" not in page + assert "<i>x</i>" in page + assert "a"b" in page + + +def test_share_previews_use_the_public_scheme_behind_a_proxy(client): + page = client.get( + "/?from=Python&to=Mathematics", + headers={"X-Forwarded-Proto": "https", "X-Forwarded-Host": "iris.example"}, + ).get_data(as_text=True) + + assert 'content="https://iris.example/api/og.png?' in page + + # --- System --------------------------------------------------------------- @@ -239,11 +417,38 @@ def test_serves_the_ui_at_the_root(client): assert b"= len(result.path) - 1 + ) + + +def test_plain_bfs_meets_at_the_target_with_no_backward_side(finder): + result = finder.find("Python", "Mathematics", BFS) + + assert result.meeting == "Mathematics" + assert set(result.sides) == {"forward"} + assert result.sides["forward"]["explored"] == result.nodes_explored + + +def test_progress_names_the_side_that_read_each_page(wikipedia, store, settings): + seen: list[Progress] = [] + PathFinder(wikipedia, store, settings, seen.append).find( + "Python", "Mathematics", BIDIRECTIONAL + ) + + forward = {p.last_node for p in seen if p.side == "forward"} + backward = {p.last_node for p in seen if p.side == "backward"} + assert "Python" in forward and "Python" not in backward + assert "Mathematics" in backward and "Mathematics" not in forward + assert seen[-1].sides["forward"]["explored"] + seen[-1].sides["backward"][ + "explored" + ] == len(seen) diff --git a/tests/test_tasks.py b/tests/test_tasks.py index 4e6b8fc..d1523f6 100644 --- a/tests/test_tasks.py +++ b/tests/test_tasks.py @@ -78,6 +78,38 @@ def test_publishes_progress_while_searching(app): assert "max_depth" in meta["search_stats"] +def test_progress_shows_each_frontier_and_the_pages_it_read_last(app): + with patch.object(find_path_task, "update_state") as update_state: + find_path_task.apply(args=("Python", "Mathematics", BIDIRECTIONAL)) + + frontiers = [ + call.kwargs["meta"]["search_stats"]["frontier"] + for call in update_state.call_args_list + if "frontier" in call.kwargs["meta"]["search_stats"] + ] + last = frontiers[-1] + + assert set(last) == {"forward", "backward"} + assert last["forward"]["recent"][-1] == "Python", "oldest read is the start" + assert last["backward"]["recent"][-1] == "Mathematics" + assert all(side["explored"] >= 1 for side in last.values()) + assert all(len(side["recent"]) <= 6 for f in frontiers for side in f.values()) + + +def test_the_result_says_where_the_frontiers_met(app): + result = run() + stats = result["search_stats"] + + assert stats["algorithm"] == BIDIRECTIONAL + assert stats["meeting_page"] in result["path"][1:-1] + assert set(stats["sides"]) == {"forward", "backward"} + + +def test_a_found_route_is_kept_for_shared_links(app, store): + path = run()["path"] + assert store.get("route:Python:Mathematics") == path + + # --- Caching -------------------------------------------------------------- diff --git a/tests/test_wikipedia.py b/tests/test_wikipedia.py index 3a2a01d..c022db8 100644 --- a/tests/test_wikipedia.py +++ b/tests/test_wikipedia.py @@ -398,3 +398,117 @@ def test_spaces_requests_by_the_configured_delay(monkeypatch): client._await_rate_slot() assert waits and waits[0] > 0, "the second call must wait out the interval" + + +# --- Hubs ------------------------------------------------------------------- + + +def test_hub_link_lists_are_cached_for_longer(store): + settings = Settings( + env="testing", + secret_key="test", + wikipedia_request_delay=0, + hub_link_threshold=3, + links_cache_ttl=100, + hub_cache_ttl=10_000, + ) + session = FakeSession( + FakeResponse(links_payload("Hub", ["A", "B", "C"])), + FakeResponse(links_payload("Leaf", ["A"])), + ) + client = build(settings, session, cache=store) + + client.links(["Hub"]) + client.links(["Leaf"]) + + raw = store._redis + assert raw.ttl("wiki_links:Hub") > 100 + assert raw.ttl("wiki_links:Leaf") <= 100 + + +# --- Suggestions -------------------------------------------------------------- + + +def suggest_payload(*pages: dict) -> dict: + return {"query": {"pages": list(pages)}} + + +def test_suggests_titles_in_rank_order_with_descriptions(settings): + session = FakeSession( + FakeResponse( + suggest_payload( + {"title": "Shah Rukh", "index": 2, "description": "Timurid ruler"}, + {"title": "Shah Rukh Khan", "index": 1, "description": "Actor"}, + {"title": "Shah", "index": 3, "pageprops": {"disambiguation": ""}}, + ) + ) + ) + + found = build(settings, session).suggest("shah ru") + + assert [s.title for s in found] == ["Shah Rukh Khan", "Shah Rukh", "Shah"] + assert found[0].description == "Actor" + assert [s.is_disambiguation for s in found] == [False, False, True] + assert session.requests[0]["gpssearch"] == "shah ru" + + +def test_two_prefixes_redirecting_to_one_article_appear_once(settings): + session = FakeSession( + FakeResponse( + suggest_payload( + {"title": "United States", "index": 1}, + {"title": "United States", "index": 4}, + ) + ) + ) + assert len(build(settings, session).suggest("us")) == 1 + + +def test_caches_suggestions_case_insensitively(settings, store): + session = FakeSession(FakeResponse(suggest_payload({"title": "Banana"}))) + client = build(settings, session, cache=store) + + client.suggest("Ban") + client.suggest("ban") + + assert len(session.requests) == 1 + + +def test_an_empty_prefix_asks_nothing(settings): + session = FakeSession() + assert build(settings, session).suggest(" ") == [] + assert session.requests == [] + + +# --- Link context ------------------------------------------------------------- + + +def wikitext_payload(text: str) -> dict: + return { + "query": { + "pages": [ + {"title": "A", "revisions": [{"slots": {"main": {"content": text}}}]} + ] + } + } + + +def test_link_context_reads_the_article_wikitext(settings, store): + session = FakeSession(FakeResponse(wikitext_payload("A links to [[B]] here."))) + client = build(settings, session, cache=store) + + context = client.link_context("A", "B") + again = client.link_context("A", "B") + + assert (context.before, context.link, context.after) == ( + "A links to ", + "B", + " here.", + ) + assert again == context + assert len(session.requests) == 1, "the second lookup comes from the cache" + + +def test_link_context_of_a_missing_article_is_elsewhere(settings): + session = FakeSession(FakeResponse({"query": {"pages": [{"missing": True}]}})) + assert build(settings, session).link_context("Gone", "B").where == "elsewhere" diff --git a/tests/test_wikitext.py b/tests/test_wikitext.py new file mode 100644 index 0000000..67b6109 --- /dev/null +++ b/tests/test_wikitext.py @@ -0,0 +1,92 @@ +"""Finding the sentence that carries a link, from raw wikitext.""" + +from __future__ import annotations + +from app.wikitext import MAX_SENTENCE, find_link_context + +ARTICLE = """{{Short description|Edible fruit}} +{{Infobox plant +| name = Banana +| region = [[Southeast Asia]] +}} +A '''banana''' is an elongated, edible [[fruit]].{{cite web|title=x}} \ +It is grown in [[India|the Indian subcontinent]] and elsewhere. Bananas vary in size. + +== Taxonomy == +Linnaeus named [[Musa (genus)|''Musa'']] and placed [[plantain]]s in it. + +{| class="wikitable" +| [[Kerala]] || yields +|} +""" + + +def sentence(context) -> str: + return context.before + context.link + context.after + + +def test_finds_the_sentence_and_marks_the_linked_words(): + context = find_link_context(ARTICLE, "Fruit") + + assert context.where == "prose" + assert context.link == "fruit" + assert sentence(context) == "A banana is an elongated, edible fruit." + assert context.section is None + + +def test_a_piped_link_marks_the_words_shown_not_the_title(): + context = find_link_context(ARTICLE, "India") + + assert context.link == "the Indian subcontinent" + assert sentence(context) == ( + "It is grown in the Indian subcontinent and elsewhere." + ) + + +def test_letters_trailing_a_link_belong_to_it(): + assert find_link_context(ARTICLE, "Plantain").link == "plantains" + + +def test_reports_the_section_the_sentence_sits_in(): + context = find_link_context(ARTICLE, "Musa (genus)") + + assert context.section == "Taxonomy" + assert context.link == "Musa" + assert "