Skip to content

aryalsujay/course_manager

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Course Manager

VCM sync dashboard. Two features:

  • Media Sync — copy course media from a NAS source folder into a local media/vcm-s destination, with selective course/instruction/discourse filtering and mirror/overwrite/update modes.
  • Tablet Sync — push a local media/vcm-s folder onto a connected Android tablet via adb-sync, plus device setup (orientation, DND, screen timeout) and wallpaper customization.

Quick Start

./start.sh

That's it — on a fresh machine or a stale clone, it self-bootstraps:

  1. Verifies Node ≥ 18, npm, and warns if adb / adb-sync are missing (needed for Tablet Sync only).
  2. Installs root + client node_modules if missing (with one retry on failure).
  3. Makes clone-tab/clone.sh executable and creates server/data/ for sync history.
  4. Checks ports 3001 and 5173. If in use, lists the offending process and prompts to kill it.
  5. Boots Express + Vite concurrently.

Flags:

./start.sh --clean     # wipe node_modules and reinstall (use if deps got weird)
./start.sh --no-deps   # skip dependency checks (fastest restart)
./start.sh --help

Server runs on http://localhost:3001, client on http://localhost:5173. Ctrl+C stops both — the server aborts any in-flight copy + tablet-sync subprocess before exiting.

Architecture

server/
├── index.js               bootstrap (express + socket.io)
├── config.js              ports, paths, sync modes, ignored files
├── state.js               shared singletons (abort controller, last dest)
├── routes/
│   ├── config.js          GET  /api/config
│   ├── structure.js       GET  /api/structure
│   ├── copy.js            POST /api/copy, /api/stop
│   └── tablet-sync.js     POST /api/tablet-sync/start|stop
├── services/
│   ├── task-builder.js    selections → copy task list
│   ├── mirror-cleanup.js  pre-copy destination pruning
│   └── copy-orchestrator.js  scan + cleanup + copy + emit progress
└── lib/
    ├── path-validator.js  whitelist allowed source/dest roots
    ├── find-source-root.js  picks first existing CANDIDATE_PATHS
    ├── copier.js          recursive copy + stream + smart-skip
    └── tablet-sync.js     spawns clone-tab/clone.sh

client/
└── src/
    ├── App.jsx            tabs (Media Sync / Tablet Sync)
    ├── feature/
    │   ├── SyncDashboard.jsx
    │   ├── TabletSync.jsx
    │   └── CopyProgress.jsx
    ├── hooks/
    │   ├── useSyncState.js  hook for the dashboard
    │   └── useConfig.js     fetches /api/config (once, cached)
    ├── lib/
    │   ├── languageCodes.js  ENG → English, plus auto-map helper
    │   └── utils.js          cn() — tailwind class merger
    └── components/ui/       Button, Badge, Card

clone-tab/clone.sh          adb settings + headless wallpaper + adb-sync

Configuration

All filesystem paths live in server/config.js:

  • SOURCE_PATHS — candidate NAS roots to scan
  • DESTINATION_PATHS — candidate local dest roots (dropdown in UI)
  • TABLET_SOURCE_PATHS — sources for the tablet-sync tab
  • ALLOWED_SOURCE_ROOTS / ALLOWED_DESTINATION_ROOTS — security whitelist; any path outside these is rejected before any FS operation

The client fetches this list from /api/config so dropdowns stay in sync with the server config without duplication.

API

Route Method Purpose
/api/config GET Static config (paths, modes)
/api/structure?sourcePath=&force= GET Scan source, return course tree (cached 10 min per sourcePath)
/api/copy POST Start copy. Body: { selections, destination, sourcePath, syncMode }
/api/stop POST Abort the current copy
/api/tablet-sync/start POST Run clone-tab/clone.sh. Body: { sourcePath, centerName, skipWallpaper }
/api/tablet-sync/stop POST SIGTERM the running clone.sh and its children

Socket.io events emitted server → client: log, progress, complete, stopped, tablet-log, tablet-complete.

Sync Modes

  • mirror (default) — pre-cleans dest to match selection, then copies. Files unique to dest (and not in source) are deleted.
  • overwrite — wipes dest entirely, then copies. Confirmation prompt in UI.
  • update — copies on top of dest, no cleanup. Smart-skip if size matches and source is not newer.

Tablet Sync

clone-tab/clone.sh does (in order): adb device check → date/time/orientation/timeout/DND/dev-options/lockscreen settings → wallpaper → adb-sync of media folder.

Wallpaper: uses headless cmd wallpaper set-from-file (Android 7+). Falls back to stdin-pipe, then the Gallery picker if both refuse.

To override the default wallpaper text, pass CENTER_NAME as env var (the server does this from the UI input) — the script invokes scripts/create_wallpaper.js to overlay text on pagoda.jpg.

Unrelated: VCM Media DB Generator

scripts/gen_all_updates.sh is a separate one-off SQL generator for the data2-<centre>.db SQLite DB used by the VCM Android app. It scans a media tree for valid instruction/discourse folders and calls gen-updates-v2 for each.

./scripts/gen_all_updates.sh --media-root /path/to/media --out /tmp/a.sql
./scripts/gen_all_updates.sh --dry-run     # preview which folders would be scanned

Requires gen-updates-v2 on PATH.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors