docs: rewrite README, add GitHub Actions CI
This commit is contained in:
parent
7ee8f14f3d
commit
0447acd6c5
38
.github/workflows/test.yml
vendored
Normal file
38
.github/workflows/test.yml
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
name: Test
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
js:
|
||||||
|
name: JavaScript (vitest)
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
cache: npm
|
||||||
|
- run: npm ci
|
||||||
|
- run: npm test
|
||||||
|
|
||||||
|
rust:
|
||||||
|
name: Rust (workspace)
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
|
with:
|
||||||
|
components: clippy rustfmt
|
||||||
|
- uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
workspaces: Rust->target backend->target ui->target
|
||||||
|
- name: Check
|
||||||
|
run: cargo check --workspace
|
||||||
|
- name: Clippy
|
||||||
|
run: cargo clippy --workspace --all-targets
|
||||||
|
- name: Test
|
||||||
|
run: cargo test --workspace
|
||||||
146
README.md
146
README.md
@ -1,30 +1,138 @@
|
|||||||
# MovieMapper
|
# MovieMapper
|
||||||
|
|
||||||
A desktop application for organizing and managing movie and TV show collections.
|
Desktop application for organizing and managing movie and TV show collections.
|
||||||
|
Scan media directories, extract metadata with FFmpeg, tag files as extras or
|
||||||
|
commentary, and move them into Jellyfin-compatible folder structures — with a
|
||||||
|
full audit trail.
|
||||||
|
|
||||||
|
[](https://github.com/actions/workflows/test.yml)
|
||||||
|
[](LICENSE)
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Browse and scan directories for media files
|
- **Directory scanning** — non-recursive folder browsing with real-time progress
|
||||||
- Search TV shows using TheTVDB API
|
- **Metadata extraction** — duration, video quality, and FPS via `ffprobe`
|
||||||
- View show details, seasons, and episodes
|
- **File tagging** — mark files as `extra` or `commentary` with visual state
|
||||||
- Rename files by clicking on the file name
|
- **Jellyfin-compatible moves** — tagged files move into spec-compliant folders
|
||||||
- Display video durations in mm:ss format
|
(`extras/`, `commentary/`, `behind the scenes/`, ...)
|
||||||
|
- **TheTVDB integration** — search shows, browse seasons/episodes, map episodes
|
||||||
|
to `SxxExx` naming convention
|
||||||
|
- **Audit logging** — every move/rename writes a `.audit` entry in the target
|
||||||
|
directory; nothing happens silently
|
||||||
|
- **Progress reporting** — IPC-driven progress updates during scans
|
||||||
|
|
||||||
## Installation
|
## Architecture
|
||||||
|
|
||||||
1. Clone the repository
|
Three implementations share the same core concepts (scanner → metadata →
|
||||||
2. Install dependencies: `npm install`
|
tagging → mapping → audit):
|
||||||
3. Run the application: `npm start` or `electron .`
|
|
||||||
|
|
||||||
## Dependencies
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ MovieMapper │
|
||||||
|
├──────────────┬──────────────────────────┬───────────────────┤
|
||||||
|
│ Electron │ Rust core (crate) │ iOS (Swift) │
|
||||||
|
│ desktop app │ movie_mapper │ companion client │
|
||||||
|
│ ├──────────────────────────┤ │
|
||||||
|
│ main.js │ model/ Show, Season, │ SharedModels/ │
|
||||||
|
│ renderer.js │ Episode │ Swift mirrors │
|
||||||
|
│ index.html │ service/ │ │
|
||||||
|
│ utils/ │ FileScanner │ build.sh │
|
||||||
|
│ │ MetadataExtractor │ archive.sh │
|
||||||
|
│ Electron │ TVDBClient │ Xcode project │
|
||||||
|
│ IPC bridge │ FileMapper │ │
|
||||||
|
│ │ TagManager │ │
|
||||||
|
│ │ AuditLogger │ │
|
||||||
|
└──────────────┴──────────────────────────┴───────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
- Electron
|
| Component | Stack | Role |
|
||||||
- fluent-ffmpeg (for video duration detection)
|
|-----------|-------|------|
|
||||||
- TheTVDB API integration
|
| `main.js`, `renderer.js` | Electron (Node 20) | Desktop UI, IPC handlers, filesystem ops |
|
||||||
|
| `utils/fileUtils.js` | Node + fluent-ffmpeg | Directory scanning, ffprobe metadata |
|
||||||
|
| `Rust/` (crate `movie_mapper`) | Rust, tokio, reqwest | Reusable core: scanner, TVDB client, mapper, tags, audit |
|
||||||
|
| `backend/` (crate) | Rust | Async backend integration layer |
|
||||||
|
| `ui/` (crate) | Rust, Iced | Native Rust UI prototype |
|
||||||
|
| `SharedModels/` | Swift | Data models for the iOS companion |
|
||||||
|
|
||||||
## Usage
|
### Data flow
|
||||||
|
|
||||||
1. Click "Select Directory" to choose a folder containing media files
|
```
|
||||||
2. The application will scan the directory and display media files with their durations
|
directory scan ──▶ ffprobe metadata ──▶ tag (extra/commentary)
|
||||||
3. Click on any file name to rename it
|
│
|
||||||
4. Use the search functionality to find TV shows and their details
|
▼
|
||||||
|
Jellyfin folder mapping
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
.audit log entry per operation
|
||||||
|
```
|
||||||
|
|
||||||
|
## Project structure
|
||||||
|
|
||||||
|
```
|
||||||
|
├── main.js # Electron main process (IPC, file ops, TVDB)
|
||||||
|
├── renderer.js # Renderer process (UI state, events)
|
||||||
|
├── index.html # UI (dark theme)
|
||||||
|
├── preload.js # Context bridge
|
||||||
|
├── utils/fileUtils.js # Directory scan + ffprobe metadata
|
||||||
|
├── tests/ # vitest suite (118 tests)
|
||||||
|
│ └── legacy/ # Earlier node:test integration tests
|
||||||
|
├── Rust/ # Rust core crate (movie_mapper)
|
||||||
|
│ ├── src/service/ # Scanner, TVDB client, mapper, tags, audit
|
||||||
|
│ ├── src/model/ # Show, Season, Episode, MediaFile
|
||||||
|
│ └── tests/ # Unit, integration, e2e, benchmarks
|
||||||
|
├── backend/ # Rust backend integration crate
|
||||||
|
├── ui/ # Rust Iced UI prototype
|
||||||
|
├── SharedModels/ # Swift models (iOS companion)
|
||||||
|
└── docs/ # Design docs, phase summaries, plans
|
||||||
|
```
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
### Desktop app (Electron)
|
||||||
|
|
||||||
|
Prerequisites: Node.js 20+, npm, `ffmpeg`/`ffprobe` on PATH.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
cp .env.example .env # add your TVDB_API_KEY
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
### Rust core
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo build --workspace
|
||||||
|
cargo test --workspace
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm test # vitest suite (JS)
|
||||||
|
cargo test --workspace # Rust unit + integration
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
| Variable | Required | Description |
|
||||||
|
|----------|----------|-------------|
|
||||||
|
| `TVDB_API_KEY` | for TVDB search | TheTVDB v4 API token |
|
||||||
|
|
||||||
|
## Jellyfin folder compatibility
|
||||||
|
|
||||||
|
Moves target the [Jellyfin extras folder specification](https://docs.jellyfin.org/):
|
||||||
|
`behind the scenes`, `deleted scenes`, `interviews`, `scenes`, `samples`,
|
||||||
|
`shorts`, `featurettes`, `clips`, `other`, `extras`, `trailers`,
|
||||||
|
`theme-music`, `backdrops`.
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
- [Project overview](docs/PROJECT_OVERVIEW.md)
|
||||||
|
- [Feature matrix](docs/FEATURES.md)
|
||||||
|
- [Rust implementation notes](docs/RUST_IMPLEMENTATION.md)
|
||||||
|
- [Folder navigation design](docs/FOLDER_NAVIGATION_PLAN.md)
|
||||||
|
- [iOS plan](docs/iOS_PLAN.md)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
[MIT](LICENSE)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user