Files
offlineu/README.md
T
rmsitzandClaude Sonnet 5 01a965c0f1 Rewrite README as internal deployment/reference documentation
Replace the original upstream template README (public-project framing,
roadmap items already built, links to a different GitHub repo) with
documentation matching the actual private deployment: real
docker-compose.yml, the Gitea->Dockhand rebuild-on-push behavior, env
vars/CLI flags, data file locations, and the full current feature set
(theming, notes hub, video duration/ffprobe caching, backup export,
Outline integration) that had never been documented.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-23 22:30:00 -04:00

7.1 KiB

OfflineU

Self-hosted course viewer for a local video/audio/text training library. Runs as a single Flask app in Docker, tracks watch progress and notes per lesson, and gives the whole library a dashboard-style home page instead of a bare file browser.

This is a personal deployment, not a public project — this doc is internal reference for running/maintaining it, not a pitch.

Lesson view Screenshot predates the current theming/icon work — kept for a rough idea of layout, not pixel-accurate.


Deployment

Deployed via docker-compose.yml, built directly from the Dockerfile in this repo (pull_policy: build, not a registry pull):

services:
  offlineu:
    build: .
    pull_policy: build
    container_name: offlineu
    network_mode: host
    ports:
      - "5000:5000"
    environment:
      - PUID=1000
      - PGID=10
      - TZ=America/New_York
      - FLASK_ENV=production
    volumes:
      - /volume1/files/training:/app/courses   # course library
      - /volume2/docker/offlineu/data:/app/data # settings/progress/notes
    restart: unless-stopped

Auto-deploy: the Gitea repo has a webhook to Dockhand — a push to main triggers a full image rebuild from the Dockerfile (confirmed, not just a container restart), so Dockerfile changes (e.g. adding ffmpeg) take effect on the very next push without any manual step.


Local development

pip install -r requirements.txt
python offlineu_core.py --library-path /path/to/courses --debug

Opens on http://127.0.0.1:5000. ffprobe (from ffmpeg) needs to be on PATH for video-duration lookups to work locally; without it those just silently stay blank instead of erroring.

CLI options

Option Description
--host Bind host (default 0.0.0.0)
--port Bind port (default 5000)
--debug Enable Flask debug mode
--create-templates Regenerate default templates if missing
--library-path Course library root (overrides COURSES_LIBRARY_PATH)
course_path (positional) Load a specific course directly at startup

Environment variables

Variable Default Purpose
COURSES_LIBRARY_PATH /app/courses Course library root
OFFLINEU_DATA_DIR /app/data Where settings/progress/notes data lives
AUTO_LOAD_COURSE Course path to load automatically on start

Features

Library browsing

  • Lazy-loading folder browser (grid or list view) with search, including an opt-in transcript search across subtitle files
  • Course cards show media file count, total video/audio runtime, and completion % at a glance
  • Hide courses/folders from the browser without touching anything on disk; bulk-select to hide or queue several at once
  • Bulk rename across course/folder names (find & replace)

Dashboard

  • Library-wide stats (courses, lessons completed, time watched, day streak) and a 90-day activity heatmap
  • Next Up queue (manually curated, reorderable)
  • Pick Back Up (courses with progress that have gone stale)
  • Recently Added / Recently Viewed
  • Surprise Me — random pick, weighted toward incomplete courses

Playback & progress

  • Video/audio player with resize, playback-speed presets, and resume-from- last-position
  • Auto-tracks watch progress and completion per lesson
  • Video/audio durations read via ffprobe and cached persistently per course (.offlineu_duration_cache.json), so total runtime and per-lesson length show up before you've ever pressed play — not just after
  • Settings → "Precompute Video Lengths" walks the whole library in the background to populate that cache up front, with live progress

Notes

  • Timestamped notes per lesson, capturable via a keyboard shortcut without leaving the player
  • Notes Hub: every note across the whole library, searchable, in one list
  • Per-course study guide export (markdown, organized by section)

Personalization (Settings)

  • Built-in themes or a custom accent color, corner radius, and card style
  • Font, text size, page width, and spacing density
  • Default library path override + manual "Refresh Library" (bypasses the 5-minute filesystem-scan cache)

Backup & integrations

  • One-click backup export: settings, hidden-path choices, recent-view history, and every course's progress/notes as a zip (not the course files themselves)
  • Optional Outline integration — push a lesson's notes to an Outline document/collection

Data files

Everything under OFFLINEU_DATA_DIR (app-wide, not tied to a course):

File Contents
settings.json Theme, layout, library path, etc.
hidden_paths.json Courses/folders curated out of the browser
next_up.json The Next Up queue, in order
recent_views.json Cross-course "Recently Viewed" history
outline_config.json Outline API token/collection mapping

Per-course, written inside the course's own folder on the library volume:

File Contents
.offlineu_progress.json Per-lesson completed/progress/duration/notes
.offlineu_duration_cache.json ffprobe duration cache, keyed by (path, size, mtime)

Folder structure example

MyCourse/
├── Section 1/
│   ├── 01 - Intro.mp4
│   ├── 02 - Setup Guide.pdf
│   └── 03 - Quiz.html
├── Section 2/
│   ├── 04 - Advanced Tips.mp4
│   └── resources/
│       └── extras.md
├── .offlineu_progress.json        ← created automatically
└── .offlineu_duration_cache.json  ← created automatically

No metadata files needed — course/section/lesson names come straight from folder and file names.

Supported file types

Type Extensions
Video .mp4 .mkv .avi .mov .webm .m4v .flv .wmv
Audio .mp3 .wav .m4a .aac .ogg .flac
Documents .txt .md .html .htm .pdf .docx .doc .rtf
Subtitles .srt .vtt .ass .sub .sbv
Quizzes Any doc file whose name contains quiz, exam, test, assessment, exercise, assignment, or homework