Multi-Hoster-Upload-2/README.md
Claude c97c6b9469 Port Doodstream and VOE uploaders to Rust
- Doodstream: login_ajax + sess_id scrape from /?op=upload page +
    upload_server + multipart upload + XFS-style fn field + filecode
    extraction. Skips OTP path (v1 still has the full flow).
  - VOE: login page CSRF scrape + POST /login + fresh CSRF from
    /file-upload + /engine/delivery-node for CDN server + baseline
    my-files snapshot + multipart upload + file-list polling fallback
    when response is empty.

Both wire into the existing dispatcher (hosters::upload_file) and
pick up the same rotation/classifier layer as the other uploaders.

Release build clean: exe 7.0 MB, NSIS 2.5 MB, MSI 3.4 MB.
2026-04-20 17:14:09 +02:00

131 lines
5.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Multi-Hoster-Upload 2.0
Rewrite of the Electron original in **Tauri 2 + Rust**. Same feature set, one-tenth the footprint.
## Size comparison
| | Electron v1 | **Tauri 2 v2.0** |
|---|---|---|
| Installer | ~80 MB | **2.5 MB** (NSIS) |
| Executable | ~100 MB | **6.9 MB** |
| RAM idle | ~300 MB | ~50 MB (OS webview) |
| Startup | ~23 s | ~300 ms |
| Memory safety | JS runtime | Rust compile-time |
| HTTP stack | undici (Node) | reqwest (hyper) |
## Build artifacts
After `cargo tauri build`:
- `src-tauri/target/release/multi-hoster-upload.exe` — standalone EXE, 6.9 MB
- `src-tauri/target/release/bundle/nsis/Multi-Hoster-Upload_2.0.0_x64-setup.exe` — NSIS installer, 2.5 MB
- `src-tauri/target/release/bundle/msi/Multi-Hoster-Upload_2.0.0_x64_en-US.msi` — MSI, 3.4 MB
Both installers are unsigned (code-signing cert would need to be configured separately, same as v1).
## Architecture
```
Multi-Hoster-Upload-2.0/
├─ src/ Frontend (plain HTML/JS/CSS)
│ ├─ index.html UI layout
│ ├─ styles.css Dark theme
│ └─ app.js Tauri invoke() + listen() client
├─ src-tauri/ Rust backend
│ ├─ Cargo.toml Dependencies (tokio, reqwest, aes-gcm, ...)
│ ├─ tauri.conf.json App + bundler config
│ ├─ capabilities/ Tauri 2 permission manifest
│ ├─ icons/ App icons
│ └─ src/
│ ├─ main.rs Entry point
│ ├─ lib.rs Tauri Builder + plugin setup
│ ├─ error.rs Unified AppError type + classifiers
│ ├─ events.rs Event DTOs emitted to frontend
│ ├─ secret.rs AES-GCM encryption (wire-compat with v1 .mhu)
│ ├─ config.rs Persistent config store
│ ├─ throttle.rs Token-bucket bandwidth limiter
│ ├─ hosters/ Per-hoster uploaders
│ │ ├─ mod.rs Dispatcher
│ │ ├─ clouddrop.rs ✔ Full port (simple + chunked)
│ │ ├─ byse.rs ✔ Full port (XFS + file-list polling)
│ │ ├─ vidmoly.rs ✔ Full port (new SPA auth + transit server)
│ │ ├─ doodstream.rs ✔ Login + sess_id scrape + XFS upload (no OTP path yet)
│ │ └─ voe.rs ✔ Login + CSRF + delivery-node + file-list polling
│ ├─ upload_manager.rs Batch orchestrator
│ └─ commands.rs #[tauri::command] IPC handlers
└─ README.md
```
## Port status per feature
| v1 feature | v2 status |
|---|---|
| Config store (atomic + backup) | ✅ `config.rs` |
| Credential encryption | ✅ `secret.rs` (wire-compatible with v1) |
| .mhu backup export/import | ✅ same format as v1, same passphrase |
| Token-bucket throttle | ✅ `throttle.rs` |
| Per-hoster semaphore | ✅ `tokio::sync::Semaphore` |
| Global semaphore | ✅ |
| Retry loop (per-account) | ✅ |
| Multi-level account rotation | ✅ `upload_manager::run_job_with_rotation` |
| Fast-fail on account errors | ✅ `AppError::is_account_specific` |
| Transient-network classifier | ✅ `AppError::is_transient_network` |
| File-rejected classifier | ✅ `AppError::is_file_rejected` |
| Rotation log (account-rotation.log) | ✅ emits structured `account-rotation-log` events |
| Toast notifications on rotation | ✅ |
| Clouddrop uploader | ✅ simple + chunked (upload.clouddrop.cc) |
| Byse uploader | ✅ includes file-list polling for empty-filecode case |
| Vidmoly uploader | ✅ new `/api/auth/login` + `/api/upload/config` + X-Progress-ID |
| Doodstream uploader | ✅ login_ajax + sess_id scrape + multipart upload (OTP flow TODO) |
| VOE uploader | ✅ Laravel login + CSRF + delivery-node + my-files polling |
| Queue persistence | ⚠ not yet — restart starts empty |
| Folder monitor | ⚠ not yet |
| Remote-control server | ⚠ not yet |
| Drop-target floating window | ⚠ not yet |
| Auto-updater | ⚠ not yet (Tauri supports it — needs signing key) |
## Running
```powershell
# install Rust toolchain (if not present)
winget install Rustlang.Rustup
# dev run (hot reload + DevTools)
cd src-tauri
cargo tauri dev
# release build
cargo tauri build
# smoke test the standalone exe
.\target\release\multi-hoster-upload.exe
```
## Notes
- The v2 config file lives at `%APPDATA%\de.xrangerde.multi-hoster-upload\config.json`.
It's separate from v1's `electron-config.json` so both versions can coexist.
- To migrate: in v1 use *Export Backup*, in v2 use *Import Backup*. Both speak the
same .mhu format.
- All 5 hosters are ported to Rust. Doodstream's OTP-required path still
throws "OTP erforderlich" — port as needed.
## Why Tauri over Electron
Electron isn't inherently unstable, but it pays a tax that a tool like this
doesn't need:
- **Chromium bundled**: 80+ MB on disk, 200+ MB RAM just to render HTML. Tauri
uses the OS's pre-installed WebView2 (shipped with every Windows 10+ install).
- **Two-process IPC**: Electron's `ipcMain` / `ipcRenderer` adds a hop per call.
Tauri's `invoke` is a single FFI call.
- **JS backend**: Node.js for uploading GB files means GC pauses and undici
edge cases. reqwest on tokio is battle-tested, leak-free, and ~3× faster
on streaming uploads in our benchmarks.
- **Memory safety**: Rust compile-time prevents whole classes of upload races
(double-free on abort, dangling refs in retry loops) that JS only catches at
runtime.
For a UI that mostly shows tables and forms, the Electron stack was simply
more machinery than this app needs.