13 Commits

Author SHA1 Message Date
truewhile b0fe40142a Rebrand MMTL to MeBox (name, logo, Docker image) (#17)
* Rebrand MMTL to MeBox across codebase and assets

Rename the project display name, Go module path, environment variable
prefix (MEBOX_*), Docker image references, and UI branding from MMTL/mmtl
to MeBox/mebox. Replace logo assets with the new MeBox icon and keep
legacy SQLite migration support for existing mmtl.db deployments.

Co-authored-by: truewhile <truewhile@users.noreply.github.com>

* Fix logo icons: use cube-only crop without truncated text

Previous icon generation cropped too much of the source image, including
partial MeBox wordmark text that was cut off in square icon containers.
Regenerate logo-64/192/512, favicon, and SVG from cube-only region.

Co-authored-by: truewhile <truewhile@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: truewhile <truewhile@users.noreply.github.com>
2026-09-02 16:26:28 +08:00
truewhile 44ca451cd4 优化
优化
2026-08-24 17:40:43 +08:00
ShukeBta 479a06f008 Unify organize ingest pipeline 2026-06-14 23:17:52 +08:00
ShukeBta c76c72966a Fix organize targets and cloud transfer controls 2026-06-14 00:27:39 +08:00
ShukeBta 5f42836bbf fix organize trigger task flow 2026-06-13 17:08:56 +08:00
ShukeBta 4e0929bbca fix organize path mapping and task flow 2026-06-13 16:32:38 +08:00
ShukeBta 76fe0dbde9 feat: scrape metadata after organize 2026-06-09 17:00:24 +08:00
ShukeBta fe0e7a09ce fix: improve media file organization workflow 2026-06-09 13:57:34 +08:00
soldosluka857 d03f84e78d feat(organize): organize arbitrary source dir (e.g. downloads) with dedup + 洗版
- Add OrganizeDirectory service: walk an arbitrary source directory (download
  dir / NAS direct-read path) and organize video files into the destination,
  without requiring the source to be a registered library.
- Dedup: skip media already present in the destination (matched by scanned DB
  identity title+year[/season+episode], robust to dir case/layout, plus a
  filesystem folder fallback).
- 洗版 (resolution replacement): when the source resolution is higher than the
  existing version, replace the lower-res file (+NFO sidecar +DB row). Prefers
  scanned dimensions, then ffprobe, then filename token; never replaces on
  unknown resolution.
- New endpoints: GET /admin/organize/sources (download/media dir candidates)
  and POST /admin/organize/source.
- UI: ToolsPage adds a '整理来源目录(去重+洗版)' form so operators can pick the
  download dir as the organize source.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-05-30 16:29:15 +08:00
soldosluka857 8f0c6d2324 feat(organize): separate source dir from destination dir (从源目录整理到目的地目录)
Previously organize only exposed a single 'target dir' that was actually
the destination, conflating 源目录 (where files to organize live) with
目的地目录 (where organized files go). Add an explicit source directory:

- OrganizeOptions gains SourcePath; DestPath replaces the old TargetPath
  (destination) for clarity. New organize.source_dir setting + source_path
  request override; resolveSourceRoot falls back to library path.
- OrganizeLibraryWithOptions only organizes media located under the source
  root, so operators can point at a specific download/staging folder and
  organize into a distinct destination.
- Handler accepts source_path/dest_path (target_path kept as a deprecated
  alias for the destination, backward compatible).
- Settings page splits into 整理源目录(待整理) + 整理目的地目录; Tools organize
  panel exposes 源目录 + 目的地目录 inputs with clear copy.

Defaults are unchanged (source = destination = library path) so existing
setups behave identically. Adds a regression test that organize is scoped
to the source directory.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-05-30 13:02:36 +08:00
soldosluka857 b9b7b7052a feat(organize/scan): transfer modes, seeding-safe relocation, inode dedup, incremental scanning
- Organizer: add move/copy/hardlink/symlink transfer modes (default move),
  per-request target_path/transfer_mode overrides, and honor organize.target_dir
  / organize.transfer_mode settings.
- keep_seeding (default on): escalate move->hardlink (cross-device->copy) so the
  qBittorrent source stays in place and continues seeding after organize.
- qBittorrent SetLocation + POST /downloads/relocate to migrate whole torrents
  while keeping them seeding.
- Scanner: FileID (device:inode) hardlink dedup to avoid duplicate recognition
  and double-counted storage; extract single-file ingest.
- Watcher: recursive watch + incremental per-file ingest/remove instead of full
  re-scan; periodic full library scan now gated behind scan.periodic_enabled
  (default off) to reduce disk wear.
- Telegram bot: handle callback_query in polling, declare allowed_updates in
  webhook, answer callbacks.
- Frontend: settings for transfer mode / keep_seeding / periodic scan; organize
  panel target dir + transfer mode overrides.
- Tests for transfer modes, organizer resolution, SetLocation, inode dedup,
  incremental ingest/remove.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-05-30 12:01:46 +08:00
soldosluka857 4e5797f1f4 fix: correct HTTP status codes and error handling in remaining handlers
- createPlaylistHandler: 200 → 201 Created, service errors → 500
- createSiteHandler: service/DB errors → 500 (was 400)
- saveStorageConfigHandler: service errors → 500 (was 400)
- SchedulerHandler.RunTask: task errors → 500 (was 400 with ErrInternal)
- aria2StatsHandler: service errors → 500 (was 400)
- organizeMediaHandler: service errors → 500 (was 400)
- testDownloadClientHandler: test failure → 200 with ok:false (was 400)
- testStorageConfigHandler: test failure → 200 with ok:false (was 400)

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-05-30 10:52:28 +08:00
Kiro 778bf77437 feat: backup, notifier, organizer, douban, watch-history, poster-wall
Complete the port of the remaining MediaStation features:

Backend services:
  - service/backup.go: SQLite hot backup via VACUUM INTO, list, delete,
    restore. Backup files stored under {data_dir}/backups/ with timestamps.
  - service/notifier.go: Multi-channel push notifications (Telegram /
    Bark / WeChat Server酱 / Webhook). Configuration via settings table
    keys notify.telegram.*, notify.bark.*, etc.
  - service/organizer.go: Auto-rename + move media files into library
    directory structure. Movie: {Title} ({Year})/{Title} ({Year}).ext,
    TV: {Title}/Season XX/{Title} - SxxExx.ext. Both per-media and
    per-library batch endpoints.
  - service/douban.go: Douban (豆瓣) metadata provider using the
    unofficial subject_suggest API. Returns Chinese titles + posters.
    Requires douban_cookie in secrets config.

Handlers:
  - handler/backup.go: GET/POST/DELETE /admin/backups, POST restore.
  - handler/organizer.go: POST /admin/media/:id/organize,
    POST /admin/libraries/:id/organize.
  - handler/notify.go: POST /admin/notify/test.

Frontend pages:
  - WatchHistoryPage.tsx: full paginated history with progress bars,
    resume buttons, poster thumbnails and timestamps.
  - PosterWallPage.tsx: dense 8-column poster grid of all media
    (matches the original MediaStation PosterWallView.vue).

Sidebar additions: 观看历史 + 海报墙 links in the main nav group.

Verified: go build, go vet, go test all pass; tsc -b && vite build
emits 30 lazy chunks; main bundle 254 KB / 85 KB gzipped.
2026-05-15 14:17:26 +00:00