A self-serve workflow to browse Frigate camera detections, pick the good ones, crop them, and stage them to Google Drive for printing — entirely inside the “Top képek” picker. No more feeding timestamps to an agent: the user browses, jumps to a date/time, crops freeform at native resolution, and pushes finished JPEGs to Drive with one click.

SUPERSEDED by the community voting system (2026-08-10)

This Drive flow is superseded by the tailnet-only community voting system → 2026-08-10-top-kep-community-voting-system (/nap/het/honap, votes stored on the mainframe, NOT Drive). The weekly Drive export top4-export.timer is DISABLED. The Drive buttons/endpoints and bulk helpers documented below are left intact and still work — a full Drive rip-out is deferred until the user asks. The “Top képek” home-portal tile now points at …:8443/nap, not the old picker.

For Agents

This supersedes/extends the original top4 spec, which lived only in top4-web.py, service top4-web, ts serve :8443). Everything below runs on telep-mainframe. The picker tile is on the Top képek portal tile. Built across 2026-08-09/10. No secrets (Mi/token material) belong in this note — the Drive/rclone remote is referenced by name only.

Quick Reference

  • Picker: /home/levander/top4-web.py, systemd top4-web.service (User=levander), 127.0.0.1:8090https://telep-mainframe.taild4189d.ts.net:8443
  • Frigate API: http://127.0.0.1:5000
  • Curated (top): gdrive:top_képek/Archive (raw pile): gdrive:top_képek/archive/
  • Ready-to-print (by folder id): gdrive,root_folder_id=1wPBPJ3avEAXeIbKCu2clVtGULB_I3C5M:
  • Bulk helpers: ~/top-kep-drive.py "<YYYY-MM-DD HH:MM>" …, ~/top-kep-id.py <eventid> …
  • rclone config: --config /home/levander/.config/rclone/rclone.conf

The picker (top4-web.py)

The Flask picker behind the Top képek portal tile. Runs as top4-web.service (User=levander), binds 127.0.0.1:8090, exposed at https://telep-mainframe.taild4189d.ts.net:8443.

Enhanced this session with four things (the original 4-slot arm→crop→set flow is unchanged — see Unchanged: the original 4-slot flow).

Batched infinite scroll (was a hard bug)

The picker used to dump all ~1500 events into the DOM at once, each thumbnail being a live Frigate snapshot fetch → the page janked and Frigate got hammered on every load.

Fix: render 48 cards at a time via an IntersectionObserver watching a #sentinel element at the bottom of the list; scrolling near the sentinel appends the next batch. Frigate is now only asked for thumbnails as they scroll into view.

Jump-to-date/time filter

A text box with Ugrás (jump) and Most (now) buttons that accepts flexible input:

  • 2026-08-04 17:13
  • Aug 4 2026, 5:13 PM

Parsed client-side with new Date(), then it fetches a window around that instant and re-renders:

/events?from=<t-1800>&to=<t+7200>

i.e. 30 min before → 2 h after the target time. Server-side, the /events route now accepts optional from/to unix params; with neither, it falls back to the previous last-7-days default.

Save-to-Drive buttons

Two ways to push a picked frame to Drive, both landing in gdrive:top_képek/ (the curated top):

ControlEndpointWhat it saves
Per-card chipPOST /save-full-to-drive?id=<eventid>The clean full snapshot (bbox=0&quality=100), rclone’d to Drive
Crop-modal “Kivágás → Drive”POST /save-crop-to-drive?id=<eventid>The freeform crop box exported at NATIVE resolution

The crop exports at native res, NOT the camwall 880×495 letterbox

The 4-slot camwall flow letterboxes crops to exactly 880×495 (to keep the wall’s scale=880:495 filter unbreakable — see top4-web.py, service top4-web, ts serve :8443)). The Drive crop path deliberately does NOT do that — it exports the freeform box at the snapshot’s native pixel resolution so prints aren’t degraded by the wall’s letterbox downscale.

Unchanged: the original 4-slot flow

Still present and working: the arm→crop→set 4-slot flow (/set-slot, /set-slot-image, slot files at /srv/frigate/top4/{1..4}.jpg) and the weekly top4-export (Mon 08:00 → gdrive). See the original spec in top4-web.py, service top4-web, ts serve :8443).

Bulk helpers (run as levander on the box)

For when you want many frames at once rather than clicking through the UI.

  • ~/top-kep-drive.py "<YYYY-MM-DD HH:MM>" [more timestamps…] — for each timestamp, saves ALL person detections in a ±window (t-45s → t+75s), deduped to >3s apart per camera, dumped FLAT into gdrive:top_képek/archive/ named <date>_<time>_<cam>_<eventid>.jpg.
  • ~/top-kep-id.py <eventid> [more ids…] — saves the exact frames for given Frigate event ids → gdrive:top_képek/ (the curated top).

Drive structure (as reorganized this session)

  • gdrive:top_képek/ (top) = curated / exported picks, flat.
  • gdrive:top_képek/archive/ = flat raw candidate pile — all bulk-saved person shots + old weekly export sets. No month subfolders (the user explicitly wanted a flat pile, no date foldering).
  • Ready-to-print folder = referenced BY FOLDER ID, not by path:
    gdrive,root_folder_id=1wPBPJ3avEAXeIbKCu2clVtGULB_I3C5M:
    
    This is rclone connection-string syntax for “the gdrive remote, rooted at this Drive folder id”. Final picks get copied here for printing.

Frigate image facts

Snapshots are enabled (so bbox is drawable, and bbox=0 gives a clean frame). Relevant API on http://127.0.0.1:5000:

  • /api/events?after=<unix>&before=<unix>&has_snapshot=1 — list events in a window
  • /api/events/<id>/snapshot.jpg?bbox=0&quality=100 — clean full snapshot for an event
  • /api/events/<id> — event detail (has camera + start_time)

Resolution: the detect stream is 1280×720, so snapshots are 720p. Fine for 4×6 prints. For larger prints, extract from the record/main stream instead (noted as a future upgrade — the snapshot API can’t give you more than the detect stream carries).

Cameras (label focus = person):

Frigate camsLocationIPNote
telep_cam1 / telep_cam2DÉL (south)192.168.30.119two streams of the SAME physical camera
telep_cam3 / telep_cam4ÉSZAK (north)192.168.30.139two streams of the SAME physical camera

See RTSP stream map and Camera VLAN (telep-cc) for the fuller map.

Gotchas worth recording

1. The _0.95 "score" in filenames is confidence, NOT a unique id

The number like _0.95 is Frigate’s detection confidence (top_score), not a unique key. Two shots in the same window can share a score (ties) → this caused a picking-collision mess where the “id” pointed at the wrong frame. The TIME is the unique key. A NNN_ unique-numbering pass over the archive was started so picks can be referenced unambiguously by number.

2. Google Drive rate-limits HARD after bulk moves — run reorgs DETACHED

During the archive flatten/reorg, rclone moves degraded to ~18–60 s PER FILE. Lesson: run big rclone reorg / rename / flatten jobs detached and poll the log:

setsid nohup rclone move </dev/null &>/home/levander/reorg.log &

A timeout-wrapped SSH call will be killed mid-batch and only partially complete. Cleanup helpers: rclone rmdirs --leave-root (removes empty dirs) and rclone deletefile (removes exact files).

3. rclone folder-by-id (connection-string syntax)

Target a Drive folder by its URL id, reusing the existing gdrive remote + config:

rclone --config /home/levander/.config/rclone/rclone.conf \
  copy <src> "gdrive,root_folder_id=<FOLDER_ID>:"

The <remote>,<param>=<value>: form overrides remote params inline without editing rclone.conf.

4. Frigate has no native "add to top képek" button

Frigate’s React UI can’t be edited directly; adding a button there would need a userscript or an injecting proxy. Resolved by not touching Frigate at all — the picker’s jump-to-time filter plus the Drive buttons cover the same need self-serve.