From 44ca451cd46f169f121ac107fa246fb2406ea946 Mon Sep 17 00:00:00 2001 From: truewhile <62226914+truewhile@users.noreply.github.com> Date: Mon, 24 Aug 2026 17:40:43 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 优化 --- .dockerignore | 2 +- .github/ISSUE_TEMPLATE/config.yml | 4 +- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- .github/codeql/codeql-config.yml | 2 +- .github/workflows/Auto-docker-publish.yml | 2 +- .github/workflows/docker-publish.yml | 4 +- .gitignore | 2 +- CONTRIBUTING.md | 10 +- Dockerfile | 24 +-- README.md | 88 +++++------ README_EN.md | 138 +++++++++--------- SECURITY.md | 10 +- cmd/server/log_rotate.go | 2 +- cmd/server/logging.go | 2 +- cmd/server/logging_test.go | 2 +- cmd/server/main.go | 14 +- cmd/server/main_test.go | 18 +-- cmd/server/router.go | 10 +- cmd/server/startup.go | 2 +- docker-compose.search.yml | 78 +++++----- docker-compose.simple.yml | 46 +++--- docker-compose.standard.yml | 72 ++++----- docker-compose.yml | 72 ++++----- docker-entrypoint.sh | 8 +- go.mod | 2 +- internal/config/config.go | 4 +- internal/config/config_test.go | 40 ++--- internal/config/defaults.go | 8 +- internal/config/normalize.go | 6 +- internal/config/types.go | 2 +- internal/database/database.go | 2 +- internal/database/database_test.go | 10 +- internal/database/schema_library_roots.go | 2 +- internal/database/schema_migration.go | 2 +- internal/database/sqlite_migration.go | 2 +- .../database/sqlite_migration_bootstrap.go | 2 +- internal/database/sqlite_migration_copy.go | 2 +- internal/database/sqlite_migration_source.go | 4 +- internal/database/sqlite_runtime.go | 20 +-- internal/handler/active_user.go | 4 +- internal/handler/admin.go | 4 +- internal/handler/admin_settings.go | 4 +- internal/handler/admin_test.go | 6 +- internal/handler/api_config.go | 2 +- internal/handler/api_config_handler.go | 2 +- internal/handler/auth.go | 4 +- internal/handler/auth_cookie.go | 4 +- internal/handler/auth_cookie_test.go | 2 +- internal/handler/auth_extra.go | 4 +- internal/handler/backup.go | 2 +- internal/handler/danmaku.go | 2 +- internal/handler/dlna.go | 2 +- internal/handler/dlna_extra.go | 2 +- internal/handler/emby_auth.go | 4 +- internal/handler/emby_auth_test.go | 8 +- internal/handler/emby_authed_loop_test.go | 8 +- .../handler/emby_discovery_routes_test.go | 12 +- internal/handler/emby_images.go | 2 +- internal/handler/emby_items_handlers.go | 2 +- internal/handler/emby_items_test.go | 8 +- internal/handler/emby_misc_routes_test.go | 6 +- internal/handler/emby_playback.go | 2 +- .../handler/emby_playback_info_routes_test.go | 8 +- internal/handler/emby_playback_routes_test.go | 8 +- internal/handler/emby_playstate_handlers.go | 2 +- internal/handler/emby_routes.go | 4 +- internal/handler/emby_routes_lowercase.go | 2 +- internal/handler/emby_session_routes_test.go | 8 +- internal/handler/emby_sessions.go | 6 +- internal/handler/emby_sessions_test.go | 2 +- internal/handler/emby_static.go | 2 +- internal/handler/emby_subtitle_routes_test.go | 8 +- internal/handler/emby_system.go | 8 +- internal/handler/emby_test_helpers_test.go | 4 +- internal/handler/emby_users.go | 10 +- internal/handler/emby_views_handlers.go | 2 +- internal/handler/filemanager.go | 2 +- internal/handler/handler.go | 6 +- internal/handler/manual_scrape.go | 2 +- internal/handler/media.go | 6 +- internal/handler/media_extra.go | 4 +- internal/handler/media_favorite.go | 6 +- internal/handler/media_roots.go | 2 +- internal/handler/media_scan.go | 2 +- internal/handler/media_test.go | 10 +- internal/handler/metadata_enrich.go | 2 +- internal/handler/nfo.go | 2 +- internal/handler/organizer.go | 2 +- internal/handler/permission_handler.go | 6 +- internal/handler/permissions.go | 6 +- internal/handler/play_profile.go | 4 +- internal/handler/playback.go | 4 +- internal/handler/playback_extra.go | 8 +- internal/handler/playback_extra_test.go | 18 +-- internal/handler/playback_scope.go | 6 +- internal/handler/playlist_extra.go | 4 +- internal/handler/profile.go | 4 +- internal/handler/profile_test.go | 6 +- internal/handler/public_ui.go | 2 +- internal/handler/public_ui_test.go | 6 +- internal/handler/recognition_words.go | 2 +- internal/handler/recycle.go | 2 +- internal/handler/refresh_handler.go | 2 +- internal/handler/routes_admin.go | 6 +- internal/handler/routes_admin_test.go | 4 +- internal/handler/routes_api_config.go | 6 +- internal/handler/routes_authenticated.go | 6 +- internal/handler/routes_authenticated_core.go | 4 +- .../handler/routes_authenticated_extras.go | 2 +- .../handler/routes_authenticated_features.go | 4 +- internal/handler/routes_authenticated_test.go | 4 +- internal/handler/routes_public.go | 4 +- internal/handler/scrape_reclassify.go | 2 +- internal/handler/search_extra.go | 2 +- internal/handler/series.go | 4 +- internal/handler/stats_user.go | 6 +- internal/handler/storage.go | 2 +- internal/handler/storage_test.go | 4 +- internal/handler/streaming.go | 2 +- internal/handler/strm.go | 4 +- internal/handler/strm_routes_test.go | 12 +- internal/handler/subtitles.go | 2 +- internal/handler/system_extra.go | 6 +- internal/handler/system_handler.go | 4 +- internal/handler/system_meta.go | 4 +- internal/handler/system_update.go | 2 +- internal/handler/task_helpers.go | 2 +- internal/handler/visibility.go | 6 +- internal/handler/watch_history.go | 6 +- internal/handler/ws.go | 2 +- internal/model/model.go | 2 +- internal/repository/access_log_repository.go | 2 +- internal/repository/api_config_repository.go | 2 +- internal/repository/bot_repo.go | 2 +- internal/repository/favorite_repository.go | 2 +- internal/repository/history_repository.go | 2 +- internal/repository/library_repository.go | 2 +- internal/repository/media_repository.go | 2 +- .../repository/media_repository_upsert.go | 2 +- .../repository/media_search_repository.go | 2 +- internal/repository/opensearch.go | 6 +- internal/repository/opensearch_test.go | 2 +- internal/repository/permission_repository.go | 2 +- internal/repository/play_profile_repo.go | 2 +- internal/repository/playlist_repository.go | 2 +- .../repository/refresh_token_repository.go | 2 +- internal/repository/repository_test.go | 4 +- internal/repository/series_repository.go | 2 +- internal/repository/setting_repository.go | 2 +- internal/repository/storage_config_repo.go | 2 +- internal/repository/strm_repository.go | 2 +- internal/repository/user_repository.go | 2 +- internal/service/adult_scraper.go | 2 +- .../service/adult_scraper_routing_test.go | 4 +- internal/service/adult_scraper_test.go | 4 +- internal/service/api_config.go | 6 +- internal/service/api_config_connection.go | 2 +- internal/service/api_config_helpers.go | 2 +- internal/service/api_config_svc.go | 6 +- internal/service/audit.go | 4 +- internal/service/auth.go | 6 +- internal/service/auth_tokens.go | 8 +- internal/service/auth_user_limits_test.go | 8 +- internal/service/backup.go | 4 +- internal/service/bangumi.go | 4 +- internal/service/bot_settings.go | 4 +- internal/service/cloud/cloud_115_test.go | 2 +- internal/service/cloud/clouddrive2.go | 2 +- internal/service/cloud/pan115_openapi.go | 2 +- .../service/cloud_library_display_stubs.go | 4 +- internal/service/danmaku_service.go | 4 +- internal/service/danmaku_service_test.go | 4 +- internal/service/db_errors.go | 2 +- internal/service/device_cleanup.go | 2 +- internal/service/device_listing.go | 2 +- internal/service/device_service.go | 4 +- internal/service/dlna.go | 2 +- internal/service/douban.go | 2 +- internal/service/emby_artwork.go | 4 +- internal/service/emby_artwork_test.go | 2 +- internal/service/emby_compat.go | 8 +- internal/service/emby_compat_test.go | 6 +- internal/service/emby_counts.go | 2 +- internal/service/emby_items_detail.go | 2 +- internal/service/emby_items_list.go | 2 +- internal/service/emby_media_sources.go | 2 +- internal/service/emby_movie_items.go | 2 +- internal/service/emby_movie_library_test.go | 2 +- internal/service/emby_playback.go | 2 +- internal/service/emby_playback_test.go | 2 +- internal/service/emby_series.go | 2 +- .../service/emby_series_hierarchy_test.go | 2 +- internal/service/emby_series_ids.go | 2 +- internal/service/emby_subtitle_test.go | 2 +- internal/service/emby_system.go | 8 +- internal/service/emby_user_data.go | 2 +- internal/service/emby_versions_test.go | 2 +- internal/service/emby_visibility.go | 2 +- internal/service/episode_metadata_cleanup.go | 2 +- .../service/episode_metadata_cleanup_test.go | 4 +- internal/service/fanart.go | 4 +- internal/service/ffmpeg_auto_install.go | 4 +- internal/service/ffprobe.go | 2 +- internal/service/ffprobe_test.go | 2 +- internal/service/filemanager.go | 4 +- internal/service/filemanager_roots.go | 4 +- internal/service/filemanager_test.go | 6 +- internal/service/image_proxy.go | 4 +- internal/service/image_proxy_remote_test.go | 2 +- internal/service/image_proxy_test.go | 2 +- internal/service/local_availability.go | 4 +- internal/service/local_metadata_apply.go | 2 +- internal/service/local_metadata_apply_test.go | 2 +- internal/service/manual_scrape.go | 2 +- internal/service/manual_scrape_providers.go | 2 +- internal/service/manual_scrape_search.go | 2 +- internal/service/manual_scrape_test.go | 6 +- internal/service/media.go | 6 +- internal/service/media_cache.go | 4 +- internal/service/media_classifier.go | 2 +- internal/service/media_display_library.go | 4 +- internal/service/media_library.go | 2 +- internal/service/media_library_roots.go | 2 +- internal/service/media_library_roots_test.go | 6 +- internal/service/media_listing.go | 4 +- internal/service/media_metadata.go | 2 +- internal/service/media_metadata_test.go | 6 +- internal/service/media_paths.go | 20 +-- internal/service/media_recycle.go | 2 +- internal/service/media_recycle_test.go | 6 +- internal/service/media_release_sort.go | 2 +- internal/service/media_search.go | 4 +- internal/service/media_series.go | 2 +- internal/service/media_series_key.go | 2 +- internal/service/media_series_resolver.go | 2 +- internal/service/media_series_test.go | 6 +- internal/service/media_test.go | 30 ++-- internal/service/media_versions.go | 2 +- internal/service/media_versions_test.go | 6 +- internal/service/media_visibility_test.go | 6 +- internal/service/metatube.go | 2 +- internal/service/nfo.go | 4 +- internal/service/nfo_test.go | 6 +- internal/service/organize_naming_test.go | 4 +- internal/service/organize_pipeline.go | 2 +- internal/service/organize_pipeline_audit.go | 2 +- internal/service/organize_pipeline_sync.go | 2 +- internal/service/organize_pipeline_test.go | 2 +- internal/service/organizer.go | 6 +- .../service/organizer_classification_test.go | 4 +- internal/service/organizer_classify.go | 2 +- ...organizer_directory_classification_test.go | 4 +- .../service/organizer_directory_dedup_test.go | 4 +- .../service/organizer_directory_libraries.go | 2 +- .../service/organizer_directory_metadata.go | 2 +- .../organizer_directory_metadata_persist.go | 2 +- .../service/organizer_directory_source.go | 2 +- .../organizer_directory_source_test.go | 16 +- .../service/organizer_directory_sources.go | 10 +- internal/service/organizer_directory_test.go | 2 +- .../service/organizer_directory_versions.go | 2 +- .../organizer_library_classification.go | 2 +- .../service/organizer_localized_title_test.go | 6 +- internal/service/organizer_media.go | 2 +- internal/service/organizer_media_metadata.go | 2 +- internal/service/organizer_metadata_match.go | 2 +- .../organizer_reclassify_anime_test.go | 4 +- .../organizer_reclassify_duplicates_test.go | 4 +- .../organizer_reclassify_media_rows.go | 2 +- .../service/organizer_reclassify_metadata.go | 2 +- .../organizer_reclassify_metadata_test.go | 4 +- .../service/organizer_reclassify_scanned.go | 2 +- internal/service/organizer_reclassify_test.go | 4 +- internal/service/organizer_scan.go | 4 +- .../organizer_scrape_providers_test.go | 4 +- .../service/organizer_scrape_safety_test.go | 4 +- internal/service/organizer_scrape_test.go | 4 +- internal/service/organizer_settings.go | 2 +- internal/service/organizer_source_test.go | 4 +- internal/service/organizer_test.go | 6 +- internal/service/organizer_transfer_test.go | 6 +- internal/service/permission.go | 4 +- internal/service/play_profile.go | 4 +- internal/service/play_profile_model.go | 2 +- internal/service/play_profile_test.go | 4 +- internal/service/playback.go | 4 +- internal/service/profile.go | 4 +- internal/service/public_url.go | 6 +- internal/service/recognition_words.go | 4 +- internal/service/runtime_cache.go | 4 +- internal/service/runtime_settings.go | 4 +- internal/service/runtime_settings_test.go | 2 +- internal/service/scanner.go | 4 +- internal/service/scanner_existing_media.go | 2 +- .../service/scanner_existing_media_test.go | 6 +- internal/service/scanner_incremental_test.go | 10 +- .../service/scanner_library_roots_test.go | 4 +- internal/service/scanner_local_ingest.go | 2 +- .../service/scanner_local_metadata_test.go | 6 +- internal/service/scanner_local_probe_queue.go | 2 +- internal/service/scanner_local_write_batch.go | 2 +- internal/service/scanner_metadata_refresh.go | 2 +- internal/service/scanner_prune.go | 2 +- internal/service/scanner_roots.go | 2 +- internal/service/scanner_scan.go | 6 +- internal/service/scheduler.go | 2 +- internal/service/scheduler_local_jobs.go | 2 +- internal/service/scheduler_organize_test.go | 4 +- internal/service/scheduler_scan_test.go | 6 +- internal/service/scraper.go | 2 +- internal/service/scraper_alias_match_test.go | 4 +- internal/service/scraper_artwork_test.go | 4 +- .../service/scraper_episode_details_test.go | 6 +- internal/service/scraper_library.go | 2 +- internal/service/scraper_library_test.go | 2 +- internal/service/scraper_local_metadata.go | 2 +- .../service/scraper_local_metadata_test.go | 6 +- internal/service/scraper_lookup.go | 2 +- internal/service/scraper_lookup_test.go | 2 +- internal/service/scraper_query.go | 4 +- .../service/scraper_query_candidates_test.go | 2 +- internal/service/scraper_query_movie_test.go | 6 +- internal/service/scraper_query_test.go | 6 +- internal/service/scraper_service.go | 6 +- internal/service/scraper_test.go | 2 +- internal/service/scraper_test_helpers_test.go | 6 +- internal/service/scraper_tmdb_details.go | 2 +- .../service/scraper_write_metadata_files.go | 2 +- .../scraper_write_metadata_files_test.go | 2 +- internal/service/security_safety_test.go | 4 +- internal/service/service.go | 6 +- internal/service/service_builder.go | 4 +- .../service_builder_library_roots_test.go | 4 +- internal/service/service_library_normalize.go | 2 +- .../service/service_library_normalize_test.go | 6 +- internal/service/service_search_warmup.go | 2 +- internal/service/session_tracker_activity.go | 2 +- internal/service/session_tracker_test.go | 4 +- internal/service/storage.go | 2 +- internal/service/stream_cloud_settings.go | 2 +- internal/service/stream_file.go | 4 +- internal/service/stream_service.go | 4 +- internal/service/stream_test.go | 6 +- internal/service/strm_115_oauth.go | 4 +- internal/service/strm_115_oauth_test.go | 4 +- internal/service/strm_play.go | 4 +- internal/service/strm_queue.go | 6 +- internal/service/strm_service.go | 8 +- internal/service/strm_sync.go | 4 +- internal/service/strm_sync_test.go | 6 +- internal/service/subtitle.go | 2 +- internal/service/subtitle_test.go | 4 +- internal/service/system_update.go | 10 +- internal/service/system_update_command.go | 4 +- internal/service/system_update_compose.go | 4 +- internal/service/system_update_docker.go | 2 +- internal/service/system_update_test.go | 32 ++-- internal/service/thetvdb.go | 2 +- internal/service/tmdb.go | 2 +- internal/service/tmdb_chinese_title_test.go | 2 +- internal/service/token_svc.go | 8 +- internal/service/token_svc_pending.go | 4 +- internal/service/token_svc_pending_test.go | 6 +- internal/service/transcoder.go | 4 +- internal/service/transcoder_ffmpeg_args.go | 2 +- internal/service/transcoder_test.go | 2 +- internal/service/visibility.go | 4 +- internal/service/watcher.go | 4 +- internal/service/watcher_test.go | 8 +- web/public/artwork-cache-sw.js | 2 +- web/src/api/playback.ts | 2 +- web/src/components/useThemeMode.ts | 5 +- web/src/stores/auth.ts | 2 +- web/src/stores/playProfile.ts | 2 +- 374 files changed, 1029 insertions(+), 1028 deletions(-) diff --git a/.dockerignore b/.dockerignore index a49d02b..6257f05 100644 --- a/.dockerignore +++ b/.dockerignore @@ -18,7 +18,7 @@ verify-downloads/ .tmp_* .tmp-deploy-* .tmp-deploy-data/ -.mediastation.pid +.mmtl.pid *.db *.db-journal *.db-shm diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 1ca884d..66cde86 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,5 +1,5 @@ blank_issues_enabled: true contact_links: - - name: Telegram MediaStationGo 交流群 - url: https://t.me/MediaStationGo + - name: Telegram MMTL 交流群 + url: https://t.me/MMTL about: 适合快速交流部署经验、使用问题和排查线索。 diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index b7450df..64e26bb 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -12,7 +12,7 @@ assignees: "" ## 期望方案 -请描述你希望 MediaStationGo 如何工作。 +请描述你希望 MMTL 如何工作。 ## 使用场景 diff --git a/.github/codeql/codeql-config.yml b/.github/codeql/codeql-config.yml index e05584d..9ae6f14 100644 --- a/.github/codeql/codeql-config.yml +++ b/.github/codeql/codeql-config.yml @@ -1,4 +1,4 @@ -name: MediaStationGo CodeQL +name: MMTL CodeQL paths-ignore: - internal/service/fileid_other.go diff --git a/.github/workflows/Auto-docker-publish.yml b/.github/workflows/Auto-docker-publish.yml index 0c7aca7..05d1901 100644 --- a/.github/workflows/Auto-docker-publish.yml +++ b/.github/workflows/Auto-docker-publish.yml @@ -82,7 +82,7 @@ jobs: NEW_VERSION="${MAJOR}.${MINOR}.${PATCH}" echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT - echo "tag=MediaStationGo-v${NEW_VERSION}" >> $GITHUB_OUTPUT + echo "tag=MMTL-v${NEW_VERSION}" >> $GITHUB_OUTPUT # 3. 更新 VERSION 文件 - name: Update version file diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 475e319..4e5d4fb 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: inputs: version: - description: 'Image tag to publish, for example MediaStationGo-v0.0.32' + description: 'Image tag to publish, for example MMTL-v0.0.32' required: true type: string ref: @@ -42,7 +42,7 @@ jobs: uses: docker/metadata-action@v5 with: # 自动使用当前仓库所有者 - images: ghcr.io/${{ github.repository_owner }}/mediastation-go + images: ghcr.io/${{ github.repository_owner }}/mmtl tags: | type=raw,value=latest type=raw,value=${{ env.RELEASE_VERSION }} diff --git a/.gitignore b/.gitignore index d56b20c..ffa5aea 100644 --- a/.gitignore +++ b/.gitignore @@ -32,7 +32,7 @@ logs/ .tmp-deploy-cache/ .tmp-deploy-server.* .tmp-live-server.* -.mediastation.pid +.mmtl.pid *.log *.db *.db-journal diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4da0548..bd4b8f7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # 贡献规范 -感谢你愿意帮助 MediaStationGo 变得更稳定。这个项目主要面向 NAS、Docker 部署、媒体库整理、订阅下载和多端播放场景;提交 Issue 或 Pull Request 时,请尽量提供可复现、可验证的信息。 +感谢你愿意帮助 MMTL 变得更稳定。这个项目主要面向 NAS、Docker 部署、媒体库整理、订阅下载和多端播放场景;提交 Issue 或 Pull Request 时,请尽量提供可复现、可验证的信息。 ## Issue 提交规范 @@ -16,7 +16,7 @@ - 期望行为:你认为正确结果应该是什么。 - 复现步骤:从哪个页面、点击什么、填写什么、触发什么任务。 - 部署方式:Docker 第一档 / 第二档 / 第三档、裸机运行、反代方式等。 -- 环境信息:NAS 型号或系统、Docker / Compose 版本、浏览器、MediaStationGo 镜像版本。 +- 环境信息:NAS 型号或系统、Docker / Compose 版本、浏览器、MMTL 镜像版本。 - 相关配置:路径映射、下载器保存路径、媒体库路径、站点类型等。请隐藏 Cookie、API Key、密码和 Token。 - 日志和任务信息:优先提供应用日志、任务队列详情、浏览器控制台错误、网络请求错误。 @@ -28,14 +28,14 @@ Docker 部署常用命令: ```bash docker compose ps -docker compose logs --tail=300 mediastation-go -docker compose exec mediastation-go sh -lc 'ls -la /data/logs || true' +docker compose logs --tail=300 mmtl +docker compose exec mmtl sh -lc 'ls -la /data/logs || true' ``` PostgreSQL 部署查询示例: ```bash -docker compose exec postgres psql -U mediastation -d mediastation -c "select key,value,updated_at from settings order by updated_at desc limit 30;" +docker compose exec postgres psql -U mmtl -d mmtl -c "select key,value,updated_at from settings order by updated_at desc limit 30;" ``` 请勿公开粘贴以下敏感信息: diff --git a/Dockerfile b/Dockerfile index d89ea04..0b20f37 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:1.6 # ============================================================================= -# Multi-architecture build for MediaStationGo. +# Multi-architecture build for MMTL. # # Stage 1 (frontend) : Node 20 -> static SPA bundle # Stage 2 (backend) : Go 1.25 -> single static binary (CGO_ENABLED=0) @@ -8,7 +8,7 @@ # # Build: # docker buildx build --platform linux/amd64,linux/arm64 \ -# --build-arg VERSION=MediaStationGo-v0.1.16 -t mediastation-go:latest --push . +# --build-arg VERSION=MMTL-v0.1.16 -t mmtl:latest --push . # # Optional Intel VAAPI/QSV runtime packages: # docker buildx build --build-arg WITH_VAAPI=true ... @@ -39,7 +39,7 @@ COPY . . COPY --from=frontend /app/web/dist ./web/dist RUN --mount=type=cache,target=/go/pkg/mod \ CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ - go build -trimpath -ldflags="-s -w -X main.version=${VERSION}" -o mediastation-go ./cmd/server + go build -trimpath -ldflags="-s -w -X main.version=${VERSION}" -o mmtl ./cmd/server # ---- Stage 3: runtime ------------------------------------------------------ FROM alpine:3.23 @@ -64,22 +64,22 @@ RUN apk add --no-cache \ && rm -rf /var/cache/apk/* # Non-root user for the long-running process. -RUN addgroup -S mediastation && adduser -S mediastation -G mediastation +RUN addgroup -S mmtl && adduser -S mmtl -G mmtl WORKDIR /app -COPY --from=backend /app/mediastation-go /usr/local/bin/mediastation-go +COPY --from=backend /app/mmtl /usr/local/bin/mmtl COPY --from=frontend /app/web/dist /app/web/dist RUN mkdir -p /data /cache /media \ - && chown -R mediastation:mediastation /data /cache /media + && chown -R mmtl:mmtl /data /cache /media # Default environment (overridable via docker-compose / `docker run -e`). -ENV MEDIASTATION_APP_PORT=8080 \ - MEDIASTATION_APP_DATA_DIR=/data \ - MEDIASTATION_APP_WEB_DIR=/app/web/dist \ - MEDIASTATION_DATABASE_DB_PATH=/data/mediastation.db \ - MEDIASTATION_CACHE_CACHE_DIR=/cache \ - MEDIASTATION_LOGGING_LEVEL=info \ +ENV MMTL_APP_PORT=8080 \ + MMTL_APP_DATA_DIR=/data \ + MMTL_APP_WEB_DIR=/app/web/dist \ + MMTL_DATABASE_DB_PATH=/data/mmtl.db \ + MMTL_CACHE_CACHE_DIR=/cache \ + MMTL_LOGGING_LEVEL=info \ TZ=Asia/Shanghai EXPOSE 8080 diff --git a/README.md b/README.md index 3b7fb0f..da6446e 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ ## 项目简介 -MediaStationGo 是一个自托管媒体管理系统,面向 NAS、小主机、家庭影音和多用户共享场景。它把媒体库、刮削、下载整理、订阅、网盘播放、Emby 协议兼容、用户权限和 Bot 通知放在一个后台里,目标是让用户只维护一套服务,就能给网页端、手机端、电视端和第三方播放器使用。 +MMTL 是一个自托管媒体管理系统,面向 NAS、小主机、家庭影音和多用户共享场景。它把媒体库、刮削、下载整理、订阅、网盘播放、Emby 协议兼容、用户权限和 Bot 通知放在一个后台里,目标是让用户只维护一套服务,就能给网页端、手机端、电视端和第三方播放器使用。 核心能力: @@ -77,7 +77,7 @@ GHCR:ghcr.io/truewhile/mmtl:latest ## 部署档位 -MediaStationGo 推荐按机器资源和用户规模选择部署档位。每份 Compose 文件都是完整文件,不需要再叠加多个 `-f`。想一个镜像跑起来就选单镜像档(SQLite);需要多用户 / 高并发时再用 PostgreSQL 三档。Redis 和 OpenSearch 是增强组件,不替代 PostgreSQL。 +MMTL 推荐按机器资源和用户规模选择部署档位。每份 Compose 文件都是完整文件,不需要再叠加多个 `-f`。想一个镜像跑起来就选单镜像档(SQLite);需要多用户 / 高并发时再用 PostgreSQL 三档。Redis 和 OpenSearch 是增强组件,不替代 PostgreSQL。 | 档位 | 完整配置文件 | 组件 | 适合场景 | | --- | --- | --- | --- | @@ -119,12 +119,12 @@ volumes: 关键数据目录: ```text -./data JWT 密钥、运行配置、SQLite 主数据库(mediastation.db)——必须备份 +./data JWT 密钥、运行配置、SQLite 主数据库(mmtl.db)——必须备份 ./cache 海报/临时缓存,可重建 ./media 媒体库 ``` -> 单镜像模式请不要配置 `MEDIASTATION_DATABASE_DSN`;一旦填了 DSN 就会切回 PostgreSQL。 +> 单镜像模式请不要配置 `MMTL_DATABASE_DSN`;一旦填了 DSN 就会切回 PostgreSQL。 ### 第一档:PostgreSQL @@ -176,10 +176,10 @@ OpenSearch 数据目录是 `./opensearch`。搜索索引可重建,但重建大 仓库内提供四份推荐 Compose 文件: ```text -docker-compose.simple.yml 单镜像档:MediaStationGo + 内置 SQLite -docker-compose.yml 第一档:MediaStationGo + PostgreSQL -docker-compose.standard.yml 第二档:MediaStationGo + PostgreSQL + Redis -docker-compose.search.yml 第三档:MediaStationGo + PostgreSQL + Redis + OpenSearch +docker-compose.simple.yml 单镜像档:MMTL + 内置 SQLite +docker-compose.yml 第一档:MMTL + PostgreSQL +docker-compose.standard.yml 第二档:MMTL + PostgreSQL + Redis +docker-compose.search.yml 第三档:MMTL + PostgreSQL + Redis + OpenSearch ``` 仓库只保留面向用户部署和项目维护的必要文件。旧的本地部署脚本、发包脚本、开发机辅助脚本、`.env` 示例和旧高级 Compose 模板已经移除;Linux / Docker 用户按上面四个 Compose 文件部署即可。开发者本地生成的 `bin/`、`data/`、`cache/`、`logs/`、`.tmp/`、`tools/` 等目录已列入 `.gitignore`,不应提交到仓库。 @@ -202,7 +202,7 @@ docker compose -f docker-compose.search.yml up -d ```yaml services: - mediastation-go: + mmtl: image: ghcr.io/truewhile/MMTL:latest ports: # 左边是宿主机访问端口,右边是容器内端口。 @@ -220,17 +220,17 @@ services: TZ: Asia/Shanghai # PostgreSQL 主数据库。 - MEDIASTATION_DATABASE_TYPE: postgres - MEDIASTATION_DATABASE_DSN: postgres://mediastation:mediastation@postgres:5432/mediastation?sslmode=disable + MMTL_DATABASE_TYPE: postgres + MMTL_DATABASE_DSN: postgres://mmtl:mmtl@postgres:5432/mmtl?sslmode=disable - # 旧 SQLite 迁移源:只在从旧版 data/mediastation.db 导入时使用。 - MEDIASTATION_DATABASE_DB_PATH: /data/mediastation.db + # 旧 SQLite 迁移源:只在从旧版 data/mmtl.db 导入时使用。 + MMTL_DATABASE_DB_PATH: /data/mmtl.db # 路径换算:宿主机路径和容器路径必须一一对应。 - MEDIASTATION_MEDIA_DIR: /vol1/1000/Media - MEDIASTATION_MEDIA_CONTAINER_DIR: /media - MEDIASTATION_DOWNLOAD_DIR: /vol1/1000/Downloads - MEDIASTATION_DOWNLOAD_CONTAINER_DIR: /downloads + MMTL_MEDIA_DIR: /vol1/1000/Media + MMTL_MEDIA_CONTAINER_DIR: /media + MMTL_DOWNLOAD_DIR: /vol1/1000/Downloads + MMTL_DOWNLOAD_CONTAINER_DIR: /downloads ``` ## 路径映射 @@ -244,10 +244,10 @@ volumes: - /vol1/1000/Docker/moviepilot-v2/media:/vol1/1000/Docker/moviepilot-v2/media - /vol1/1000/qBittorrent/downloads:/vol1/1000/qBittorrent/downloads environment: - MEDIASTATION_MEDIA_DIR: /vol1/1000/Docker/moviepilot-v2/media - MEDIASTATION_MEDIA_CONTAINER_DIR: /vol1/1000/Docker/moviepilot-v2/media - MEDIASTATION_DOWNLOAD_DIR: /vol1/1000/qBittorrent/downloads - MEDIASTATION_DOWNLOAD_CONTAINER_DIR: /vol1/1000/qBittorrent/downloads + MMTL_MEDIA_DIR: /vol1/1000/Docker/moviepilot-v2/media + MMTL_MEDIA_CONTAINER_DIR: /vol1/1000/Docker/moviepilot-v2/media + MMTL_DOWNLOAD_DIR: /vol1/1000/qBittorrent/downloads + MMTL_DOWNLOAD_CONTAINER_DIR: /vol1/1000/qBittorrent/downloads ``` Windows Docker Desktop 示例: @@ -256,20 +256,20 @@ Windows Docker Desktop 示例: volumes: - D:/Media:/media environment: - MEDIASTATION_MEDIA_DIR: D:/Media - MEDIASTATION_MEDIA_CONTAINER_DIR: /media + MMTL_MEDIA_DIR: D:/Media + MMTL_MEDIA_CONTAINER_DIR: /media ``` 如果后台添加媒体库时填的是 `/vol1/...`,Compose 里也建议把同一个 `/vol1/...` 挂进容器,避免自动整理和下载入库时路径不可访问。 ## 旧 SQLite 迁移 -新版推荐 PostgreSQL 作为主数据库。`MEDIASTATION_DATABASE_DB_PATH` 不是主库路径,而是旧 SQLite 数据的迁移源。 +新版推荐 PostgreSQL 作为主数据库。`MMTL_DATABASE_DB_PATH` 不是主库路径,而是旧 SQLite 数据的迁移源。 迁移步骤: -1. 把旧版 `mediastation.db` 放到 `./data/mediastation.db`。 -2. 保持 `MEDIASTATION_DATABASE_DB_PATH: /data/mediastation.db`。 +1. 把旧版 `mmtl.db` 放到 `./data/mmtl.db`。 +2. 保持 `MMTL_DATABASE_DB_PATH: /data/mmtl.db`。 3. 启动一次,确认日志显示迁移完成,网页数据正常。 4. 备份 `./postgres` 和 `./data`。 5. 确认不再需要 SQLite 后,把迁移源改成不存在的路径,例如: @@ -277,7 +277,7 @@ environment: ```yaml environment: # 已完成 SQLite 迁移后,建议改成不存在的路径,避免下次启动重复检查旧库。 - MEDIASTATION_DATABASE_DB_PATH: /data/no-sqlite-migration.db + MMTL_DATABASE_DB_PATH: /data/no-sqlite-migration.db ``` 不要删除 `./postgres`。PostgreSQL 已经是主数据库,删除它会丢失账号、媒体库、订阅、配置和历史数据。 @@ -287,36 +287,36 @@ environment: Compose 模板默认把完整应用日志写入 `./data/logs/app.log`,同时拆分 `./data/logs/warn.log` 和 `./data/logs/error.log`。Docker 自身日志也会保留 10 个 50MB 文件: ```bash -docker compose logs -f mediastation-go +docker compose logs -f mmtl tail -f ./data/logs/app.log tail -f ./data/logs/error.log ``` -如果要排查订阅、站点搜索、自动整理或 STRM 生成问题,保持 `MEDIASTATION_LOGGING_LEVEL: info`;需要更细日志时临时改成 `debug`,确认后再改回 `info`。 +如果要排查订阅、站点搜索、自动整理或 STRM 生成问题,保持 `MMTL_LOGGING_LEVEL: info`;需要更细日志时临时改成 `debug`,确认后再改回 `info`。 -STRM 输出目录请使用容器内可写路径,例如 `/data/strm`,或你已经挂载进容器的媒体目录。旧版本保存过 `/app/data/strm` 的部署会在生成时自动迁移到当前 `MEDIASTATION_APP_DATA_DIR`,默认就是 `/data`。 +STRM 输出目录请使用容器内可写路径,例如 `/data/strm`,或你已经挂载进容器的媒体目录。旧版本保存过 `/app/data/strm` 的部署会在生成时自动迁移到当前 `MMTL_APP_DATA_DIR`,默认就是 `/data`。 ## 更新与备份 更新镜像: ```bash -docker compose pull mediastation-go -docker compose up -d --no-deps mediastation-go +docker compose pull mmtl +docker compose up -d --no-deps mmtl ``` -不要执行裸 `docker compose pull` 做日常更新。PostgreSQL / Redis / OpenSearch 是数据与缓存基础组件,compose 已设置为 `pull_policy: missing`,首次部署缺镜像时会拉取,日常更新只建议拉取 `mediastation-go`。需要升级这些基础组件时,请先备份 `./postgres`,再手动修改镜像版本并单独拉取。 +不要执行裸 `docker compose pull` 做日常更新。PostgreSQL / Redis / OpenSearch 是数据与缓存基础组件,compose 已设置为 `pull_policy: missing`,首次部署缺镜像时会拉取,日常更新只建议拉取 `mmtl`。需要升级这些基础组件时,请先备份 `./postgres`,再手动修改镜像版本并单独拉取。 如果第二档或第三档保留了原始文件名,更新时指定对应完整文件: ```bash # 第二档 -docker compose -f docker-compose.standard.yml pull mediastation-go -docker compose -f docker-compose.standard.yml up -d --no-deps mediastation-go +docker compose -f docker-compose.standard.yml pull mmtl +docker compose -f docker-compose.standard.yml up -d --no-deps mmtl # 第三档 -docker compose -f docker-compose.search.yml pull mediastation-go -docker compose -f docker-compose.search.yml up -d --no-deps mediastation-go +docker compose -f docker-compose.search.yml pull mmtl +docker compose -f docker-compose.search.yml up -d --no-deps mmtl ``` 必须备份: @@ -338,7 +338,7 @@ docker compose -f docker-compose.search.yml up -d --no-deps mediastation-go **启动后还是反复迁移 SQLite?** -确认旧数据已经迁移成功后,把 `MEDIASTATION_DATABASE_DB_PATH` 改成不存在的路径,例如 `/data/no-sqlite-migration.db`,然后重启容器。 +确认旧数据已经迁移成功后,把 `MMTL_DATABASE_DB_PATH` 改成不存在的路径,例如 `/data/no-sqlite-migration.db`,然后重启容器。 **扫库或入库速度很慢?** @@ -346,7 +346,7 @@ docker compose -f docker-compose.search.yml up -d --no-deps mediastation-go **qBittorrent 下载完成后无法整理?** -确认 qBittorrent 保存路径已经通过 `volumes` 挂载进 MediaStationGo 容器,并且 `MEDIASTATION_DOWNLOAD_DIR` 与 `MEDIASTATION_DOWNLOAD_CONTAINER_DIR` 对应正确。 +确认 qBittorrent 保存路径已经通过 `volumes` 挂载进 MMTL 容器,并且 `MMTL_DOWNLOAD_DIR` 与 `MMTL_DOWNLOAD_CONTAINER_DIR` 对应正确。 **硬链接目录在 Docker / NAS 上看不到内容?** @@ -354,7 +354,7 @@ docker compose -f docker-compose.search.yml up -d --no-deps mediastation-go **第三方播放器无法连接?** -确认播放器填写的是 `http://服务器IP:18080`,账号密码使用 MediaStationGo 用户账号。反代部署时需要正确设置外部访问地址和 HTTPS 头。 +确认播放器填写的是 `http://服务器IP:18080`,账号密码使用 MMTL 用户账号。反代部署时需要正确设置外部访问地址和 HTTPS 头。 ## 开发构建 @@ -400,11 +400,11 @@ http://127.0.0.1:8080/api/health ## Star History - + - - - Star History Chart + + + Star History Chart diff --git a/README_EN.md b/README_EN.md index 59f2c2f..9ef5096 100644 --- a/README_EN.md +++ b/README_EN.md @@ -29,14 +29,14 @@ ## What is it? -MediaStationGo is a self-hosted media center for personal libraries, home NAS, and home-theater users. +MMTL is a self-hosted media center for personal libraries, home NAS, and home-theater users. It helps you: - Manage movies, TV shows, anime, variety shows, music, and adult libraries. - Create multiple user accounts for family members, friends, or different devices. - Scan files and enrich posters, summaries, years, seasons, and episodes. -- Play in the web UI, or log in with a MediaStationGo account from Emby-protocol apps such as Infuse, VidHub, SenPlayer, and Emby clients. +- Play in the web UI, or log in with a MMTL account from Emby-protocol apps such as Infuse, VidHub, SenPlayer, and Emby clients. - Connect qBittorrent for search, subscriptions, downloads, and post-download organization. - Connect OpenList, CloudDrive2, WebDAV, and other storage backends with STRMURL or 302 redirect playback. - Run on NAS, mini PCs, VPS, Linux, Windows Docker Desktop, or any Docker-friendly host. @@ -47,8 +47,8 @@ It helps you: ## Key Highlights -- **One server, many clients**: deploy MediaStationGo once; you do not need to run a separate Emby server. -- **Emby-protocol compatibility**: add the server in third-party players as an Emby/Jellyfin-compatible server, then log in with your MediaStationGo username and password. +- **One server, many clients**: deploy MMTL once; you do not need to run a separate Emby server. +- **Emby-protocol compatibility**: add the server in third-party players as an Emby/Jellyfin-compatible server, then log in with your MMTL username and password. - **Multi-user management**: supports admins, regular users, account enable/disable, expiry dates, device management, Bot registration, and redeem codes. - **Local + cloud media in one place**: manage local disks, download folders, OpenList, CloudDrive2, WebDAV, and other storage backends from one panel. - **Download-to-library workflow**: connect qBittorrent for search, subscriptions, download completion organization, and metadata matching. @@ -61,7 +61,7 @@ It helps you: - **Beginners** who want to edit one `docker-compose.yml` and start the service. - **NAS users** who want a low-resource media center for local disks and cloud storage. - **PT/download users** who want downloads, organization, metadata, and playback in one panel. -- **External-player users** who want to log in to Emby-protocol third-party apps with one MediaStationGo account. +- **External-player users** who want to log in to Emby-protocol third-party apps with one MMTL account. - **Family-sharing users** who want separate user accounts without deploying a separate media server for each person. - **Developers** who want to study or extend a Go + React self-hosted media app. @@ -82,12 +82,12 @@ It helps you: Docker Compose is the recommended path. Beginners do not need `.env`, bare-metal binaries, or source builds. Use the single-image SQLite template if you want the smallest possible setup. ```bash -mkdir -p MediaStationGo -cd MediaStationGo -# Simplest option: one MediaStationGo container + SQLite -curl -fsSL https://raw.githubusercontent.com/ShukeBta/MediaStationGo/main/docker-compose.simple.yml -o docker-compose.yml -# Or tier 1: MediaStationGo + PostgreSQL -# curl -fsSL https://raw.githubusercontent.com/ShukeBta/MediaStationGo/main/docker-compose.yml -o docker-compose.yml +mkdir -p MMTL +cd MMTL +# Simplest option: one MMTL container + SQLite +curl -fsSL https://raw.githubusercontent.com/ShukeBta/MMTL/main/docker-compose.simple.yml -o docker-compose.yml +# Or tier 1: MMTL + PostgreSQL +# curl -fsSL https://raw.githubusercontent.com/ShukeBta/MMTL/main/docker-compose.yml -o docker-compose.yml ``` Edit `docker-compose.yml`: @@ -119,9 +119,9 @@ Password: admin123 ## Docker Compose Recommended -The repository `docker-compose.yml` is the lightweight recommended template: no `.env` required, and by default it only starts `MediaStationGo + PostgreSQL`. This is the best starting point for most NAS users. +The repository `docker-compose.yml` is the lightweight recommended template: no `.env` required, and by default it only starts `MMTL + PostgreSQL`. This is the best starting point for most NAS users. -If you already have an older `./data/mediastation.db`, the first start with the new compose file automatically imports it into PostgreSQL. Keep `./data`; it still stores the JWT secret, runtime data, and the old SQLite migration source. +If you already have an older `./data/mmtl.db`, the first start with the new compose file automatically imports it into PostgreSQL. Keep `./data`; it still stores the JWT secret, runtime data, and the old SQLite migration source. ### Deployment modes @@ -134,7 +134,7 @@ If you already have an older `./data/mediastation.db`, the first start with the Each compose file is standalone. Do not stack multiple `-f` files together. -The single-image `docker-compose.simple.yml` runs only MediaStationGo with a built-in SQLite database — the simplest starting point. Do not set `MEDIASTATION_DATABASE_DSN` there, or it switches back to PostgreSQL. Move up to the PostgreSQL modes for multi-user or high-concurrency use (keep `./data` when you switch). Redis and OpenSearch are enhancement layers, not source databases. Do not enable OpenSearch by default on low-memory NAS devices. +The single-image `docker-compose.simple.yml` runs only MMTL with a built-in SQLite database — the simplest starting point. Do not set `MMTL_DATABASE_DSN` there, or it switches back to PostgreSQL. Move up to the PostgreSQL modes for multi-user or high-concurrency use (keep `./data` when you switch). Redis and OpenSearch are enhancement layers, not source databases. Do not enable OpenSearch by default on low-memory NAS devices. ### Database Choice And Disabling SQLite @@ -142,14 +142,14 @@ The current Docker Compose setup uses PostgreSQL by default. SQLite is no longer ```yaml environment: - MEDIASTATION_DATABASE_TYPE: postgres - MEDIASTATION_DATABASE_DSN: postgres://mediastation:mediastation@postgres:5432/mediastation?sslmode=disable + MMTL_DATABASE_TYPE: postgres + MMTL_DATABASE_DSN: postgres://mmtl:mmtl@postgres:5432/mmtl?sslmode=disable ``` -`MEDIASTATION_DATABASE_DB_PATH` is only used as a one-time migration source for old SQLite data: +`MMTL_DATABASE_DB_PATH` is only used as a one-time migration source for old SQLite data: - Fresh installs: `docker compose up -d` uses PostgreSQL and does not create a new SQLite primary database. -- Upgrades: if `./data/mediastation.db` exists, the first start with the new compose file imports it into PostgreSQL. +- Upgrades: if `./data/mmtl.db` exists, the first start with the new compose file imports it into PostgreSQL. - Migration fills missing rows by primary key and skips rows that already exist. If it fails partway through, a later start continues the remaining tables. - After a successful import, PostgreSQL gets a completion marker in the `settings` table, so the old SQLite file is not imported again. - Redis is a hot cache and OpenSearch is a search index; neither is a source database. @@ -157,9 +157,9 @@ environment: Recommended SQLite to PostgreSQL upgrade flow: ```bash -docker compose pull mediastation-go -docker compose up -d --no-deps mediastation-go -docker compose logs -f mediastation-go +docker compose pull mmtl +docker compose up -d --no-deps mmtl +docker compose logs -f mmtl ``` After you see `sqlite data migrated to postgres`, or after the web UI shows your users, libraries, and settings correctly, you can stop using the old SQLite file as a migration source. @@ -170,15 +170,15 @@ To make the deployment PostgreSQL-only after migration, keep PostgreSQL selected ```yaml environment: - MEDIASTATION_DATABASE_TYPE: postgres - MEDIASTATION_DATABASE_DSN: postgres://mediastation:mediastation@postgres:5432/mediastation?sslmode=disable - MEDIASTATION_DATABASE_DB_PATH: /data/disabled-sqlite-migration.db + MMTL_DATABASE_TYPE: postgres + MMTL_DATABASE_DSN: postgres://mmtl:mmtl@postgres:5432/mmtl?sslmode=disable + MMTL_DATABASE_DB_PATH: /data/disabled-sqlite-migration.db ``` Then rename or move the old host-side SQLite file as an offline backup: ```bash -mv data/mediastation.db data/mediastation.sqlite.bak +mv data/mmtl.db data/mmtl.sqlite.bak ``` For bare-metal or custom `config.yaml` deployments, use the same idea: @@ -186,7 +186,7 @@ For bare-metal or custom `config.yaml` deployments, use the same idea: ```yaml database: type: postgres - dsn: postgres://mediastation:mediastation@127.0.0.1:5432/mediastation?sslmode=disable + dsn: postgres://mmtl:mmtl@127.0.0.1:5432/mmtl?sslmode=disable db_path: "" ``` @@ -198,15 +198,15 @@ Both image sources are supported. Pick one and put it in `image:`: | Source | Image | Best for | | --- | --- | --- | -| GitHub Container Registry (GHCR) | `ghcr.io/shukebta/mediastation-go:latest` | Recommended default, follows repository releases | -| Docker Hub | `shukbet/mediastationgo:latest` | Backup source when GHCR is slow or unavailable | +| GitHub Container Registry (GHCR) | `ghcr.io/shukebta/mmtl:latest` | Recommended default, follows repository releases | +| Docker Hub | `shukbet/mmtl:latest` | Backup source when GHCR is slow or unavailable | To pin a version, first confirm the tag exists on the repository Packages page. Use this format: ```yaml -image: ghcr.io/shukebta/mediastation-go: +image: ghcr.io/shukebta/mmtl: # If GHCR does not have that tag, use Docker Hub as the backup: -# image: shukbet/mediastationgo:MediaStationGo-v0.0.72 +# image: shukbet/mmtl:MMTL-v0.0.72 ``` For the simplest setup, keep GHCR `latest`. @@ -215,10 +215,10 @@ Manual pull examples: ```bash # GitHub Container Registry -docker pull ghcr.io/shukebta/mediastation-go:latest +docker pull ghcr.io/shukebta/mmtl:latest # Docker Hub backup -docker pull shukbet/mediastationgo:latest +docker pull shukbet/mmtl:latest ``` Focus on this part: @@ -260,8 +260,8 @@ volumes: - /vol1/1000/Downloads:/downloads environment: - MEDIASTATION_MEDIA_DIR: /vol1/1000/Media - MEDIASTATION_DOWNLOAD_DIR: /vol1/1000/Downloads + MMTL_MEDIA_DIR: /vol1/1000/Media + MMTL_DOWNLOAD_DIR: /vol1/1000/Downloads ``` Rules: @@ -279,12 +279,12 @@ The root `docker-compose.yml` follows this style: ```yaml services: - mediastation-go: + mmtl: # Pick one image source: # GitHub Container Registry (GHCR): - image: ghcr.io/shukebta/mediastation-go:latest + image: ghcr.io/shukebta/mmtl:latest # Docker Hub backup: - # image: shukbet/mediastationgo:latest + # image: shukbet/mmtl:latest restart: unless-stopped init: true @@ -326,38 +326,38 @@ services: PUID: "1000" PGID: "1000" - MEDIASTATION_APP_HOST: 0.0.0.0 - MEDIASTATION_APP_PORT: 8080 - MEDIASTATION_APP_WEB_DIR: /app/web/dist - MEDIASTATION_APP_DATA_DIR: /data + MMTL_APP_HOST: 0.0.0.0 + MMTL_APP_PORT: 8080 + MMTL_APP_WEB_DIR: /app/web/dist + MMTL_APP_DATA_DIR: /data # Lightweight mode uses PostgreSQL by default. # Old SQLite data migrates from this path on first start. - MEDIASTATION_DATABASE_TYPE: postgres - MEDIASTATION_DATABASE_DSN: postgres://mediastation:mediastation@postgres:5432/mediastation?sslmode=disable + MMTL_DATABASE_TYPE: postgres + MMTL_DATABASE_DSN: postgres://mmtl:mmtl@postgres:5432/mmtl?sslmode=disable # After migration, change this to /data/disabled-sqlite-migration.db to disable the SQLite migration source. - MEDIASTATION_DATABASE_DB_PATH: /data/mediastation.db - MEDIASTATION_CACHE_CACHE_DIR: /cache + MMTL_DATABASE_DB_PATH: /data/mmtl.db + MMTL_CACHE_CACHE_DIR: /cache # Use /media and /downloads in the web UI and downloader by default. - # Only set MEDIASTATION_*_DIR to real host paths when migrating old + # Only set MMTL_*_DIR to real host paths when migrating old # libraries/tasks that already stored host paths. - MEDIASTATION_MEDIA_DIR: /media - MEDIASTATION_MEDIA_CONTAINER_DIR: /media - MEDIASTATION_DOWNLOAD_DIR: /downloads - MEDIASTATION_DOWNLOAD_CONTAINER_DIR: /downloads + MMTL_MEDIA_DIR: /media + MMTL_MEDIA_CONTAINER_DIR: /media + MMTL_DOWNLOAD_DIR: /downloads + MMTL_DOWNLOAD_CONTAINER_DIR: /downloads postgres: image: postgres:16-alpine restart: unless-stopped environment: - POSTGRES_DB: mediastation - POSTGRES_USER: mediastation - POSTGRES_PASSWORD: mediastation + POSTGRES_DB: mmtl + POSTGRES_USER: mmtl + POSTGRES_PASSWORD: mmtl volumes: - ./postgres:/var/lib/postgresql/data healthcheck: - test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -U mediastation -d mediastation"] + test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -U mmtl -d mmtl"] interval: 10s timeout: 5s retries: 10 @@ -386,7 +386,7 @@ services: 4. **Use external players** - Add the server as an Emby/Jellyfin-compatible server. - Server URL: `http://SERVER_IP:18080`. - - Use the username and password created in MediaStationGo. No separate Emby server is required. + - Use the username and password created in MMTL. No separate Emby server is required. - Admins can create regular users in the web UI or Bot so each person can log in with their own account. 5. **Use cloud playback** @@ -401,21 +401,21 @@ services: ### Update ```bash -docker compose pull mediastation-go -docker compose up -d --no-deps mediastation-go +docker compose pull mmtl +docker compose up -d --no-deps mmtl ``` ### Logs ```bash -docker compose logs -f mediastation-go +docker compose logs -f mmtl tail -f ./data/logs/app.log tail -f ./data/logs/error.log ``` -The compose templates keep full application logs in `./data/logs/app.log` and split warnings/errors into `warn.log` and `error.log`. Keep `MEDIASTATION_LOGGING_LEVEL=info` while diagnosing subscription, site search, organizer, or STRM generation issues; temporarily switch to `debug` only when deeper tracing is needed. +The compose templates keep full application logs in `./data/logs/app.log` and split warnings/errors into `warn.log` and `error.log`. Keep `MMTL_LOGGING_LEVEL=info` while diagnosing subscription, site search, organizer, or STRM generation issues; temporarily switch to `debug` only when deeper tracing is needed. -Use a writable container path for STRM output, such as `/data/strm` or a mounted media path. Deployments that previously saved `/app/data/strm` are migrated automatically to the configured `MEDIASTATION_APP_DATA_DIR`, which defaults to `/data`. +Use a writable container path for STRM output, such as `/data/strm` or a mounted media path. Deployments that previously saved `/app/data/strm` are migrated automatically to the configured `MMTL_APP_DATA_DIR`, which defaults to `/data`. ### Backup @@ -435,7 +435,7 @@ redis/ # hot cache, safe to rebuild opensearch/ # search index, rebuildable; backing it up can save reindex time on huge libraries ``` -`cache/` is usually not important. If you explicitly still use `database.type=sqlite`, the primary database remains `data/mediastation.db`. +`cache/` is usually not important. If you explicitly still use `database.type=sqlite`, the primary database remains `data/mmtl.db`. ### Stop @@ -453,7 +453,7 @@ Check the container: ```bash docker ps -docker compose logs --tail=100 mediastation-go +docker compose logs --tail=100 mmtl ``` Then open: @@ -503,7 +503,7 @@ Beginners should not. Editing `docker-compose.yml` directly is easier to underst | Libraries | Movies, TV shows, anime, variety, music, adult content | | Metadata | NFO, local artwork, TMDb, TheTVDB, Bangumi, Douban, Fanart, JavBus/JavDB | | Playback | Web playback, HTTP Range, HLS transcoding, direct links, STRMURL, 302 redirect | -| External clients | Emby-protocol compatible APIs; MediaStationGo accounts can log in to third-party players | +| External clients | Emby-protocol compatible APIs; MMTL accounts can log in to third-party players | | User management | Multi-user accounts, admin/regular users, expiry dates, device management, Bot registration and redeem codes | | Downloads | qBittorrent, site search, subscriptions, post-download organization | | File manager | Browse, organize, copy, move, hardlink, symlink | @@ -543,7 +543,7 @@ cd web && npm run build ## Community and Friends -- Telegram group: +- Telegram group: - NodeSeek: [https://www.nodeseek.com/](https://www.nodeseek.com/) - LINUX DO: [https://linux.do/](https://linux.do/) @@ -551,7 +551,7 @@ cd web && npm run build ## Donation -If MediaStationGo saves you time, feel free to buy the author a bowl of noodles. +If MMTL saves you time, feel free to buy the author a bowl of noodles. WeChat Donation QR @@ -559,11 +559,11 @@ If MediaStationGo saves you time, feel free to buy the author a bowl of noodles. ## Star History - + - - - Star History Chart + + + Star History Chart diff --git a/SECURITY.md b/SECURITY.md index bfe882f..fbdbfda 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,13 +1,13 @@ # 安全策略 -MediaStationGo 是自托管媒体系统,常部署在 NAS、家庭网络、Docker、反向代理和第三方下载器环境中。安全问题通常会同时涉及应用代码、容器配置、路径映射、站点 Cookie / API Key、下载器凭据和外部访问入口。请按本策略报告和处理安全问题。 +MMTL 是自托管媒体系统,常部署在 NAS、家庭网络、Docker、反向代理和第三方下载器环境中。安全问题通常会同时涉及应用代码、容器配置、路径映射、站点 Cookie / API Key、下载器凭据和外部访问入口。请按本策略报告和处理安全问题。 ## 支持范围 我们优先支持以下版本和部署方式的安全修复: - 当前 `main` 分支。 -- 最新发布镜像:`ghcr.io/shukebta/mediastation-go:latest`。 +- 最新发布镜像:`ghcr.io/shukebta/mmtl:latest`。 - README 中推荐的 Docker Compose 第一档、第二档、第三档部署方式。 历史版本、私有魔改镜像、未公开补丁分支和非标准部署仍可报告,但维护者可能要求先在最新 `main` 或最新镜像中复现。 @@ -16,7 +16,7 @@ MediaStationGo 是自托管媒体系统,常部署在 NAS、家庭网络、Dock 请不要在公开 Issue、PR、讨论区或群聊中披露可利用细节。优先使用 GitHub Security Advisory 私密报告: - + 如果无法使用 GitHub 私密报告,可以先通过项目 README 中的社区入口联系维护者,说明“需要私下报告安全问题”,不要直接贴出利用细节、密钥或完整日志。 @@ -68,14 +68,14 @@ MediaStationGo 是自托管媒体系统,常部署在 NAS、家庭网络、Dock ## 自托管安全基线 -部署 MediaStationGo 时建议: +部署 MMTL 时建议: - 首次登录后立即修改默认 `admin / admin123`。 - 不要把 PostgreSQL、Redis、OpenSearch、qBittorrent WebUI 暴露到公网。 - 反向代理公网访问时启用 HTTPS,并限制管理后台访问来源。 - 使用强随机的 JWT / 加密密钥,妥善备份 `./data` 和数据库。 - 不要在 Issue、PR、截图或日志中公开站点 Cookie、API Key、Passkey、下载器密码。 -- Docker `volumes` 只挂载 MediaStationGo 需要访问的目录,媒体库目录需要写入时再授予写权限。 +- Docker `volumes` 只挂载 MMTL 需要访问的目录,媒体库目录需要写入时再授予写权限。 - 定期更新镜像,并在升级前备份 `./postgres` 和 `./data`。 ## 安全修复 PR diff --git a/cmd/server/log_rotate.go b/cmd/server/log_rotate.go index ace5547..371dd01 100644 --- a/cmd/server/log_rotate.go +++ b/cmd/server/log_rotate.go @@ -7,7 +7,7 @@ import ( "sync" "time" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) const defaultLogMaxSizeMB = 20 diff --git a/cmd/server/logging.go b/cmd/server/logging.go index cc61329..90f18b5 100644 --- a/cmd/server/logging.go +++ b/cmd/server/logging.go @@ -8,7 +8,7 @@ import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) // newLogger 根据 cfg.Logging 构建 Zap。 diff --git a/cmd/server/logging_test.go b/cmd/server/logging_test.go index 5532753..c49331b 100644 --- a/cmd/server/logging_test.go +++ b/cmd/server/logging_test.go @@ -8,7 +8,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) func TestProductionLoggerWritesConfiguredInfoToAppLogAndSplitsWarnError(t *testing.T) { diff --git a/cmd/server/main.go b/cmd/server/main.go index 4725a56..91103a7 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -1,6 +1,6 @@ -// Package main is the MediaStationGo HTTP server entry point. +// Package main is the MMTL HTTP server entry point. // -// MediaStationGo is a Go rewrite of the legacy Python implementation, +// MMTL is a Go rewrite of the legacy Python implementation, // adopting the same tech stack as cropflre/nowen-video: // // Backend: Go 1.25 + Gin + GORM + PostgreSQL/SQLite + Viper + Zap + JWT @@ -24,10 +24,10 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/database" - "github.com/ShukeBta/MediaStationGo/internal/repository" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/database" + "github.com/ShukeBta/MMTL/internal/repository" + "github.com/ShukeBta/MMTL/internal/service" ) // version is overwritten at build time via -ldflags="-X main.version=...". @@ -38,7 +38,7 @@ func effectiveVersion(buildVersion string) string { if buildVersion != "" && buildVersion != "dev" { return buildVersion } - if envVersion := strings.TrimSpace(os.Getenv("MEDIASTATION_VERSION")); envVersion != "" { + if envVersion := strings.TrimSpace(os.Getenv("MMTL_VERSION")); envVersion != "" { return envVersion } if buildVersion == "" { diff --git a/cmd/server/main_test.go b/cmd/server/main_test.go index 7f1bd36..c423b48 100644 --- a/cmd/server/main_test.go +++ b/cmd/server/main_test.go @@ -12,23 +12,23 @@ import ( ) func TestEffectiveVersionPrefersBuildVersion(t *testing.T) { - t.Setenv("MEDIASTATION_VERSION", "MediaStationGo-v0.1.15") + t.Setenv("MMTL_VERSION", "MMTL-v0.1.15") - if got := effectiveVersion("MediaStationGo-v0.1.16"); got != "MediaStationGo-v0.1.16" { - t.Fatalf("effectiveVersion = %q, want MediaStationGo-v0.1.16", got) + if got := effectiveVersion("MMTL-v0.1.16"); got != "MMTL-v0.1.16" { + t.Fatalf("effectiveVersion = %q, want MMTL-v0.1.16", got) } } func TestEffectiveVersionUsesEnvWhenBuildVersionIsDev(t *testing.T) { - t.Setenv("MEDIASTATION_VERSION", " MediaStationGo-v0.1.16 ") + t.Setenv("MMTL_VERSION", " MMTL-v0.1.16 ") - if got := effectiveVersion("dev"); got != "MediaStationGo-v0.1.16" { - t.Fatalf("effectiveVersion = %q, want MediaStationGo-v0.1.16", got) + if got := effectiveVersion("dev"); got != "MMTL-v0.1.16" { + t.Fatalf("effectiveVersion = %q, want MMTL-v0.1.16", got) } } func TestEffectiveVersionDefaultsToDev(t *testing.T) { - t.Setenv("MEDIASTATION_VERSION", "") + t.Setenv("MMTL_VERSION", "") if got := effectiveVersion(""); got != "dev" { t.Fatalf("effectiveVersion = %q, want dev", got) @@ -85,7 +85,7 @@ func TestServeSPAServesAssetsImmutableAndBypassesAPIRoutes(t *testing.T) { if err := os.WriteFile(filepath.Join(webDir, "assets", "app.js"), []byte("console.log('ok')"), 0o644); err != nil { t.Fatal(err) } - if err := os.WriteFile(filepath.Join(webDir, "brand", "mediastationgo-logo.svg"), []byte(""), 0o644); err != nil { + if err := os.WriteFile(filepath.Join(webDir, "brand", "mmtl-logo.svg"), []byte(""), 0o644); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(webDir, "artwork-cache-sw.js"), []byte("self.addEventListener('fetch', () => {})"), 0o644); err != nil { @@ -105,7 +105,7 @@ func TestServeSPAServesAssetsImmutableAndBypassesAPIRoutes(t *testing.T) { t.Fatalf("asset Cache-Control = %q, want immutable", got) } - brandReq := httptest.NewRequest(http.MethodGet, "/brand/mediastationgo-logo.svg", nil) + brandReq := httptest.NewRequest(http.MethodGet, "/brand/mmtl-logo.svg", nil) brandResp := httptest.NewRecorder() router.ServeHTTP(brandResp, brandReq) if brandResp.Code != http.StatusOK { diff --git a/cmd/server/router.go b/cmd/server/router.go index 0588e9f..8ec8515 100644 --- a/cmd/server/router.go +++ b/cmd/server/router.go @@ -9,10 +9,10 @@ import ( "github.com/gin-gonic/gin" "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/handler" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/handler" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/service" ) func buildRouter(cfg *config.Config, logger *zap.Logger, svc *service.Container) *gin.Engine { @@ -79,7 +79,7 @@ func serveNoCacheFile(filePath string) gin.HandlerFunc { func serveSPAIndex(c *gin.Context, indexPath string) { setNoCacheHeaders(c) if _, err := os.Stat(indexPath); err != nil { - c.String(http.StatusNotFound, "MediaStationGo web UI not found: %s", indexPath) + c.String(http.StatusNotFound, "MMTL web UI not found: %s", indexPath) return } c.File(indexPath) diff --git a/cmd/server/startup.go b/cmd/server/startup.go index c5f415d..d14ad09 100644 --- a/cmd/server/startup.go +++ b/cmd/server/startup.go @@ -8,7 +8,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) func applyCPUThreadLimit(cfg *config.Config, logger *zap.Logger) { diff --git a/docker-compose.search.yml b/docker-compose.search.yml index 0f54308..3a5e6c5 100644 --- a/docker-compose.search.yml +++ b/docker-compose.search.yml @@ -1,7 +1,7 @@ -# MediaStationGo 第三档完整 Docker Compose 部署文件 +# MMTL 第三档完整 Docker Compose 部署文件 # # 组件: -# MediaStationGo + PostgreSQL + Redis + OpenSearch +# MMTL + PostgreSQL + Redis + OpenSearch # # 使用方式二选一: # 1. 保存为 docker-compose.yml 后执行: @@ -19,12 +19,12 @@ # admin / admin123 services: - mediastation-go: + mmtl: # 镜像二选一: # 方式一:GitHub 仓库镜像 GHCR(默认,推荐) - image: ghcr.io/shukebta/mediastation-go:latest + image: ghcr.io/shukebta/mmtl:latest # 方式二:Docker Hub 备用(GHCR 拉取慢或不可用时使用) - # image: shukbet/mediastationgo:latest + # image: shukbet/mmtl:latest restart: unless-stopped init: true @@ -78,45 +78,45 @@ services: PUID: "1000" PGID: "1000" - MEDIASTATION_APP_HOST: 0.0.0.0 - MEDIASTATION_APP_PORT: 8080 - MEDIASTATION_APP_WEB_DIR: /app/web/dist - MEDIASTATION_APP_DATA_DIR: /data - MEDIASTATION_LOGGING_LEVEL: info - MEDIASTATION_LOGGING_FORMAT: console - MEDIASTATION_LOGGING_OUTPUT_PATH: /data/logs - MEDIASTATION_LOGGING_MAX_SIZE_MB: "50" - MEDIASTATION_LOGGING_MAX_BACKUPS: "20" - MEDIASTATION_LOGGING_MAX_AGE_DAYS: "30" + MMTL_APP_HOST: 0.0.0.0 + MMTL_APP_PORT: 8080 + MMTL_APP_WEB_DIR: /app/web/dist + MMTL_APP_DATA_DIR: /data + MMTL_LOGGING_LEVEL: info + MMTL_LOGGING_FORMAT: console + MMTL_LOGGING_OUTPUT_PATH: /data/logs + MMTL_LOGGING_MAX_SIZE_MB: "50" + MMTL_LOGGING_MAX_BACKUPS: "20" + MMTL_LOGGING_MAX_AGE_DAYS: "30" - MEDIASTATION_DATABASE_TYPE: postgres - MEDIASTATION_DATABASE_DSN: postgres://mediastation:mediastation@postgres:5432/mediastation?sslmode=disable - MEDIASTATION_DATABASE_DB_PATH: /data/mediastation.db + MMTL_DATABASE_TYPE: postgres + MMTL_DATABASE_DSN: postgres://mmtl:mmtl@postgres:5432/mmtl?sslmode=disable + MMTL_DATABASE_DB_PATH: /data/mmtl.db - MEDIASTATION_CACHE_REDIS_URL: redis://redis:6379/0 - MEDIASTATION_CACHE_CACHE_DIR: /cache + MMTL_CACHE_REDIS_URL: redis://redis:6379/0 + MMTL_CACHE_CACHE_DIR: /cache # OpenSearch 只做搜索索引,主数据仍以 PostgreSQL 为准。 - MEDIASTATION_SEARCH_BACKEND: opensearch - MEDIASTATION_SEARCH_OPENSEARCH_URL: http://opensearch:9200 - MEDIASTATION_SEARCH_INDEX: mediastation_media + MMTL_SEARCH_BACKEND: opensearch + MMTL_SEARCH_OPENSEARCH_URL: http://opensearch:9200 + MMTL_SEARCH_INDEX: mmtl_media - MEDIASTATION_UPDATE_IMAGE: ghcr.io/shukebta/mediastation-go:latest + MMTL_UPDATE_IMAGE: ghcr.io/shukebta/mmtl:latest # 默认推荐在网页里使用容器路径 /media。 # 如果旧媒体库已经保存了宿主机路径 /vol1/1000/Media, # 再把这里改成同一个宿主机真实路径用于旧路径换算。 - MEDIASTATION_MEDIA_DIR: /media - MEDIASTATION_MEDIA_CONTAINER_DIR: /media - MEDIASTATION_DOWNLOAD_DIR: /downloads - MEDIASTATION_DOWNLOAD_CONTAINER_DIR: /downloads + MMTL_MEDIA_DIR: /media + MMTL_MEDIA_CONTAINER_DIR: /media + MMTL_DOWNLOAD_DIR: /downloads + MMTL_DOWNLOAD_CONTAINER_DIR: /downloads - MEDIASTATION_TRANSCODER_ENABLED: "true" - MEDIASTATION_TRANSCODER_HARDWARE_ACCEL: "false" - MEDIASTATION_TRANSCODER_REALTIME: "true" - MEDIASTATION_TRANSCODER_THREADS: "2" - MEDIASTATION_TRANSCODER_MAX_CONCURRENT: "1" - MEDIASTATION_TRANSCODER_IDLE_TIMEOUT_SECONDS: "120" + MMTL_TRANSCODER_ENABLED: "true" + MMTL_TRANSCODER_HARDWARE_ACCEL: "false" + MMTL_TRANSCODER_REALTIME: "true" + MMTL_TRANSCODER_THREADS: "2" + MMTL_TRANSCODER_MAX_CONCURRENT: "1" + MMTL_TRANSCODER_IDLE_TIMEOUT_SECONDS: "120" healthcheck: test: ["CMD-SHELL", "busybox wget -qO- http://127.0.0.1:8080/api/health || exit 1"] @@ -133,18 +133,18 @@ services: postgres: image: postgres:16-alpine - # 首次部署允许拉取;日常更新请只 pull mediastation-go。 + # 首次部署允许拉取;日常更新请只 pull mmtl。 pull_policy: missing restart: unless-stopped environment: - POSTGRES_DB: mediastation - POSTGRES_USER: mediastation - POSTGRES_PASSWORD: mediastation + POSTGRES_DB: mmtl + POSTGRES_USER: mmtl + POSTGRES_PASSWORD: mmtl TZ: Asia/Shanghai volumes: - ./postgres:/var/lib/postgresql/data healthcheck: - test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -U mediastation -d mediastation"] + test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -U mmtl -d mmtl"] interval: 10s timeout: 5s retries: 10 diff --git a/docker-compose.simple.yml b/docker-compose.simple.yml index 449bca5..f3bbc01 100644 --- a/docker-compose.simple.yml +++ b/docker-compose.simple.yml @@ -1,4 +1,4 @@ -# MediaStationGo 单镜像部署模板(SQLite) +# MMTL 单镜像部署模板(SQLite) # # 适合:新手、单人使用、低配 NAS / 小主机。 # 特点:只有一个镜像,不需要 PostgreSQL / Redis / .env。 @@ -12,12 +12,12 @@ # 首次登录后请立刻修改密码。 services: - mediastation-go: - image: ghcr.io/shukebta/mediastation-go:latest + mmtl: + image: ghcr.io/shukebta/mmtl:latest # Docker Hub 备用: - # image: shukbet/mediastationgo:latest + # image: shukbet/mmtl:latest - container_name: mediastation-go + container_name: mmtl restart: unless-stopped init: true @@ -64,29 +64,29 @@ services: PUID: "1000" PGID: "1000" - MEDIASTATION_APP_HOST: 0.0.0.0 - MEDIASTATION_APP_PORT: 8080 - MEDIASTATION_APP_WEB_DIR: /app/web/dist - MEDIASTATION_APP_DATA_DIR: /data + MMTL_APP_HOST: 0.0.0.0 + MMTL_APP_PORT: 8080 + MMTL_APP_WEB_DIR: /app/web/dist + MMTL_APP_DATA_DIR: /data - # 单镜像档固定使用 SQLite。主数据库文件:./data/mediastation.db。 - MEDIASTATION_DATABASE_TYPE: sqlite - MEDIASTATION_DATABASE_DB_PATH: /data/mediastation.db - MEDIASTATION_CACHE_CACHE_DIR: /cache + # 单镜像档固定使用 SQLite。主数据库文件:./data/mmtl.db。 + MMTL_DATABASE_TYPE: sqlite + MMTL_DATABASE_DB_PATH: /data/mmtl.db + MMTL_CACHE_CACHE_DIR: /cache # 路径映射保持容器内统一,网页和下载器里优先使用 /media、/downloads。 - MEDIASTATION_MEDIA_DIR: /media - MEDIASTATION_MEDIA_CONTAINER_DIR: /media - MEDIASTATION_DOWNLOAD_DIR: /downloads - MEDIASTATION_DOWNLOAD_CONTAINER_DIR: /downloads + MMTL_MEDIA_DIR: /media + MMTL_MEDIA_CONTAINER_DIR: /media + MMTL_DOWNLOAD_DIR: /downloads + MMTL_DOWNLOAD_CONTAINER_DIR: /downloads # 完整应用日志默认写入 ./data/logs/app.log;排查复杂问题时可临时改成 debug。 - MEDIASTATION_LOGGING_LEVEL: info - MEDIASTATION_LOGGING_FORMAT: console - MEDIASTATION_LOGGING_OUTPUT_PATH: /data/logs - MEDIASTATION_LOGGING_MAX_SIZE_MB: "50" - MEDIASTATION_LOGGING_MAX_BACKUPS: "20" - MEDIASTATION_LOGGING_MAX_AGE_DAYS: "30" + MMTL_LOGGING_LEVEL: info + MMTL_LOGGING_FORMAT: console + MMTL_LOGGING_OUTPUT_PATH: /data/logs + MMTL_LOGGING_MAX_SIZE_MB: "50" + MMTL_LOGGING_MAX_BACKUPS: "20" + MMTL_LOGGING_MAX_AGE_DAYS: "30" extra_hosts: # 容器访问宿主机服务用,例如 qBittorrent: http://host.docker.internal:8085 diff --git a/docker-compose.standard.yml b/docker-compose.standard.yml index 116361e..d523fe0 100644 --- a/docker-compose.standard.yml +++ b/docker-compose.standard.yml @@ -1,7 +1,7 @@ -# MediaStationGo 第二档完整 Docker Compose 部署文件 +# MMTL 第二档完整 Docker Compose 部署文件 # # 组件: -# MediaStationGo + PostgreSQL + Redis +# MMTL + PostgreSQL + Redis # # 使用方式二选一: # 1. 保存为 docker-compose.yml 后执行: @@ -16,12 +16,12 @@ # admin / admin123 services: - mediastation-go: + mmtl: # 镜像二选一: # 方式一:GitHub 仓库镜像 GHCR(默认,推荐) - image: ghcr.io/shukebta/mediastation-go:latest + image: ghcr.io/shukebta/mmtl:latest # 方式二:Docker Hub 备用(GHCR 拉取慢或不可用时使用) - # image: shukbet/mediastationgo:latest + # image: shukbet/mmtl:latest restart: unless-stopped init: true @@ -73,39 +73,39 @@ services: PUID: "1000" PGID: "1000" - MEDIASTATION_APP_HOST: 0.0.0.0 - MEDIASTATION_APP_PORT: 8080 - MEDIASTATION_APP_WEB_DIR: /app/web/dist - MEDIASTATION_APP_DATA_DIR: /data - MEDIASTATION_LOGGING_LEVEL: info - MEDIASTATION_LOGGING_FORMAT: console - MEDIASTATION_LOGGING_OUTPUT_PATH: /data/logs - MEDIASTATION_LOGGING_MAX_SIZE_MB: "50" - MEDIASTATION_LOGGING_MAX_BACKUPS: "20" - MEDIASTATION_LOGGING_MAX_AGE_DAYS: "30" + MMTL_APP_HOST: 0.0.0.0 + MMTL_APP_PORT: 8080 + MMTL_APP_WEB_DIR: /app/web/dist + MMTL_APP_DATA_DIR: /data + MMTL_LOGGING_LEVEL: info + MMTL_LOGGING_FORMAT: console + MMTL_LOGGING_OUTPUT_PATH: /data/logs + MMTL_LOGGING_MAX_SIZE_MB: "50" + MMTL_LOGGING_MAX_BACKUPS: "20" + MMTL_LOGGING_MAX_AGE_DAYS: "30" - MEDIASTATION_DATABASE_TYPE: postgres - MEDIASTATION_DATABASE_DSN: postgres://mediastation:mediastation@postgres:5432/mediastation?sslmode=disable - MEDIASTATION_DATABASE_DB_PATH: /data/mediastation.db + MMTL_DATABASE_TYPE: postgres + MMTL_DATABASE_DSN: postgres://mmtl:mmtl@postgres:5432/mmtl?sslmode=disable + MMTL_DATABASE_DB_PATH: /data/mmtl.db # Redis 只做热缓存,源数据仍在 PostgreSQL;Redis 丢失可自动重建。 - MEDIASTATION_CACHE_REDIS_URL: redis://redis:6379/0 - MEDIASTATION_CACHE_CACHE_DIR: /cache + MMTL_CACHE_REDIS_URL: redis://redis:6379/0 + MMTL_CACHE_CACHE_DIR: /cache - MEDIASTATION_UPDATE_IMAGE: ghcr.io/shukebta/mediastation-go:latest + MMTL_UPDATE_IMAGE: ghcr.io/shukebta/mmtl:latest # 路径换算配置。左边宿主机真实路径要和 volumes 左边保持一致。 - MEDIASTATION_MEDIA_DIR: /media - MEDIASTATION_MEDIA_CONTAINER_DIR: /media - MEDIASTATION_DOWNLOAD_DIR: /downloads - MEDIASTATION_DOWNLOAD_CONTAINER_DIR: /downloads + MMTL_MEDIA_DIR: /media + MMTL_MEDIA_CONTAINER_DIR: /media + MMTL_DOWNLOAD_DIR: /downloads + MMTL_DOWNLOAD_CONTAINER_DIR: /downloads - MEDIASTATION_TRANSCODER_ENABLED: "true" - MEDIASTATION_TRANSCODER_HARDWARE_ACCEL: "false" - MEDIASTATION_TRANSCODER_REALTIME: "true" - MEDIASTATION_TRANSCODER_THREADS: "2" - MEDIASTATION_TRANSCODER_MAX_CONCURRENT: "1" - MEDIASTATION_TRANSCODER_IDLE_TIMEOUT_SECONDS: "120" + MMTL_TRANSCODER_ENABLED: "true" + MMTL_TRANSCODER_HARDWARE_ACCEL: "false" + MMTL_TRANSCODER_REALTIME: "true" + MMTL_TRANSCODER_THREADS: "2" + MMTL_TRANSCODER_MAX_CONCURRENT: "1" + MMTL_TRANSCODER_IDLE_TIMEOUT_SECONDS: "120" healthcheck: test: ["CMD-SHELL", "busybox wget -qO- http://127.0.0.1:8080/api/health || exit 1"] @@ -122,18 +122,18 @@ services: postgres: image: postgres:16-alpine - # 首次部署允许拉取;日常更新请只 pull mediastation-go。 + # 首次部署允许拉取;日常更新请只 pull mmtl。 pull_policy: missing restart: unless-stopped environment: - POSTGRES_DB: mediastation - POSTGRES_USER: mediastation - POSTGRES_PASSWORD: mediastation + POSTGRES_DB: mmtl + POSTGRES_USER: mmtl + POSTGRES_PASSWORD: mmtl TZ: Asia/Shanghai volumes: - ./postgres:/var/lib/postgresql/data healthcheck: - test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -U mediastation -d mediastation"] + test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -U mmtl -d mmtl"] interval: 10s timeout: 5s retries: 10 diff --git a/docker-compose.yml b/docker-compose.yml index 4ea52aa..4f06234 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,4 @@ -# MediaStationGo 最简单 Docker Compose 部署文件 +# MMTL 最简单 Docker Compose 部署文件 # # 新手建议: # 1. 不用 .env。 @@ -15,12 +15,12 @@ # admin / admin123 services: - mediastation-go: + mmtl: # 镜像二选一: # 方式一:GitHub 仓库镜像 GHCR(默认,推荐) - image: ghcr.io/shukebta/mediastation-go:latest + image: ghcr.io/shukebta/mmtl:latest # 方式二:Docker Hub 备用(GHCR 拉取慢或不可用时使用) - # image: shukbet/mediastationgo:latest + # image: shukbet/mmtl:latest restart: unless-stopped init: true @@ -87,52 +87,52 @@ services: PGID: "1000" # 程序基础配置,通常不用改。 - MEDIASTATION_APP_HOST: 0.0.0.0 - MEDIASTATION_APP_PORT: 8080 - MEDIASTATION_APP_WEB_DIR: /app/web/dist - MEDIASTATION_APP_DATA_DIR: /data + MMTL_APP_HOST: 0.0.0.0 + MMTL_APP_PORT: 8080 + MMTL_APP_WEB_DIR: /app/web/dist + MMTL_APP_DATA_DIR: /data # 详细应用日志会保存在 ./data/logs/app.log,warn/error 也会拆分保存。 # 排查复杂问题时可临时改成 debug。 - MEDIASTATION_LOGGING_LEVEL: info - MEDIASTATION_LOGGING_FORMAT: console - MEDIASTATION_LOGGING_OUTPUT_PATH: /data/logs - MEDIASTATION_LOGGING_MAX_SIZE_MB: "50" - MEDIASTATION_LOGGING_MAX_BACKUPS: "20" - MEDIASTATION_LOGGING_MAX_AGE_DAYS: "30" + MMTL_LOGGING_LEVEL: info + MMTL_LOGGING_FORMAT: console + MMTL_LOGGING_OUTPUT_PATH: /data/logs + MMTL_LOGGING_MAX_SIZE_MB: "50" + MMTL_LOGGING_MAX_BACKUPS: "20" + MMTL_LOGGING_MAX_AGE_DAYS: "30" # 轻量模式默认只使用 PostgreSQL,适合大多数 NAS。 - # 旧版 ./data/mediastation.db 存在时,首次启动会自动迁移到 PostgreSQL。 - MEDIASTATION_DATABASE_TYPE: postgres - MEDIASTATION_DATABASE_DSN: postgres://mediastation:mediastation@postgres:5432/mediastation?sslmode=disable + # 旧版 ./data/mmtl.db 存在时,首次启动会自动迁移到 PostgreSQL。 + MMTL_DATABASE_TYPE: postgres + MMTL_DATABASE_DSN: postgres://mmtl:mmtl@postgres:5432/mmtl?sslmode=disable # SQLite 旧库迁移源: - # - 首次从旧版 ./data/mediastation.db 导入时保持此路径。 + # - 首次从旧版 ./data/mmtl.db 导入时保持此路径。 # - 确认迁移完成后,建议改成 /data/no-sqlite-migration.db 这类不存在的路径。 - MEDIASTATION_DATABASE_DB_PATH: /data/mediastation.db - MEDIASTATION_CACHE_CACHE_DIR: /cache + MMTL_DATABASE_DB_PATH: /data/mmtl.db + MMTL_CACHE_CACHE_DIR: /cache # 管理面板热更新默认拉取此镜像,并用 Watchtower 一次性重建当前容器。 - MEDIASTATION_UPDATE_IMAGE: ghcr.io/shukebta/mediastation-go:latest + MMTL_UPDATE_IMAGE: ghcr.io/shukebta/mmtl:latest # 路径换算配置。 # 默认推荐在网页里使用容器路径 /media。 # 如果旧媒体库已经保存了宿主机路径 /vol1/1000/Media, # 再把这里改成同一个宿主机真实路径用于旧路径换算。 - MEDIASTATION_MEDIA_DIR: /media - MEDIASTATION_MEDIA_CONTAINER_DIR: /media + MMTL_MEDIA_DIR: /media + MMTL_MEDIA_CONTAINER_DIR: /media # 默认推荐下载器保存路径使用 /downloads。 # 如果下载器只能返回宿主机路径,再改成同一个宿主机真实路径。 - MEDIASTATION_DOWNLOAD_DIR: /downloads - MEDIASTATION_DOWNLOAD_CONTAINER_DIR: /downloads + MMTL_DOWNLOAD_DIR: /downloads + MMTL_DOWNLOAD_CONTAINER_DIR: /downloads # NAS 友好的低负载默认值。 - MEDIASTATION_TRANSCODER_ENABLED: "true" - MEDIASTATION_TRANSCODER_HARDWARE_ACCEL: "false" - MEDIASTATION_TRANSCODER_REALTIME: "true" - MEDIASTATION_TRANSCODER_THREADS: "2" - MEDIASTATION_TRANSCODER_MAX_CONCURRENT: "1" - MEDIASTATION_TRANSCODER_IDLE_TIMEOUT_SECONDS: "120" + MMTL_TRANSCODER_ENABLED: "true" + MMTL_TRANSCODER_HARDWARE_ACCEL: "false" + MMTL_TRANSCODER_REALTIME: "true" + MMTL_TRANSCODER_THREADS: "2" + MMTL_TRANSCODER_MAX_CONCURRENT: "1" + MMTL_TRANSCODER_IDLE_TIMEOUT_SECONDS: "120" healthcheck: test: ["CMD-SHELL", "busybox wget -qO- http://127.0.0.1:8080/api/health || exit 1"] @@ -150,20 +150,20 @@ services: postgres: image: postgres:16-alpine - # 首次部署允许拉取;日常更新请只 pull mediastation-go。 + # 首次部署允许拉取;日常更新请只 pull mmtl。 # 如需升级 PostgreSQL,请先备份 ./postgres 后再手动调整镜像版本并拉取。 pull_policy: missing restart: unless-stopped environment: - POSTGRES_DB: mediastation - POSTGRES_USER: mediastation - POSTGRES_PASSWORD: mediastation + POSTGRES_DB: mmtl + POSTGRES_USER: mmtl + POSTGRES_PASSWORD: mmtl TZ: Asia/Shanghai volumes: # PostgreSQL 主数据目录。升级/重建容器时必须保留。 - ./postgres:/var/lib/postgresql/data healthcheck: - test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -U mediastation -d mediastation"] + test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -U mmtl -d mmtl"] interval: 10s timeout: 5s retries: 10 diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index ed4000e..05ef2c8 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -1,8 +1,8 @@ #!/bin/sh set -eu -run_uid="${PUID:-$(id -u mediastation 2>/dev/null || echo 1000)}" -run_gid="${PGID:-$(id -g mediastation 2>/dev/null || echo 1000)}" +run_uid="${PUID:-$(id -u mmtl 2>/dev/null || echo 1000)}" +run_gid="${PGID:-$(id -g mmtl 2>/dev/null || echo 1000)}" case "$run_uid" in ''|*[!0-9]*) @@ -19,10 +19,10 @@ case "$run_gid" in esac if [ "$run_uid" = "0" ]; then - exec mediastation-go + exec mmtl fi chown -R "$run_uid:$run_gid" /data /cache 2>/dev/null || true chown "$run_uid:$run_gid" /media 2>/dev/null || true -exec su-exec "$run_uid:$run_gid" mediastation-go +exec su-exec "$run_uid:$run_gid" mmtl diff --git a/go.mod b/go.mod index 69560fd..fd609b9 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/ShukeBta/MediaStationGo +module github.com/ShukeBta/MMTL go 1.25.0 diff --git a/internal/config/config.go b/internal/config/config.go index bea13ec..c1a58fd 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -4,7 +4,7 @@ // 1. 内置默认值 // 2. 工作目录中的 config.yaml(嵌套格式) // 3. config/*.yaml 分片文件(按模块) -// 4. 以 MEDIASTATION_ 为前缀的环境变量 +// 4. 以 MMTL_ 为前缀的环境变量 package config import ( @@ -17,7 +17,7 @@ import ( ) // EnvPrefix 是所有环境变量驱动的覆盖使用的前缀。 -const EnvPrefix = "MEDIASTATION" +const EnvPrefix = "MMTL" // Load 从默认值 / 文件 / 环境读取配置。 // diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 93d7342..ca61bbb 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -40,15 +40,15 @@ func TestLoadDefaults(t *testing.T) { if cfg.Database.MaxOpenConns != defaultDatabaseMaxOpenConns { t.Fatalf("expected default MaxOpenConns %d, got %d", defaultDatabaseMaxOpenConns, cfg.Database.MaxOpenConns) } - if cfg.Cache.RedisPrefix != "mediastationgo" { - t.Fatalf("expected default redis prefix, got %q", cfg.Cache.RedisPrefix) - } - if cfg.Cache.MediaTTLSeconds != 15 { - t.Fatalf("expected default media cache ttl 15, got %d", cfg.Cache.MediaTTLSeconds) - } - if cfg.Search.Index != "mediastation_media" { - t.Fatalf("expected default search index, got %q", cfg.Search.Index) - } + if cfg.Cache.RedisPrefix != "mmtl" { + t.Fatalf("expected default redis prefix, got %q", cfg.Cache.RedisPrefix) + } + if cfg.Cache.MediaTTLSeconds != 15 { + t.Fatalf("expected default media cache ttl 15, got %d", cfg.Cache.MediaTTLSeconds) + } + if cfg.Search.Index != "mmtl_media" { + t.Fatalf("expected default search index, got %q", cfg.Search.Index) + } if cfg.Database.MaxIdleConns != defaultDatabaseMaxIdleConns { t.Fatalf("expected default MaxIdleConns %d, got %d", defaultDatabaseMaxIdleConns, cfg.Database.MaxIdleConns) } @@ -74,7 +74,7 @@ func TestLoadDefaults(t *testing.T) { } } -// TestEnvOverride checks that MEDIASTATION_* env vars override the defaults. +// TestEnvOverride checks that MMTL_* env vars override the defaults. func TestEnvOverride(t *testing.T) { dir := t.TempDir() wd, _ := os.Getwd() @@ -83,16 +83,16 @@ func TestEnvOverride(t *testing.T) { t.Fatalf("chdir: %v", err) } - t.Setenv("MEDIASTATION_APP_PORT", "9090") - t.Setenv("MEDIASTATION_DATABASE_TYPE", "postgres") - t.Setenv("MEDIASTATION_DATABASE_DSN", "postgres://msgo:secret@postgres:5432/msgo?sslmode=disable") - t.Setenv("MEDIASTATION_CACHE_REDIS_URL", "redis://redis:6379/0") - t.Setenv("MEDIASTATION_CACHE_MEDIA_TTL_SECONDS", "30") - t.Setenv("MEDIASTATION_SEARCH_BACKEND", "opensearch") - t.Setenv("MEDIASTATION_SEARCH_OPENSEARCH_URL", "http://opensearch:9200") - t.Setenv("MEDIASTATION_LICENSE_SERVER_URL", "https://license.example.com") - t.Setenv("MEDIASTATION_LICENSE_HMAC_SECRET", "override-secret") - t.Setenv("MEDIASTATION_LICENSE_PUBLIC_KEY", "override-public-key") + t.Setenv("MMTL_APP_PORT", "9090") + t.Setenv("MMTL_DATABASE_TYPE", "postgres") + t.Setenv("MMTL_DATABASE_DSN", "postgres://mmtl:secret@postgres:5432/mmtl?sslmode=disable") + t.Setenv("MMTL_CACHE_REDIS_URL", "redis://redis:6379/0") + t.Setenv("MMTL_CACHE_MEDIA_TTL_SECONDS", "30") + t.Setenv("MMTL_SEARCH_BACKEND", "opensearch") + t.Setenv("MMTL_SEARCH_OPENSEARCH_URL", "http://opensearch:9200") + t.Setenv("MMTL_LICENSE_SERVER_URL", "https://license.example.com") + t.Setenv("MMTL_LICENSE_HMAC_SECRET", "override-secret") + t.Setenv("MMTL_LICENSE_PUBLIC_KEY", "override-public-key") cfg, err := Load() if err != nil { t.Fatalf("Load() error: %v", err) diff --git a/internal/config/defaults.go b/internal/config/defaults.go index 7992379..7f273aa 100644 --- a/internal/config/defaults.go +++ b/internal/config/defaults.go @@ -25,7 +25,7 @@ func setDefaults(v *viper.Viper) { v.SetDefault("app.server_url", "") v.SetDefault("database.type", "auto") - v.SetDefault("database.db_path", "./data/mediastation.db") + v.SetDefault("database.db_path", "./data/mmtl.db") v.SetDefault("database.dsn", "") v.SetDefault("database.wal_mode", true) v.SetDefault("database.busy_timeout", 5000) @@ -45,12 +45,12 @@ func setDefaults(v *viper.Viper) { v.SetDefault("cache.cache_dir", "./cache") v.SetDefault("cache.cleanup_interval_min", 60) v.SetDefault("cache.redis_url", "") - v.SetDefault("cache.redis_prefix", "mediastationgo") + v.SetDefault("cache.redis_prefix", "mmtl") v.SetDefault("cache.media_ttl_seconds", 15) v.SetDefault("search.backend", "") v.SetDefault("search.opensearch_url", "") - v.SetDefault("search.index", "mediastation_media") + v.SetDefault("search.index", "mmtl_media") v.SetDefault("search.username", "") v.SetDefault("search.password", "") @@ -63,7 +63,7 @@ func setDefaults(v *viper.Viper) { v.SetDefault("flaresolverr.enabled", false) v.SetDefault("flaresolverr.url", "http://localhost:8191") - v.SetDefault("flaresolverr.session", "mediastation") + v.SetDefault("flaresolverr.session", "mmtl") v.SetDefault("flaresolverr.timeout", 60) v.SetDefault("downloads.smart_classify", true) diff --git a/internal/config/normalize.go b/internal/config/normalize.go index 8e42f0d..6eaea21 100644 --- a/internal/config/normalize.go +++ b/internal/config/normalize.go @@ -15,7 +15,7 @@ func (c *Config) normalize() error { c.App.DataDir = "./data" } if c.Database.DBPath == "" { - c.Database.DBPath = filepath.Join(c.App.DataDir, "mediastation.db") + c.Database.DBPath = filepath.Join(c.App.DataDir, "mmtl.db") } if c.Database.Type == "" { c.Database.Type = "auto" @@ -45,14 +45,14 @@ func (c *Config) normalize() error { c.Cache.CacheDir = filepath.Join(c.App.DataDir, "cache") } if c.Cache.RedisPrefix == "" { - c.Cache.RedisPrefix = "mediastationgo" + c.Cache.RedisPrefix = "mmtl" } if c.Cache.MediaTTLSeconds < 1 { c.Cache.MediaTTLSeconds = 15 } c.Search.Backend = strings.ToLower(strings.TrimSpace(c.Search.Backend)) if c.Search.Index == "" { - c.Search.Index = "mediastation_media" + c.Search.Index = "mmtl_media" } if c.Secrets.JWTSecret == "" { // 持久化自动生成的密钥以在操作员忘记配置时保持会话稳定。 diff --git a/internal/config/types.go b/internal/config/types.go index 6326ccd..fc3c3ac 100644 --- a/internal/config/types.go +++ b/internal/config/types.go @@ -140,7 +140,7 @@ type AIConfig struct { MaxConcurrent int `mapstructure:"max_concurrent"` } -// LicenseConfig configures the optional MediaStationGo license server bridge. +// LicenseConfig configures the optional MMTL license server bridge. type LicenseConfig struct { ServerURL string `mapstructure:"server_url"` HMACSecret string `mapstructure:"hmac_secret"` diff --git a/internal/database/database.go b/internal/database/database.go index e56b661..96aff92 100644 --- a/internal/database/database.go +++ b/internal/database/database.go @@ -13,7 +13,7 @@ import ( "gorm.io/gorm" "gorm.io/gorm/logger" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) // Open initialises the configured GORM database. database.type=auto chooses diff --git a/internal/database/database_test.go b/internal/database/database_test.go index 892fc22..8b9f098 100644 --- a/internal/database/database_test.go +++ b/internal/database/database_test.go @@ -8,8 +8,8 @@ import ( "github.com/glebarez/sqlite" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" ) func TestOpenRequiresConfig(t *testing.T) { @@ -28,7 +28,7 @@ func TestOpenRequiresConfig(t *testing.T) { func TestOpenSQLiteWithNilLoggerConfiguresPool(t *testing.T) { cfg := &config.Config{} cfg.Database.Type = "sqlite" - cfg.Database.DBPath = filepath.Join(t.TempDir(), "mediastation.db") + cfg.Database.DBPath = filepath.Join(t.TempDir(), "mmtl.db") cfg.Database.WALMode = true cfg.Database.BusyTimeout = 5000 cfg.Database.CacheSize = -2000 @@ -278,7 +278,7 @@ func TestSQLiteMigrationCompleteMarker(t *testing.T) { func TestSQLiteMigrationFallsBackToDataDirDefaultPath(t *testing.T) { dir := t.TempDir() - sqlitePath := filepath.Join(dir, "mediastation.db") + sqlitePath := filepath.Join(dir, "mmtl.db") src, err := gorm.Open(sqlite.Open(sqlitePath), &gorm.Config{}) if err != nil { t.Fatal(err) @@ -362,7 +362,7 @@ func TestSQLiteMigrationFallsBackToDataDirDefaultPath(t *testing.T) { func TestOpenSQLiteMigrationSourceUsesFallbackSourcePath(t *testing.T) { dir := t.TempDir() - sqlitePath := filepath.Join(dir, "mediastation.db") + sqlitePath := filepath.Join(dir, "mmtl.db") src, err := gorm.Open(sqlite.Open(sqlitePath), &gorm.Config{}) if err != nil { t.Fatal(err) diff --git a/internal/database/schema_library_roots.go b/internal/database/schema_library_roots.go index 2d45171..2dd2b10 100644 --- a/internal/database/schema_library_roots.go +++ b/internal/database/schema_library_roots.go @@ -6,7 +6,7 @@ import ( "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func ensureLibraryRootsCompatibility(db *gorm.DB) error { diff --git a/internal/database/schema_migration.go b/internal/database/schema_migration.go index e58b799..c335b78 100644 --- a/internal/database/schema_migration.go +++ b/internal/database/schema_migration.go @@ -3,7 +3,7 @@ package database import ( "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // AutoMigrate creates tables for every model registered in the model package. diff --git a/internal/database/sqlite_migration.go b/internal/database/sqlite_migration.go index e46908b..29f92f6 100644 --- a/internal/database/sqlite_migration.go +++ b/internal/database/sqlite_migration.go @@ -7,7 +7,7 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) // MigrateSQLiteToCurrentIfNeeded copies an existing SQLite database into diff --git a/internal/database/sqlite_migration_bootstrap.go b/internal/database/sqlite_migration_bootstrap.go index 33db6f9..604a3bd 100644 --- a/internal/database/sqlite_migration_bootstrap.go +++ b/internal/database/sqlite_migration_bootstrap.go @@ -9,7 +9,7 @@ import ( "gorm.io/gorm" "gorm.io/gorm/clause" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func resetBootstrapTargetBeforeSQLiteMigrationIfSafe(src, target *gorm.DB, log *zap.Logger) error { diff --git a/internal/database/sqlite_migration_copy.go b/internal/database/sqlite_migration_copy.go index 0cb891f..fbf3f8c 100644 --- a/internal/database/sqlite_migration_copy.go +++ b/internal/database/sqlite_migration_copy.go @@ -10,7 +10,7 @@ import ( "gorm.io/gorm/clause" "gorm.io/gorm/schema" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func copyModelTables(src, target *gorm.DB, batchSize int) (int64, error) { diff --git a/internal/database/sqlite_migration_source.go b/internal/database/sqlite_migration_source.go index daca3ec..8bb1171 100644 --- a/internal/database/sqlite_migration_source.go +++ b/internal/database/sqlite_migration_source.go @@ -12,7 +12,7 @@ import ( "gorm.io/gorm" "gorm.io/gorm/logger" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) func openSQLiteMigrationSource(cfg *config.Config, sqlitePath string) (*gorm.DB, error) { @@ -36,7 +36,7 @@ func sqliteMigrationSourcePath(cfg *config.Config, log *zap.Logger) (string, err } } - fallback := filepath.Join(strings.TrimSpace(cfg.App.DataDir), "mediastation.db") + fallback := filepath.Join(strings.TrimSpace(cfg.App.DataDir), "mmtl.db") if fallback == "" || sameCleanPath(configured, fallback) { return "", nil } diff --git a/internal/database/sqlite_runtime.go b/internal/database/sqlite_runtime.go index f18247e..57b1f7c 100644 --- a/internal/database/sqlite_runtime.go +++ b/internal/database/sqlite_runtime.go @@ -7,14 +7,14 @@ import ( "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) func installSQLiteWriteGate(db *gorm.DB) { if db == nil { return } - const lockedKey = "mediastation:sqlite_write_locked" + const lockedKey = "mmtl:sqlite_write_locked" gate := newSQLiteWriteGate() lock := func(tx *gorm.DB) { ctx := context.Background() @@ -32,14 +32,14 @@ func installSQLiteWriteGate(db *gorm.DB) { gate.Unlock() } } - _ = db.Callback().Create().Before("gorm:create").Register("mediastation:sqlite_write_lock", lock) - _ = db.Callback().Create().After("gorm:create").Register("mediastation:sqlite_write_unlock", unlock) - _ = db.Callback().Update().Before("gorm:update").Register("mediastation:sqlite_write_lock", lock) - _ = db.Callback().Update().After("gorm:update").Register("mediastation:sqlite_write_unlock", unlock) - _ = db.Callback().Delete().Before("gorm:delete").Register("mediastation:sqlite_write_lock", lock) - _ = db.Callback().Delete().After("gorm:delete").Register("mediastation:sqlite_write_unlock", unlock) - _ = db.Callback().Raw().Before("gorm:raw").Register("mediastation:sqlite_write_lock", lock) - _ = db.Callback().Raw().After("gorm:raw").Register("mediastation:sqlite_write_unlock", unlock) + _ = db.Callback().Create().Before("gorm:create").Register("mmtl:sqlite_write_lock", lock) + _ = db.Callback().Create().After("gorm:create").Register("mmtl:sqlite_write_unlock", unlock) + _ = db.Callback().Update().Before("gorm:update").Register("mmtl:sqlite_write_lock", lock) + _ = db.Callback().Update().After("gorm:update").Register("mmtl:sqlite_write_unlock", unlock) + _ = db.Callback().Delete().Before("gorm:delete").Register("mmtl:sqlite_write_lock", lock) + _ = db.Callback().Delete().After("gorm:delete").Register("mmtl:sqlite_write_unlock", unlock) + _ = db.Callback().Raw().Before("gorm:raw").Register("mmtl:sqlite_write_lock", lock) + _ = db.Callback().Raw().After("gorm:raw").Register("mmtl:sqlite_write_unlock", unlock) } // sqliteWriteGate serializes in-process SQLite writes while respecting the diff --git a/internal/handler/active_user.go b/internal/handler/active_user.go index 662507c..61fdd93 100644 --- a/internal/handler/active_user.go +++ b/internal/handler/active_user.go @@ -6,8 +6,8 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/service" ) const embyCtxUserName = "emby_user_name" diff --git a/internal/handler/admin.go b/internal/handler/admin.go index a1ed07c..5449f23 100644 --- a/internal/handler/admin.go +++ b/internal/handler/admin.go @@ -9,8 +9,8 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/service" ) func listUsersHandler(svc *service.Container) gin.HandlerFunc { diff --git a/internal/handler/admin_settings.go b/internal/handler/admin_settings.go index ed8afbb..734b363 100644 --- a/internal/handler/admin_settings.go +++ b/internal/handler/admin_settings.go @@ -9,8 +9,8 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/service" ) type settingReq struct { diff --git a/internal/handler/admin_test.go b/internal/handler/admin_test.go index d3a984e..5d31a46 100644 --- a/internal/handler/admin_test.go +++ b/internal/handler/admin_test.go @@ -10,9 +10,9 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" + "github.com/ShukeBta/MMTL/internal/service" ) func TestDeleteUserRefusesRecentRealtimeSession(t *testing.T) { diff --git a/internal/handler/api_config.go b/internal/handler/api_config.go index 2521ce9..f80746f 100644 --- a/internal/handler/api_config.go +++ b/internal/handler/api_config.go @@ -9,7 +9,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) func listAPIConfigsHandler(svc *service.Container) gin.HandlerFunc { diff --git a/internal/handler/api_config_handler.go b/internal/handler/api_config_handler.go index 3ff3156..f186722 100644 --- a/internal/handler/api_config_handler.go +++ b/internal/handler/api_config_handler.go @@ -7,7 +7,7 @@ import ( "github.com/gin-gonic/gin" "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) // ApiConfigHandler API 配置 HTTP 处理。 diff --git a/internal/handler/auth.go b/internal/handler/auth.go index 41547c5..3bc47c9 100644 --- a/internal/handler/auth.go +++ b/internal/handler/auth.go @@ -7,8 +7,8 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/service" ) type loginReq struct { diff --git a/internal/handler/auth_cookie.go b/internal/handler/auth_cookie.go index 0fe3c88..a4ae747 100644 --- a/internal/handler/auth_cookie.go +++ b/internal/handler/auth_cookie.go @@ -7,8 +7,8 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/service" ) func setAccessTokenCookie(c *gin.Context, token string, maxAgeSeconds int) { diff --git a/internal/handler/auth_cookie_test.go b/internal/handler/auth_cookie_test.go index 3440bd4..7494217 100644 --- a/internal/handler/auth_cookie_test.go +++ b/internal/handler/auth_cookie_test.go @@ -7,7 +7,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/middleware" + "github.com/ShukeBta/MMTL/internal/middleware" ) func TestSetAccessTokenCookie(t *testing.T) { diff --git a/internal/handler/auth_extra.go b/internal/handler/auth_extra.go index 7d7195d..542f803 100644 --- a/internal/handler/auth_extra.go +++ b/internal/handler/auth_extra.go @@ -10,8 +10,8 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/service" ) // refreshHandler returns a fresh token signed for the current user. diff --git a/internal/handler/backup.go b/internal/handler/backup.go index 9643cbb..7c6f03e 100644 --- a/internal/handler/backup.go +++ b/internal/handler/backup.go @@ -6,7 +6,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) func createBackupHandler(svc *service.Container) gin.HandlerFunc { diff --git a/internal/handler/danmaku.go b/internal/handler/danmaku.go index 696c4dc..628589e 100644 --- a/internal/handler/danmaku.go +++ b/internal/handler/danmaku.go @@ -6,7 +6,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) // getDanmakuHandler returns danmaku for a media. ?kw= optionally overrides the diff --git a/internal/handler/dlna.go b/internal/handler/dlna.go index 3d3277e..964d841 100644 --- a/internal/handler/dlna.go +++ b/internal/handler/dlna.go @@ -6,7 +6,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) func dlnaListHandler(svc *service.Container) gin.HandlerFunc { diff --git a/internal/handler/dlna_extra.go b/internal/handler/dlna_extra.go index 385ba20..1e561fc 100644 --- a/internal/handler/dlna_extra.go +++ b/internal/handler/dlna_extra.go @@ -11,7 +11,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) // dlnaControlPath maps the action name to the AVTransport SOAP body. diff --git a/internal/handler/emby_auth.go b/internal/handler/emby_auth.go index b531631..feeb5d8 100644 --- a/internal/handler/emby_auth.go +++ b/internal/handler/emby_auth.go @@ -7,8 +7,8 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/service" ) // embyError 返回 Emby 风格的错误(顶层 Code/Message)。 diff --git a/internal/handler/emby_auth_test.go b/internal/handler/emby_auth_test.go index b88e0cd..1940e98 100644 --- a/internal/handler/emby_auth_test.go +++ b/internal/handler/emby_auth_test.go @@ -14,10 +14,10 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" + "github.com/ShukeBta/MMTL/internal/service" ) func TestParseEmbyAuthByNameReqAcceptsLowercaseJSON(t *testing.T) { diff --git a/internal/handler/emby_authed_loop_test.go b/internal/handler/emby_authed_loop_test.go index 42e3ae1..5b4d390 100644 --- a/internal/handler/emby_authed_loop_test.go +++ b/internal/handler/emby_authed_loop_test.go @@ -13,10 +13,10 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" + "github.com/ShukeBta/MMTL/internal/service" ) // TestEmbyLoginThenAuthedRequest simulates the exact flow an Emby-compatible diff --git a/internal/handler/emby_discovery_routes_test.go b/internal/handler/emby_discovery_routes_test.go index 5a6a916..6dcecb8 100644 --- a/internal/handler/emby_discovery_routes_test.go +++ b/internal/handler/emby_discovery_routes_test.go @@ -12,10 +12,10 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" + "github.com/ShukeBta/MMTL/internal/service" ) func TestEmbyWithRequestAddressUsesHost(t *testing.T) { @@ -24,7 +24,7 @@ func TestEmbyWithRequestAddressUsesHost(t *testing.T) { c, _ := gin.CreateTestContext(w) c.Request = httptest.NewRequest(http.MethodGet, "http://192.168.1.4:18080/System/Info/Public", nil) - payload := embyWithRequestAddress(c, map[string]any{"Id": "mediastation-go-001"}) + payload := embyWithRequestAddress(c, map[string]any{"Id": "mmtl-001"}) if payload["LocalAddress"] != "http://192.168.1.4:18080" { t.Fatalf("unexpected LocalAddress: %#v", payload["LocalAddress"]) @@ -42,7 +42,7 @@ func TestEmbyWithRequestAddressHonorsForwardedHeaders(t *testing.T) { c.Request.Header.Set("X-Forwarded-Proto", "https") c.Request.Header.Set("X-Forwarded-Host", "media.example.test") - payload := embyWithRequestAddress(c, map[string]any{"Id": "mediastation-go-001"}) + payload := embyWithRequestAddress(c, map[string]any{"Id": "mmtl-001"}) if payload["LocalAddress"] != "https://media.example.test" { t.Fatalf("unexpected LocalAddress: %#v", payload["LocalAddress"]) diff --git a/internal/handler/emby_images.go b/internal/handler/emby_images.go index 799c9a0..11538c3 100644 --- a/internal/handler/emby_images.go +++ b/internal/handler/emby_images.go @@ -9,7 +9,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) var embyPlaceholderPNG = []byte{ diff --git a/internal/handler/emby_items_handlers.go b/internal/handler/emby_items_handlers.go index 3018dad..6c178a9 100644 --- a/internal/handler/emby_items_handlers.go +++ b/internal/handler/emby_items_handlers.go @@ -7,7 +7,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) func parseEmbyItemsParams(c *gin.Context) service.ItemsParams { diff --git a/internal/handler/emby_items_test.go b/internal/handler/emby_items_test.go index c296c0a..f673c8b 100644 --- a/internal/handler/emby_items_test.go +++ b/internal/handler/emby_items_test.go @@ -14,10 +14,10 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" + "github.com/ShukeBta/MMTL/internal/service" ) func TestEmbyItemImageServesWithoutAPIAuth(t *testing.T) { diff --git a/internal/handler/emby_misc_routes_test.go b/internal/handler/emby_misc_routes_test.go index 3317590..5a08b59 100644 --- a/internal/handler/emby_misc_routes_test.go +++ b/internal/handler/emby_misc_routes_test.go @@ -13,9 +13,9 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" + "github.com/ShukeBta/MMTL/internal/service" ) func TestEmbyVirtualFoldersRouteReturnsJSON(t *testing.T) { diff --git a/internal/handler/emby_playback.go b/internal/handler/emby_playback.go index d3520d6..0d1e303 100644 --- a/internal/handler/emby_playback.go +++ b/internal/handler/emby_playback.go @@ -8,7 +8,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) func embyPlaybackInfoHandler(svc *service.Container) gin.HandlerFunc { diff --git a/internal/handler/emby_playback_info_routes_test.go b/internal/handler/emby_playback_info_routes_test.go index 5a7c29c..31ab9e1 100644 --- a/internal/handler/emby_playback_info_routes_test.go +++ b/internal/handler/emby_playback_info_routes_test.go @@ -13,10 +13,10 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" + "github.com/ShukeBta/MMTL/internal/service" ) func TestEmbyLowercasePlaybackInfoRouteReturnsJSON(t *testing.T) { diff --git a/internal/handler/emby_playback_routes_test.go b/internal/handler/emby_playback_routes_test.go index 59b0b01..30afae7 100644 --- a/internal/handler/emby_playback_routes_test.go +++ b/internal/handler/emby_playback_routes_test.go @@ -12,10 +12,10 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" + "github.com/ShukeBta/MMTL/internal/service" ) func TestEmbyLowercaseVideoStreamRouteServesMedia(t *testing.T) { diff --git a/internal/handler/emby_playstate_handlers.go b/internal/handler/emby_playstate_handlers.go index c8c58af..f9a3ee2 100644 --- a/internal/handler/emby_playstate_handlers.go +++ b/internal/handler/emby_playstate_handlers.go @@ -7,7 +7,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) type embyPlayingReq struct { diff --git a/internal/handler/emby_routes.go b/internal/handler/emby_routes.go index 5e2d3fd..f29590e 100644 --- a/internal/handler/emby_routes.go +++ b/internal/handler/emby_routes.go @@ -5,8 +5,8 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/service" ) // registerEmbyRoutes 在 r 上挂双前缀("" + "/emby")的 Emby 兼容路由。 diff --git a/internal/handler/emby_routes_lowercase.go b/internal/handler/emby_routes_lowercase.go index 96189ae..9246b25 100644 --- a/internal/handler/emby_routes_lowercase.go +++ b/internal/handler/emby_routes_lowercase.go @@ -3,7 +3,7 @@ package handler import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) func registerLowercaseEmbyAuthRoutes(auth *gin.RouterGroup, svc *service.Container) { diff --git a/internal/handler/emby_session_routes_test.go b/internal/handler/emby_session_routes_test.go index 2d0e78d..7a5ebe9 100644 --- a/internal/handler/emby_session_routes_test.go +++ b/internal/handler/emby_session_routes_test.go @@ -14,10 +14,10 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" + "github.com/ShukeBta/MMTL/internal/service" ) func TestEmbyMarkPlayedRefreshesPlaybackDevice(t *testing.T) { diff --git a/internal/handler/emby_sessions.go b/internal/handler/emby_sessions.go index 8bcab26..d36ca8a 100644 --- a/internal/handler/emby_sessions.go +++ b/internal/handler/emby_sessions.go @@ -7,8 +7,8 @@ import ( "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt/v5" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/service" ) func embySessionsHandler(svc *service.Container) gin.HandlerFunc { @@ -29,7 +29,7 @@ func embySessionsHandler(svc *service.Container) gin.HandlerFunc { } row := gin.H{ "Id": sess.ID, - "ServerId": "mediastation-go-001", + "ServerId": "mmtl-001", "Client": sess.Client, "DeviceId": sess.DeviceID, "DeviceName": sess.DeviceName, diff --git a/internal/handler/emby_sessions_test.go b/internal/handler/emby_sessions_test.go index bd4d485..3353cb9 100644 --- a/internal/handler/emby_sessions_test.go +++ b/internal/handler/emby_sessions_test.go @@ -10,7 +10,7 @@ import ( "github.com/gin-gonic/gin" "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) func TestEmbySessionsReturnsRealtimeSession(t *testing.T) { diff --git a/internal/handler/emby_static.go b/internal/handler/emby_static.go index d4b1501..2312520 100644 --- a/internal/handler/emby_static.go +++ b/internal/handler/emby_static.go @@ -7,7 +7,7 @@ import ( "github.com/gin-gonic/gin" "github.com/gorilla/websocket" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) func embyNoContentHandler(_ *service.Container) gin.HandlerFunc { diff --git a/internal/handler/emby_subtitle_routes_test.go b/internal/handler/emby_subtitle_routes_test.go index e22c8b7..7533578 100644 --- a/internal/handler/emby_subtitle_routes_test.go +++ b/internal/handler/emby_subtitle_routes_test.go @@ -14,10 +14,10 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" + "github.com/ShukeBta/MMTL/internal/service" ) // TestEmbySubtitleOfficialRouteServesRawASS verifies that the official Emby diff --git a/internal/handler/emby_system.go b/internal/handler/emby_system.go index c70c024..092fe56 100644 --- a/internal/handler/emby_system.go +++ b/internal/handler/emby_system.go @@ -6,7 +6,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) func embySystemInfoHandler(svc *service.Container) gin.HandlerFunc { @@ -84,9 +84,9 @@ func embyPublicSystemInfoPayload(c *gin.Context, svc *service.Container) map[str return embyWithRequestAddress(c, svc.Emby.SystemInfoPublic()) } return embyWithRequestAddress(c, map[string]any{ - "Id": "mediastation-go-001", - "ServerId": "mediastation-go-001", - "ServerName": "MediaStationGo", + "Id": "mmtl-001", + "ServerId": "mmtl-001", + "ServerName": "MMTL", "Version": "4.8.10.0", "ServerVersion": "4.8.10.0", "ProductName": "Emby Server", diff --git a/internal/handler/emby_test_helpers_test.go b/internal/handler/emby_test_helpers_test.go index a1bc770..fd76b3e 100644 --- a/internal/handler/emby_test_helpers_test.go +++ b/internal/handler/emby_test_helpers_test.go @@ -6,7 +6,7 @@ import ( "github.com/golang-jwt/jwt/v5" - "github.com/ShukeBta/MediaStationGo/internal/middleware" + "github.com/ShukeBta/MMTL/internal/middleware" ) func signedTestToken(t *testing.T, secret string) string { @@ -23,7 +23,7 @@ func signedTestTokenWithPurpose(t *testing.T, secret, purpose string) string { Purpose: purpose, RegisteredClaims: jwt.RegisteredClaims{ ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour)), - Issuer: "mediastationgo-test", + Issuer: "mmtl-test", Subject: "user-1", }, } diff --git a/internal/handler/emby_users.go b/internal/handler/emby_users.go index d99ee04..b0e779d 100644 --- a/internal/handler/emby_users.go +++ b/internal/handler/emby_users.go @@ -6,7 +6,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) // ─── Users / Auth ──────────────────────────────────────────────────────────── @@ -67,7 +67,7 @@ func embyAuthByNameHandler(svc *service.Container) gin.HandlerFunc { embyRememberCompatSession(c, accessToken) c.JSON(http.StatusOK, gin.H{ "AccessToken": accessToken, - "ServerId": "mediastation-go-001", + "ServerId": "mmtl-001", "User": userPayload, "SessionInfo": gin.H{ "Id": resp.User.ID, @@ -150,12 +150,12 @@ func embyGetUserByIDHandler(svc *service.Container) gin.HandlerFunc { func embyFallbackUser(id string) gin.H { if strings.TrimSpace(id) == "" { - id = "mediastation-user" + id = "mmtl-user" } return gin.H{ "Id": id, - "Name": "MediaStationGo", - "ServerId": "mediastation-go-001", + "Name": "MMTL", + "ServerId": "mmtl-001", "HasPassword": true, "HasConfiguredPassword": true, "HasConfiguredEasyPassword": false, diff --git a/internal/handler/emby_views_handlers.go b/internal/handler/emby_views_handlers.go index 58c867c..dab3dd8 100644 --- a/internal/handler/emby_views_handlers.go +++ b/internal/handler/emby_views_handlers.go @@ -5,7 +5,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) func embyViewsHandler(svc *service.Container) gin.HandlerFunc { diff --git a/internal/handler/filemanager.go b/internal/handler/filemanager.go index bf07793..96e9cb2 100644 --- a/internal/handler/filemanager.go +++ b/internal/handler/filemanager.go @@ -10,7 +10,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) type fileFolderReq struct { diff --git a/internal/handler/handler.go b/internal/handler/handler.go index 71e703a..509c8c0 100644 --- a/internal/handler/handler.go +++ b/internal/handler/handler.go @@ -8,8 +8,8 @@ import ( "github.com/gin-gonic/gin" "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/service" ) // Register attaches every API route to the engine. @@ -46,7 +46,7 @@ func healthCheck(c *gin.Context) { } func versionInfo(c *gin.Context) { - c.JSON(200, gin.H{"name": "MediaStationGo", "version": "0.1.0"}) + c.JSON(200, gin.H{"name": "MMTL", "version": "0.1.0"}) } // ─── 权限 Handler 包装 ──────────────────────────────────────────────────────── diff --git a/internal/handler/manual_scrape.go b/internal/handler/manual_scrape.go index d09a657..d053e61 100644 --- a/internal/handler/manual_scrape.go +++ b/internal/handler/manual_scrape.go @@ -8,7 +8,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) type manualScrapeApplyReq struct { diff --git a/internal/handler/media.go b/internal/handler/media.go index 3f1a893..8d3cce5 100644 --- a/internal/handler/media.go +++ b/internal/handler/media.go @@ -10,9 +10,9 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/service" ) type createLibraryReq struct { diff --git a/internal/handler/media_extra.go b/internal/handler/media_extra.go index 9d88dc9..9f99bfc 100644 --- a/internal/handler/media_extra.go +++ b/internal/handler/media_extra.go @@ -8,8 +8,8 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/service" ) func recentMediaHandler(svc *service.Container) gin.HandlerFunc { diff --git a/internal/handler/media_favorite.go b/internal/handler/media_favorite.go index 61fc140..dd133af 100644 --- a/internal/handler/media_favorite.go +++ b/internal/handler/media_favorite.go @@ -12,9 +12,9 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/service" ) // addMediaFavoriteHandler ensures the (user, media) row exists. If it diff --git a/internal/handler/media_roots.go b/internal/handler/media_roots.go index 76f2034..608bdc2 100644 --- a/internal/handler/media_roots.go +++ b/internal/handler/media_roots.go @@ -6,7 +6,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) func listLibraryRootsHandler(svc *service.Container) gin.HandlerFunc { diff --git a/internal/handler/media_scan.go b/internal/handler/media_scan.go index 9c4aab0..035f7eb 100644 --- a/internal/handler/media_scan.go +++ b/internal/handler/media_scan.go @@ -7,7 +7,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) func scanLibraryHandler(svc *service.Container) gin.HandlerFunc { diff --git a/internal/handler/media_test.go b/internal/handler/media_test.go index 6e2ea16..3fc3f1b 100644 --- a/internal/handler/media_test.go +++ b/internal/handler/media_test.go @@ -18,11 +18,11 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" + "github.com/ShukeBta/MMTL/internal/service" ) func TestQueueLibraryRootScanImportsNewLibraryMedia(t *testing.T) { diff --git a/internal/handler/metadata_enrich.go b/internal/handler/metadata_enrich.go index 9d383ec..956c26b 100644 --- a/internal/handler/metadata_enrich.go +++ b/internal/handler/metadata_enrich.go @@ -8,7 +8,7 @@ import ( "sync" "time" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) var metadataNoiseRE = regexp.MustCompile(`(?i)(自动订阅|订阅|全集|合集|complete|batch|season\s*\d+|s\d{1,2}|s\d{1,2}e\d{1,3}|第\s*\d+\s*季|第\s*\d+\s*[集话話期]|2160p|1080p|720p|4k|uhd|bluray|blu-ray|web-?dl|hdtv|remux|x26[45]|h\.?26[45]|hevc|avc|hdr10?\+?|dovi|dv|atmos|aac|ddp?5\.1|truehd|flac)`) diff --git a/internal/handler/nfo.go b/internal/handler/nfo.go index 43bf1e2..be2e0c4 100644 --- a/internal/handler/nfo.go +++ b/internal/handler/nfo.go @@ -6,7 +6,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) func exportNFOHandler(svc *service.Container) gin.HandlerFunc { diff --git a/internal/handler/organizer.go b/internal/handler/organizer.go index 0ebf58e..270d971 100644 --- a/internal/handler/organizer.go +++ b/internal/handler/organizer.go @@ -7,7 +7,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) // organizeReq carries optional per-request overrides. 留空则沿用系统设置。 diff --git a/internal/handler/permission_handler.go b/internal/handler/permission_handler.go index c261d48..6ad0e4a 100644 --- a/internal/handler/permission_handler.go +++ b/internal/handler/permission_handler.go @@ -7,9 +7,9 @@ import ( "github.com/gin-gonic/gin" "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/service" ) // PermissionHandler 权限相关 HTTP 处理。 diff --git a/internal/handler/permissions.go b/internal/handler/permissions.go index 6753fe4..a140a03 100644 --- a/internal/handler/permissions.go +++ b/internal/handler/permissions.go @@ -11,9 +11,9 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/service" ) func requirePermission(svc *service.Container, key string) gin.HandlerFunc { diff --git a/internal/handler/play_profile.go b/internal/handler/play_profile.go index 30ccf3d..dee5fed 100644 --- a/internal/handler/play_profile.go +++ b/internal/handler/play_profile.go @@ -11,8 +11,8 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/service" ) type verifyPlayProfilePINReq struct { diff --git a/internal/handler/playback.go b/internal/handler/playback.go index b3d99d9..13c8001 100644 --- a/internal/handler/playback.go +++ b/internal/handler/playback.go @@ -6,8 +6,8 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/service" ) // ─── History ──────────────────────────────────────────────────────────────── diff --git a/internal/handler/playback_extra.go b/internal/handler/playback_extra.go index e335098..3b012c0 100644 --- a/internal/handler/playback_extra.go +++ b/internal/handler/playback_extra.go @@ -14,9 +14,9 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/service" ) // playbackInfoHandler returns the media row + a `stream_url` the React @@ -141,7 +141,7 @@ func externalPlaybackURL(c *gin.Context, svc *service.Container, path string) st if strings.HasPrefix(path, "http://") || strings.HasPrefix(path, "https://") { return path } - headerOrigin := sanitizedPublicOrigin(c.GetHeader("X-MediaStation-Public-Origin")) + headerOrigin := sanitizedPublicOrigin(c.GetHeader("X-MMTL-Public-Origin")) if headerOrigin != "" && !isLocalPublicOrigin(headerOrigin) { return joinOriginPath(headerOrigin, path) } diff --git a/internal/handler/playback_extra_test.go b/internal/handler/playback_extra_test.go index eb5d846..c135d64 100644 --- a/internal/handler/playback_extra_test.go +++ b/internal/handler/playback_extra_test.go @@ -15,11 +15,11 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" + "github.com/ShukeBta/MMTL/internal/service" ) func TestExternalURLUsesMediaScopedPlaybackToken(t *testing.T) { @@ -109,7 +109,7 @@ func TestExternalURLPrefersBrowserPublicOriginOverForwardedSource(t *testing.T) req.Header.Set("Authorization", "Bearer "+loginToken) req.Header.Set("X-Forwarded-Proto", "https") req.Header.Set("X-Forwarded-Host", "media.v6.agonyz.dpdns.org") - req.Header.Set("X-MediaStation-Public-Origin", "https://media.agonyz.dpdns.org") + req.Header.Set("X-MMTL-Public-Origin", "https://media.agonyz.dpdns.org") w := httptest.NewRecorder() router.ServeHTTP(w, req) @@ -140,7 +140,7 @@ func TestExternalPlayersSanitizeBrowserPublicOrigin(t *testing.T) { req := httptest.NewRequest(http.MethodGet, "http://origin.internal/api/playback/media-1/external-players", nil) req.Header.Set("Authorization", "Bearer "+loginToken) - req.Header.Set("X-MediaStation-Public-Origin", "https://user:pass@media.agonyz.dpdns.org/sneaky/path?x=1#frag") + req.Header.Set("X-MMTL-Public-Origin", "https://user:pass@media.agonyz.dpdns.org/sneaky/path?x=1#frag") w := httptest.NewRecorder() router.ServeHTTP(w, req) @@ -184,7 +184,7 @@ func TestExternalURLFallsBackToConfiguredPublicServerURL(t *testing.T) { req.Header.Set("Authorization", "Bearer "+loginToken) req.Header.Set("X-Forwarded-Proto", "https") req.Header.Set("X-Forwarded-Host", "source.example.test") - req.Header.Set("X-MediaStation-Public-Origin", "javascript:alert(1)") + req.Header.Set("X-MMTL-Public-Origin", "javascript:alert(1)") w := httptest.NewRecorder() router.ServeHTTP(w, req) @@ -211,7 +211,7 @@ func TestExternalURLPrefersConfiguredPublicServerURLOverLocalBrowserOrigin(t *te req := httptest.NewRequest(http.MethodGet, "http://127.0.0.1:8080/api/playback/media-1/external-url", nil) req.Header.Set("Authorization", "Bearer "+loginToken) - req.Header.Set("X-MediaStation-Public-Origin", "http://127.0.0.1:8080") + req.Header.Set("X-MMTL-Public-Origin", "http://127.0.0.1:8080") w := httptest.NewRecorder() router.ServeHTTP(w, req) diff --git a/internal/handler/playback_scope.go b/internal/handler/playback_scope.go index 1fe5d05..2343da8 100644 --- a/internal/handler/playback_scope.go +++ b/internal/handler/playback_scope.go @@ -7,9 +7,9 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/service" ) func enforceScopedPlaybackToken(c *gin.Context, mediaID string) bool { diff --git a/internal/handler/playlist_extra.go b/internal/handler/playlist_extra.go index cf988a1..7091aa3 100644 --- a/internal/handler/playlist_extra.go +++ b/internal/handler/playlist_extra.go @@ -7,8 +7,8 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/service" ) type reorderReq struct { diff --git a/internal/handler/profile.go b/internal/handler/profile.go index 2b32752..1c4458d 100644 --- a/internal/handler/profile.go +++ b/internal/handler/profile.go @@ -9,8 +9,8 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/service" ) func updateProfileHandler(svc *service.Container) gin.HandlerFunc { diff --git a/internal/handler/profile_test.go b/internal/handler/profile_test.go index f22bd0b..2ba5d3e 100644 --- a/internal/handler/profile_test.go +++ b/internal/handler/profile_test.go @@ -6,9 +6,9 @@ import ( "github.com/glebarez/sqlite" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" + "github.com/ShukeBta/MMTL/internal/service" ) func TestProfileHideAdultRequiresPasswordOnlyWhenChanged(t *testing.T) { diff --git a/internal/handler/public_ui.go b/internal/handler/public_ui.go index a53d377..81333a0 100644 --- a/internal/handler/public_ui.go +++ b/internal/handler/public_ui.go @@ -5,7 +5,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) const hideCommunityLinksSettingKey = "ui.hide_community_links_for_users" diff --git a/internal/handler/public_ui_test.go b/internal/handler/public_ui_test.go index e6eb9ee..cc75814 100644 --- a/internal/handler/public_ui_test.go +++ b/internal/handler/public_ui_test.go @@ -11,9 +11,9 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" + "github.com/ShukeBta/MMTL/internal/service" ) func TestPublicUIConfigExposesCommunityLinkVisibility(t *testing.T) { diff --git a/internal/handler/recognition_words.go b/internal/handler/recognition_words.go index 065f12d..a1cc7cb 100644 --- a/internal/handler/recognition_words.go +++ b/internal/handler/recognition_words.go @@ -5,7 +5,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) func recognitionWordsService(svc *service.Container) *service.RecognitionWordsService { diff --git a/internal/handler/recycle.go b/internal/handler/recycle.go index cc9d352..003cb9e 100644 --- a/internal/handler/recycle.go +++ b/internal/handler/recycle.go @@ -6,7 +6,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) func deleteMediaHandler(svc *service.Container) gin.HandlerFunc { diff --git a/internal/handler/refresh_handler.go b/internal/handler/refresh_handler.go index f5c6653..c0645d8 100644 --- a/internal/handler/refresh_handler.go +++ b/internal/handler/refresh_handler.go @@ -7,7 +7,7 @@ import ( "github.com/gin-gonic/gin" "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) // RefreshHandler 令牌刷新 HTTP 处理。 diff --git a/internal/handler/routes_admin.go b/internal/handler/routes_admin.go index 90bdce4..6205d8a 100644 --- a/internal/handler/routes_admin.go +++ b/internal/handler/routes_admin.go @@ -4,9 +4,9 @@ package handler import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/service" ) func registerAdminRoutes(api *gin.RouterGroup, cfg *config.Config, svc *service.Container) { diff --git a/internal/handler/routes_admin_test.go b/internal/handler/routes_admin_test.go index fd5d2a3..c38b934 100644 --- a/internal/handler/routes_admin_test.go +++ b/internal/handler/routes_admin_test.go @@ -6,8 +6,8 @@ import ( "github.com/gin-gonic/gin" "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/service" ) func TestAdminRouteSurfacesAreRegistered(t *testing.T) { diff --git a/internal/handler/routes_api_config.go b/internal/handler/routes_api_config.go index b70714f..818d365 100644 --- a/internal/handler/routes_api_config.go +++ b/internal/handler/routes_api_config.go @@ -4,9 +4,9 @@ package handler import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/service" ) func registerAPIConfigRoutes(api *gin.RouterGroup, cfg *config.Config, svc *service.Container) { diff --git a/internal/handler/routes_authenticated.go b/internal/handler/routes_authenticated.go index b7e4992..9b5290e 100644 --- a/internal/handler/routes_authenticated.go +++ b/internal/handler/routes_authenticated.go @@ -4,9 +4,9 @@ package handler import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/service" ) func registerAuthenticatedRoutes(api *gin.RouterGroup, cfg *config.Config, svc *service.Container) { diff --git a/internal/handler/routes_authenticated_core.go b/internal/handler/routes_authenticated_core.go index ecfc179..2cf2ced 100644 --- a/internal/handler/routes_authenticated_core.go +++ b/internal/handler/routes_authenticated_core.go @@ -3,8 +3,8 @@ package handler import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/service" ) func registerAuthedUserAndLicenseRoutes(authed *gin.RouterGroup, svc *service.Container) { diff --git a/internal/handler/routes_authenticated_extras.go b/internal/handler/routes_authenticated_extras.go index a97abbf..4bf7e73 100644 --- a/internal/handler/routes_authenticated_extras.go +++ b/internal/handler/routes_authenticated_extras.go @@ -3,7 +3,7 @@ package handler import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) func registerAuthedUISurfaceRoutes(authed *gin.RouterGroup, svc *service.Container) { diff --git a/internal/handler/routes_authenticated_features.go b/internal/handler/routes_authenticated_features.go index 3ca7e16..06c1ad0 100644 --- a/internal/handler/routes_authenticated_features.go +++ b/internal/handler/routes_authenticated_features.go @@ -3,8 +3,8 @@ package handler import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/service" ) func registerAuthedFileRoutes(authed *gin.RouterGroup, svc *service.Container) { diff --git a/internal/handler/routes_authenticated_test.go b/internal/handler/routes_authenticated_test.go index aad47b1..2633a6a 100644 --- a/internal/handler/routes_authenticated_test.go +++ b/internal/handler/routes_authenticated_test.go @@ -6,8 +6,8 @@ import ( "github.com/gin-gonic/gin" "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/service" ) func TestAuthenticatedRouteSurfacesAreRegistered(t *testing.T) { diff --git a/internal/handler/routes_public.go b/internal/handler/routes_public.go index 6969502..0992361 100644 --- a/internal/handler/routes_public.go +++ b/internal/handler/routes_public.go @@ -7,8 +7,8 @@ import ( "github.com/gin-gonic/gin" "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/service" ) func registerPublicAuthRoutes(api *gin.RouterGroup, svc *service.Container, log *zap.Logger) { diff --git a/internal/handler/scrape_reclassify.go b/internal/handler/scrape_reclassify.go index ac51131..7678ce8 100644 --- a/internal/handler/scrape_reclassify.go +++ b/internal/handler/scrape_reclassify.go @@ -3,7 +3,7 @@ package handler import ( "context" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) // 刮削元数据时不再自动跨库纠偏或自动创建新媒体库,保持在当前媒体库内仅更新元数据 diff --git a/internal/handler/search_extra.go b/internal/handler/search_extra.go index 20fea64..8b42f40 100644 --- a/internal/handler/search_extra.go +++ b/internal/handler/search_extra.go @@ -10,7 +10,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) // searchUnifiedHandler is the basic /api/search endpoint. diff --git a/internal/handler/series.go b/internal/handler/series.go index defc226..108c386 100644 --- a/internal/handler/series.go +++ b/internal/handler/series.go @@ -13,8 +13,8 @@ import ( "github.com/gin-gonic/gin" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/service" ) // seasonGroup is the JSON returned to the React UI per season. diff --git a/internal/handler/stats_user.go b/internal/handler/stats_user.go index 7775d49..d2f14c6 100644 --- a/internal/handler/stats_user.go +++ b/internal/handler/stats_user.go @@ -8,9 +8,9 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/service" ) // statsUserHandler returns a watch-time summary for one user. diff --git a/internal/handler/storage.go b/internal/handler/storage.go index 8697587..5dfc638 100644 --- a/internal/handler/storage.go +++ b/internal/handler/storage.go @@ -5,7 +5,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) func storageBreakdownHandler(svc *service.Container) gin.HandlerFunc { diff --git a/internal/handler/storage_test.go b/internal/handler/storage_test.go index 6aa4240..c136e59 100644 --- a/internal/handler/storage_test.go +++ b/internal/handler/storage_test.go @@ -6,8 +6,8 @@ import ( "github.com/gin-gonic/gin" "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/service" ) func TestStorageRouteIsRegistered(t *testing.T) { diff --git a/internal/handler/streaming.go b/internal/handler/streaming.go index d0e4bef..170134b 100644 --- a/internal/handler/streaming.go +++ b/internal/handler/streaming.go @@ -9,7 +9,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) func hlsPlaylistHandler(svc *service.Container) gin.HandlerFunc { diff --git a/internal/handler/strm.go b/internal/handler/strm.go index 01eee6b..57387e7 100644 --- a/internal/handler/strm.go +++ b/internal/handler/strm.go @@ -11,8 +11,8 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/service" ) // ─── 网盘账号 ────────────────────────────────────────────────────────────────── diff --git a/internal/handler/strm_routes_test.go b/internal/handler/strm_routes_test.go index 416a9d1..6220be1 100644 --- a/internal/handler/strm_routes_test.go +++ b/internal/handler/strm_routes_test.go @@ -11,10 +11,10 @@ import ( "gorm.io/gorm" "gorm.io/gorm/logger" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" + "github.com/ShukeBta/MMTL/internal/service" ) // TestStrmAdminRoutes 冒烟测试 STRM 管理端点注册与 401 拦截。 @@ -36,8 +36,8 @@ func TestStrmAdminRoutesAreRegistered(t *testing.T) { "DELETE /api/admin/strm/accounts/:id", "POST /api/admin/strm/accounts/:id/test", "GET /api/admin/strm/accounts/:id/list", - "POST /api/admin/strm/accounts/115-qr/start", - "POST /api/admin/strm/accounts/115-qr/poll", + "POST /api/admin/strm/accounts/:id/oauth/start", + "POST /api/admin/strm/accounts/:id/oauth/poll", "GET /api/admin/strm/settings", "PUT /api/admin/strm/settings", "GET /api/admin/strm/paths", diff --git a/internal/handler/subtitles.go b/internal/handler/subtitles.go index dc08cc4..3c7fd40 100644 --- a/internal/handler/subtitles.go +++ b/internal/handler/subtitles.go @@ -6,7 +6,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) func listSubtitlesHandler(svc *service.Container) gin.HandlerFunc { diff --git a/internal/handler/system_extra.go b/internal/handler/system_extra.go index b574a7c..ef6f2e6 100644 --- a/internal/handler/system_extra.go +++ b/internal/handler/system_extra.go @@ -10,9 +10,9 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/service" ) // listSystemConfigHandler is the non-admin alias for /admin/settings. diff --git a/internal/handler/system_handler.go b/internal/handler/system_handler.go index 527d882..0d34b29 100644 --- a/internal/handler/system_handler.go +++ b/internal/handler/system_handler.go @@ -9,8 +9,8 @@ import ( "github.com/gin-gonic/gin" "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/service" ) // SystemHandler handles system-related endpoints. diff --git a/internal/handler/system_meta.go b/internal/handler/system_meta.go index 8e1b4d3..daf3fbf 100644 --- a/internal/handler/system_meta.go +++ b/internal/handler/system_meta.go @@ -15,7 +15,7 @@ import ( "github.com/shirou/gopsutil/v3/disk" "github.com/shirou/gopsutil/v3/mem" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) // startedAt is captured at first call so /system/status can report uptime @@ -31,7 +31,7 @@ func systemInfoHandler(svc *service.Container) gin.HandlerFunc { } } c.JSON(http.StatusOK, gin.H{ - "name": "MediaStationGo", + "name": "MMTL", "version": "0.1.0", "go": runtime.Version(), "os": runtime.GOOS, diff --git a/internal/handler/system_update.go b/internal/handler/system_update.go index 4d6360c..b49300a 100644 --- a/internal/handler/system_update.go +++ b/internal/handler/system_update.go @@ -6,7 +6,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) func systemUpdateStatusHandler(svc *service.Container) gin.HandlerFunc { diff --git a/internal/handler/task_helpers.go b/internal/handler/task_helpers.go index caeed3e..6f472b8 100644 --- a/internal/handler/task_helpers.go +++ b/internal/handler/task_helpers.go @@ -1,6 +1,6 @@ package handler -import "github.com/ShukeBta/MediaStationGo/internal/service" +import "github.com/ShukeBta/MMTL/internal/service" func finishHTTPTask(task *service.TaskHandle, err error, stage, message string, metrics map[string]int64, details []string) { if task == nil { diff --git a/internal/handler/visibility.go b/internal/handler/visibility.go index 00b2e63..5202290 100644 --- a/internal/handler/visibility.go +++ b/internal/handler/visibility.go @@ -11,9 +11,9 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/service" ) func mediaVisibilityForRequest(c *gin.Context, svc *service.Container) service.MediaVisibility { diff --git a/internal/handler/watch_history.go b/internal/handler/watch_history.go index e6f3e8d..41ea1c7 100644 --- a/internal/handler/watch_history.go +++ b/internal/handler/watch_history.go @@ -17,9 +17,9 @@ import ( "github.com/gin-gonic/gin" - "github.com/ShukeBta/MediaStationGo/internal/middleware" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/middleware" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/service" ) // historyListHandler returns the caller's history rows joined with the diff --git a/internal/handler/ws.go b/internal/handler/ws.go index 6d04fb3..187f0eb 100644 --- a/internal/handler/ws.go +++ b/internal/handler/ws.go @@ -15,7 +15,7 @@ import ( "github.com/google/uuid" "github.com/gorilla/websocket" - "github.com/ShukeBta/MediaStationGo/internal/service" + "github.com/ShukeBta/MMTL/internal/service" ) var wsUpgrader = websocket.Upgrader{ diff --git a/internal/model/model.go b/internal/model/model.go index f9f5760..812aec8 100644 --- a/internal/model/model.go +++ b/internal/model/model.go @@ -1,5 +1,5 @@ // Package model 定义 GORM 数据模型和自动迁移使用的注册表。 -// 每个子系统在 MediaStationGo 中拥有一个表切片;AllModels 返回联合以供 db.AutoMigrate 使用。 +// 每个子系统在 MMTL 中拥有一个表切片;AllModels 返回联合以供 db.AutoMigrate 使用。 package model import ( diff --git a/internal/repository/access_log_repository.go b/internal/repository/access_log_repository.go index 6d29886..1485842 100644 --- a/internal/repository/access_log_repository.go +++ b/internal/repository/access_log_repository.go @@ -5,7 +5,7 @@ import ( "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // AccessLogRepository persists model.AccessLog records. diff --git a/internal/repository/api_config_repository.go b/internal/repository/api_config_repository.go index e5fc2cb..c79417f 100644 --- a/internal/repository/api_config_repository.go +++ b/internal/repository/api_config_repository.go @@ -7,7 +7,7 @@ import ( "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // ApiConfigRepository persists model.ApiConfig records. diff --git a/internal/repository/bot_repo.go b/internal/repository/bot_repo.go index 9c0c6ca..e2b98b6 100644 --- a/internal/repository/bot_repo.go +++ b/internal/repository/bot_repo.go @@ -7,7 +7,7 @@ import ( "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // ─── RegistrationCode ───────────────────────────────────────────────────────── diff --git a/internal/repository/favorite_repository.go b/internal/repository/favorite_repository.go index 33150ea..e6c3770 100644 --- a/internal/repository/favorite_repository.go +++ b/internal/repository/favorite_repository.go @@ -6,7 +6,7 @@ import ( "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // FavoriteRepository persists model.Favorite records. diff --git a/internal/repository/history_repository.go b/internal/repository/history_repository.go index acee023..132fc94 100644 --- a/internal/repository/history_repository.go +++ b/internal/repository/history_repository.go @@ -6,7 +6,7 @@ import ( "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // HistoryRepository persists model.PlaybackHistory entries. The application diff --git a/internal/repository/library_repository.go b/internal/repository/library_repository.go index 4a1a328..3012509 100644 --- a/internal/repository/library_repository.go +++ b/internal/repository/library_repository.go @@ -7,7 +7,7 @@ import ( "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // LibraryRepository persists model.Library records. diff --git a/internal/repository/media_repository.go b/internal/repository/media_repository.go index 44521ab..5cadb7d 100644 --- a/internal/repository/media_repository.go +++ b/internal/repository/media_repository.go @@ -7,7 +7,7 @@ import ( "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // MediaRepository persists model.Media records. diff --git a/internal/repository/media_repository_upsert.go b/internal/repository/media_repository_upsert.go index 1bfeb59..49f1df1 100644 --- a/internal/repository/media_repository_upsert.go +++ b/internal/repository/media_repository_upsert.go @@ -7,7 +7,7 @@ import ( "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // Upsert inserts or updates a media row keyed by Path (unique index). diff --git a/internal/repository/media_search_repository.go b/internal/repository/media_search_repository.go index 0437d62..d781cf6 100644 --- a/internal/repository/media_search_repository.go +++ b/internal/repository/media_search_repository.go @@ -7,7 +7,7 @@ import ( "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // Search runs a LIKE search against the title field. Empty query returns the diff --git a/internal/repository/opensearch.go b/internal/repository/opensearch.go index ed8ffbf..4c81ee7 100644 --- a/internal/repository/opensearch.go +++ b/internal/repository/opensearch.go @@ -11,8 +11,8 @@ import ( "strings" "time" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" ) type OpenSearchMediaBackend struct { @@ -29,7 +29,7 @@ func NewOpenSearchMediaBackend(cfg config.SearchConfig) *OpenSearchMediaBackend } index := strings.TrimSpace(cfg.Index) if index == "" { - index = "mediastation_media" + index = "mmtl_media" } return &OpenSearchMediaBackend{ baseURL: strings.TrimRight(strings.TrimSpace(cfg.OpenSearchURL), "/"), diff --git a/internal/repository/opensearch_test.go b/internal/repository/opensearch_test.go index 0db8d55..bb2d4cc 100644 --- a/internal/repository/opensearch_test.go +++ b/internal/repository/opensearch_test.go @@ -6,7 +6,7 @@ import ( "net/http/httptest" "testing" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) func TestOpenSearchMediaBackendSearchesIDs(t *testing.T) { diff --git a/internal/repository/permission_repository.go b/internal/repository/permission_repository.go index ae86172..44d095c 100644 --- a/internal/repository/permission_repository.go +++ b/internal/repository/permission_repository.go @@ -6,7 +6,7 @@ import ( "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // PermissionRepository persists model.UserPermission records. diff --git a/internal/repository/play_profile_repo.go b/internal/repository/play_profile_repo.go index 7dfc4cf..a76981d 100644 --- a/internal/repository/play_profile_repo.go +++ b/internal/repository/play_profile_repo.go @@ -6,7 +6,7 @@ import ( "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // PlayProfileRepository persists model.PlayProfile records. diff --git a/internal/repository/playlist_repository.go b/internal/repository/playlist_repository.go index e61c1b5..14d854c 100644 --- a/internal/repository/playlist_repository.go +++ b/internal/repository/playlist_repository.go @@ -5,7 +5,7 @@ import ( "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // PlaylistRepository persists model.Playlist + PlaylistItem. diff --git a/internal/repository/refresh_token_repository.go b/internal/repository/refresh_token_repository.go index d17bf53..5847e8a 100644 --- a/internal/repository/refresh_token_repository.go +++ b/internal/repository/refresh_token_repository.go @@ -9,7 +9,7 @@ import ( "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // RefreshTokenRepository persists model.RefreshToken records. diff --git a/internal/repository/repository_test.go b/internal/repository/repository_test.go index 2ad464a..66f843c 100644 --- a/internal/repository/repository_test.go +++ b/internal/repository/repository_test.go @@ -9,8 +9,8 @@ import ( "github.com/glebarez/sqlite" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/database" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/database" + "github.com/ShukeBta/MMTL/internal/model" ) func TestMediaUpsertSkipsUnchangedExistingRow(t *testing.T) { diff --git a/internal/repository/series_repository.go b/internal/repository/series_repository.go index 06da499..c7ad824 100644 --- a/internal/repository/series_repository.go +++ b/internal/repository/series_repository.go @@ -6,7 +6,7 @@ import ( "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // SeriesRepository persists model.Series records. diff --git a/internal/repository/setting_repository.go b/internal/repository/setting_repository.go index 80ade8c..c028eec 100644 --- a/internal/repository/setting_repository.go +++ b/internal/repository/setting_repository.go @@ -6,7 +6,7 @@ import ( "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // SettingRepository persists key/value preferences. diff --git a/internal/repository/storage_config_repo.go b/internal/repository/storage_config_repo.go index 173af9f..e6c666e 100644 --- a/internal/repository/storage_config_repo.go +++ b/internal/repository/storage_config_repo.go @@ -8,7 +8,7 @@ import ( "github.com/google/uuid" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // StorageConfigRepository persists model.StorageConfig records. diff --git a/internal/repository/strm_repository.go b/internal/repository/strm_repository.go index aaae9bd..bccb039 100644 --- a/internal/repository/strm_repository.go +++ b/internal/repository/strm_repository.go @@ -7,7 +7,7 @@ import ( "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // ─── StrmAccount ─────────────────────────────────────────────────────────────── diff --git a/internal/repository/user_repository.go b/internal/repository/user_repository.go index 6f7ac87..c92da72 100644 --- a/internal/repository/user_repository.go +++ b/internal/repository/user_repository.go @@ -9,7 +9,7 @@ import ( "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // UserRepository persists model.User records. diff --git a/internal/service/adult_scraper.go b/internal/service/adult_scraper.go index a3befec..92862cf 100644 --- a/internal/service/adult_scraper.go +++ b/internal/service/adult_scraper.go @@ -13,7 +13,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/repository" ) var ( diff --git a/internal/service/adult_scraper_routing_test.go b/internal/service/adult_scraper_routing_test.go index 0cafa64..5612404 100644 --- a/internal/service/adult_scraper_routing_test.go +++ b/internal/service/adult_scraper_routing_test.go @@ -11,8 +11,8 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func TestAdultProviderRouting(t *testing.T) { diff --git a/internal/service/adult_scraper_test.go b/internal/service/adult_scraper_test.go index cbbbdf3..6e35212 100644 --- a/internal/service/adult_scraper_test.go +++ b/internal/service/adult_scraper_test.go @@ -8,8 +8,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func TestNormalizeAdultCode(t *testing.T) { diff --git a/internal/service/api_config.go b/internal/service/api_config.go index ed8e7c7..622a40e 100644 --- a/internal/service/api_config.go +++ b/internal/service/api_config.go @@ -5,7 +5,7 @@ // read so values stored on disk are useless without the JWT secret. // // On first read it seeds the table with the providers supported by -// MediaStationGo today (TMDb / Bangumi / TheTVDB / Fanart / OpenAI / Douban). +// MMTL today (TMDb / Bangumi / TheTVDB / Fanart / OpenAI / Douban). package service import ( @@ -17,8 +17,8 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) // APIConfigService coordinates third-party API key storage. diff --git a/internal/service/api_config_connection.go b/internal/service/api_config_connection.go index 15f53ed..940068a 100644 --- a/internal/service/api_config_connection.go +++ b/internal/service/api_config_connection.go @@ -10,7 +10,7 @@ import ( "strings" "time" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // TestConnection 测试 API 连接。 diff --git a/internal/service/api_config_helpers.go b/internal/service/api_config_helpers.go index d0898f7..f63dc98 100644 --- a/internal/service/api_config_helpers.go +++ b/internal/service/api_config_helpers.go @@ -5,7 +5,7 @@ import ( "net/url" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // GetEffectiveConfig 获取生效的 API 配置(数据库配置优先于配置文件)。 diff --git a/internal/service/api_config_svc.go b/internal/service/api_config_svc.go index 8768454..c76f1c1 100644 --- a/internal/service/api_config_svc.go +++ b/internal/service/api_config_svc.go @@ -7,9 +7,9 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) // ApiConfigService 负责第三方 API 配置的 CRUD 和加密管理。 diff --git a/internal/service/audit.go b/internal/service/audit.go index cd13bfc..10bed8f 100644 --- a/internal/service/audit.go +++ b/internal/service/audit.go @@ -12,8 +12,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) // AuditService is the only sanctioned writer for the access_logs table. diff --git a/internal/service/auth.go b/internal/service/auth.go index d72f9a3..4704ce0 100644 --- a/internal/service/auth.go +++ b/internal/service/auth.go @@ -12,9 +12,9 @@ import ( "go.uber.org/zap" "golang.org/x/crypto/bcrypt" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) // AuthService handles registration, login, and JWT issuance. diff --git a/internal/service/auth_tokens.go b/internal/service/auth_tokens.go index 24c6b20..8833cfa 100644 --- a/internal/service/auth_tokens.go +++ b/internal/service/auth_tokens.go @@ -9,7 +9,7 @@ import ( "github.com/golang-jwt/jwt/v5" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // IssueToken signs a JWT for the given user (60min validity, includes tier). @@ -21,7 +21,7 @@ func (s *AuthService) IssueToken(u *model.User) (string, error) { RegisteredClaims: jwt.RegisteredClaims{ IssuedAt: jwt.NewNumericDate(time.Now()), ExpiresAt: jwt.NewNumericDate(time.Now().Add(60 * time.Minute)), - Issuer: "mediastationgo", + Issuer: "mmtl", Subject: u.ID, }, } @@ -68,7 +68,7 @@ func (s *AuthService) IssueExternalPlaybackToken(u *model.User, mediaID string, RegisteredClaims: jwt.RegisteredClaims{ IssuedAt: jwt.NewNumericDate(time.Now()), ExpiresAt: jwt.NewNumericDate(time.Now().Add(ExternalPlaybackTokenDurationForMedia(durationSec))), - Issuer: "mediastationgo", + Issuer: "mmtl", Subject: u.ID, }, } @@ -95,7 +95,7 @@ func (s *AuthService) IssueEmbyToken(u *model.User) (string, error) { RegisteredClaims: jwt.RegisteredClaims{ IssuedAt: jwt.NewNumericDate(time.Now()), ExpiresAt: jwt.NewNumericDate(time.Now().Add(EmbyTokenDuration)), - Issuer: "mediastationgo", + Issuer: "mmtl", Subject: u.ID, }, } diff --git a/internal/service/auth_user_limits_test.go b/internal/service/auth_user_limits_test.go index 3b3a9a4..247f854 100644 --- a/internal/service/auth_user_limits_test.go +++ b/internal/service/auth_user_limits_test.go @@ -12,10 +12,10 @@ import ( "go.uber.org/zap" "golang.org/x/crypto/bcrypt" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/database" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/database" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func newAuthTestServices(t *testing.T) (*repository.Container, *AuthService, *ProfileService, *PermissionService) { diff --git a/internal/service/backup.go b/internal/service/backup.go index cada25f..b3ee59e 100644 --- a/internal/service/backup.go +++ b/internal/service/backup.go @@ -19,7 +19,7 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) // BackupService manages database backups. @@ -72,7 +72,7 @@ func (b *BackupService) Create(ctx context.Context) (*BackupInfo, error) { return nil, err } ts := time.Now().Format("20060102_150405") - dst := filepath.Join(dir, fmt.Sprintf("mediastation_%s.db", ts)) + dst := filepath.Join(dir, fmt.Sprintf("mmtl_%s.db", ts)) // VACUUM INTO creates a clean, non-WAL copy atomically. if err := b.db.WithContext(ctx).Exec("VACUUM INTO ?", dst).Error; err != nil { diff --git a/internal/service/bangumi.go b/internal/service/bangumi.go index 07d062d..7326ebc 100644 --- a/internal/service/bangumi.go +++ b/internal/service/bangumi.go @@ -23,7 +23,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) // BangumiProvider talks to https://api.bgm.tv. @@ -181,7 +181,7 @@ func (b *BangumiProvider) getJSON(ctx context.Context, u string, out any) error if err != nil { return err } - req.Header.Set("User-Agent", "MediaStationGo/0.1 (https://github.com/ShukeBta/MediaStationGo)") + req.Header.Set("User-Agent", "MMTL/0.1 (https://github.com/ShukeBta/MMTL)") if t := strings.TrimSpace(b.cfg.Secrets.BangumiToken); t != "" { req.Header.Set("Authorization", "Bearer "+t) } diff --git a/internal/service/bot_settings.go b/internal/service/bot_settings.go index de7f899..fa81393 100644 --- a/internal/service/bot_settings.go +++ b/internal/service/bot_settings.go @@ -7,8 +7,8 @@ import ( "strconv" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) // Bot / 设备管控相关的设置键。全部存储在 settings 表,由管理员通过 diff --git a/internal/service/cloud/cloud_115_test.go b/internal/service/cloud/cloud_115_test.go index 59c0b24..19f0a11 100644 --- a/internal/service/cloud/cloud_115_test.go +++ b/internal/service/cloud/cloud_115_test.go @@ -8,7 +8,7 @@ import ( "strings" "testing" - "github.com/ShukeBta/MediaStationGo/internal/service/cloud115" + "github.com/ShukeBta/MMTL/internal/service/cloud115" ) // 115 开放平台(openapi)驱动测试:mock proapi 的列目录/直链接口。 diff --git a/internal/service/cloud/clouddrive2.go b/internal/service/cloud/clouddrive2.go index 64ddfa6..a77d112 100644 --- a/internal/service/cloud/clouddrive2.go +++ b/internal/service/cloud/clouddrive2.go @@ -13,7 +13,7 @@ import ( // cloudDrive2Provider bridges CloudDrive2 through its WebDAV endpoint. // // CloudDrive2 integrates many cloud disks (115 / 123 / Aliyun and more). -// Treating it as a WebDAV-backed cloud provider lets MediaStationGo +// Treating it as a WebDAV-backed cloud provider lets MMTL // browse, mount and upload to those disks without carrying every provider's // private chunk-upload protocol in this project. type cloudDrive2Provider struct { diff --git a/internal/service/cloud/pan115_openapi.go b/internal/service/cloud/pan115_openapi.go index 5c596ee..351eb82 100644 --- a/internal/service/cloud/pan115_openapi.go +++ b/internal/service/cloud/pan115_openapi.go @@ -19,7 +19,7 @@ import ( "fmt" "strings" - "github.com/ShukeBta/MediaStationGo/internal/service/cloud115" + "github.com/ShukeBta/MMTL/internal/service/cloud115" ) // openAPI115Provider 实现 Provider 接口:List 列目录、Resolve 用 pickcode diff --git a/internal/service/cloud_library_display_stubs.go b/internal/service/cloud_library_display_stubs.go index 514403e..455d7b9 100644 --- a/internal/service/cloud_library_display_stubs.go +++ b/internal/service/cloud_library_display_stubs.go @@ -6,8 +6,8 @@ import ( "path" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) // CloudMountInfo 是云盘挂载库的规范标识(因网盘后端已移除,仅保留类型以兼容 diff --git a/internal/service/danmaku_service.go b/internal/service/danmaku_service.go index 18ae7a0..a62e46b 100644 --- a/internal/service/danmaku_service.go +++ b/internal/service/danmaku_service.go @@ -15,7 +15,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/repository" ) // Danmaku setting keys, managed through the admin settings UI (PUT @@ -296,7 +296,7 @@ func (s *DanmakuService) fetchBody(ctx context.Context, sourceURL string, follow if err != nil { return "", err } - req.Header.Set("User-Agent", "MediaStationGo/danmaku (+https://github.com/ShukeBta/MediaStationGo)") + req.Header.Set("User-Agent", "MMTL/danmaku (+https://github.com/ShukeBta/MMTL)") req.Header.Set("Accept", "application/json, application/xml, */*") resp, err := client.Do(req) if err != nil { diff --git a/internal/service/danmaku_service_test.go b/internal/service/danmaku_service_test.go index fe695a9..0309941 100644 --- a/internal/service/danmaku_service_test.go +++ b/internal/service/danmaku_service_test.go @@ -13,8 +13,8 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func newDanmakuTestService(t *testing.T) *DanmakuService { diff --git a/internal/service/db_errors.go b/internal/service/db_errors.go index 8084e34..9e146f6 100644 --- a/internal/service/db_errors.go +++ b/internal/service/db_errors.go @@ -1,6 +1,6 @@ package service -import "github.com/ShukeBta/MediaStationGo/internal/repository" +import "github.com/ShukeBta/MMTL/internal/repository" func IsTransientDatabaseLock(err error) bool { return repository.IsSQLiteBusyError(err) diff --git a/internal/service/device_cleanup.go b/internal/service/device_cleanup.go index 684426d..97d090f 100644 --- a/internal/service/device_cleanup.go +++ b/internal/service/device_cleanup.go @@ -8,7 +8,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // SweepInactiveUsers is kept for compatibility with the existing scheduler; it diff --git a/internal/service/device_listing.go b/internal/service/device_listing.go index 35f4adc..0d4442a 100644 --- a/internal/service/device_listing.go +++ b/internal/service/device_listing.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // KickDevice marks a device as kicked so the next request from it is rejected diff --git a/internal/service/device_service.go b/internal/service/device_service.go index 708eca7..5cca7bd 100644 --- a/internal/service/device_service.go +++ b/internal/service/device_service.go @@ -10,8 +10,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) // DeviceService implements device/session tracking and the two decoupled diff --git a/internal/service/dlna.go b/internal/service/dlna.go index edcb735..b17b708 100644 --- a/internal/service/dlna.go +++ b/internal/service/dlna.go @@ -6,7 +6,7 @@ // service to start playback of an HTTP URL. // // We do NOT mediate the renderer ↔ client traffic; the renderer pulls -// the bytes directly from MediaStationGo's /api/stream endpoint, so +// the bytes directly from MMTL's /api/stream endpoint, so // the cast call only ever transports a URL string. package service diff --git a/internal/service/douban.go b/internal/service/douban.go index 5eb6770..fa1cf86 100644 --- a/internal/service/douban.go +++ b/internal/service/douban.go @@ -27,7 +27,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) // DoubanProvider talks to the unofficial Douban movie API. diff --git a/internal/service/emby_artwork.go b/internal/service/emby_artwork.go index 7d6a34f..b079d7f 100644 --- a/internal/service/emby_artwork.go +++ b/internal/service/emby_artwork.go @@ -5,8 +5,8 @@ import ( "strings" "time" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) // ImageURL returns artwork for a media/series/season item id. diff --git a/internal/service/emby_artwork_test.go b/internal/service/emby_artwork_test.go index 3b34c91..7144cb8 100644 --- a/internal/service/emby_artwork_test.go +++ b/internal/service/emby_artwork_test.go @@ -3,7 +3,7 @@ package service import ( "testing" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func TestImageURLFallsBackToLibraryCoverURL(t *testing.T) { diff --git a/internal/service/emby_compat.go b/internal/service/emby_compat.go index 2915d86..bc7d0c2 100644 --- a/internal/service/emby_compat.go +++ b/internal/service/emby_compat.go @@ -3,7 +3,7 @@ // EmbyService produces JSON envelopes shaped like the most-consumed // Emby-API endpoints so existing players (Infuse / Yamby / Hills / // Senplayer / Kodi NextPVR extension / iOS native clients) can talk to -// MediaStationGo without a custom plugin. +// MMTL without a custom plugin. // // The shim is read-mostly: items, images, playback are fully covered; // 播放进度上报 / 收藏切换 是写路径但走我们自己的 PlaybackHistory / @@ -17,14 +17,14 @@ import ( "sync" "time" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/repository" "go.uber.org/zap" ) // 用一个固定的 ServerId 字符串。Emby 客户端会缓存这个 id,第一次见到 // 该 id 后会把所有派生数据(cookie/收藏/历史)和它绑定。 -const embyServerID = "mediastation-go-001" +const embyServerID = "mmtl-001" // embyCompatVersion deliberately reports an Emby 4.x server. Official Emby // clients reject Jellyfin-style 10.x identities as unsupported/too old during diff --git a/internal/service/emby_compat_test.go b/internal/service/emby_compat_test.go index 2dd036e..04ff9b4 100644 --- a/internal/service/emby_compat_test.go +++ b/internal/service/emby_compat_test.go @@ -6,9 +6,9 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func newTestEmbyService(t *testing.T) *EmbyService { diff --git a/internal/service/emby_counts.go b/internal/service/emby_counts.go index c1ceb05..e64c5b0 100644 --- a/internal/service/emby_counts.go +++ b/internal/service/emby_counts.go @@ -4,7 +4,7 @@ import ( "context" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" "gorm.io/gorm" ) diff --git a/internal/service/emby_items_detail.go b/internal/service/emby_items_detail.go index 8f67931..8510b3a 100644 --- a/internal/service/emby_items_detail.go +++ b/internal/service/emby_items_detail.go @@ -6,7 +6,7 @@ import ( "strings" "time" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // Item 单条目详情。 diff --git a/internal/service/emby_items_list.go b/internal/service/emby_items_list.go index 3ec405a..686d10c 100644 --- a/internal/service/emby_items_list.go +++ b/internal/service/emby_items_list.go @@ -6,7 +6,7 @@ import ( "strings" "time" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func (e *EmbyService) mediaItems(ctx context.Context, p ItemsParams) (map[string]any, error) { diff --git a/internal/service/emby_media_sources.go b/internal/service/emby_media_sources.go index d7f39d0..6a8edfc 100644 --- a/internal/service/emby_media_sources.go +++ b/internal/service/emby_media_sources.go @@ -7,7 +7,7 @@ import ( "sort" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func (e *EmbyService) mediaSourcesForItem(ctx context.Context, m *model.Media, asEmbedded, directOnly bool) []map[string]any { diff --git a/internal/service/emby_movie_items.go b/internal/service/emby_movie_items.go index 67ab069..625a274 100644 --- a/internal/service/emby_movie_items.go +++ b/internal/service/emby_movie_items.go @@ -8,7 +8,7 @@ import ( "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // movieLibraryHasEpisodicContent 报告电影类型库里是否混入了「剧集结构」内容 diff --git a/internal/service/emby_movie_library_test.go b/internal/service/emby_movie_library_test.go index be158e8..9419d6f 100644 --- a/internal/service/emby_movie_library_test.go +++ b/internal/service/emby_movie_library_test.go @@ -4,7 +4,7 @@ import ( "testing" "time" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func TestEmbyMovieLibrarySeasonNumbersStayMovies(t *testing.T) { diff --git a/internal/service/emby_playback.go b/internal/service/emby_playback.go index 5f84715..652beed 100644 --- a/internal/service/emby_playback.go +++ b/internal/service/emby_playback.go @@ -10,7 +10,7 @@ import ( "strings" "time" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // PlaybackInfo returns a PlaybackInfoResponse usable by Emby clients. diff --git a/internal/service/emby_playback_test.go b/internal/service/emby_playback_test.go index 6a4b6ee..3072d2c 100644 --- a/internal/service/emby_playback_test.go +++ b/internal/service/emby_playback_test.go @@ -4,7 +4,7 @@ import ( "testing" "time" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func TestEmbyRootItemsExposeLibraries(t *testing.T) { diff --git a/internal/service/emby_series.go b/internal/service/emby_series.go index 7c319d9..e680126 100644 --- a/internal/service/emby_series.go +++ b/internal/service/emby_series.go @@ -6,7 +6,7 @@ import ( "strings" "time" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) type embySeriesGroup struct { diff --git a/internal/service/emby_series_hierarchy_test.go b/internal/service/emby_series_hierarchy_test.go index 9600fa0..1fd5877 100644 --- a/internal/service/emby_series_hierarchy_test.go +++ b/internal/service/emby_series_hierarchy_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func TestEmbyItemsExposeSeriesSeasonEpisodeHierarchy(t *testing.T) { diff --git a/internal/service/emby_series_ids.go b/internal/service/emby_series_ids.go index 44df15a..914953f 100644 --- a/internal/service/emby_series_ids.go +++ b/internal/service/emby_series_ids.go @@ -11,7 +11,7 @@ import ( "strings" "time" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func (e *EmbyService) seriesIDForMedia(m *model.Media) string { diff --git a/internal/service/emby_subtitle_test.go b/internal/service/emby_subtitle_test.go index 5e0414a..e76d40d 100644 --- a/internal/service/emby_subtitle_test.go +++ b/internal/service/emby_subtitle_test.go @@ -9,7 +9,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // writeTempVideoWithSubtitle creates a temp directory with a fake video and a diff --git a/internal/service/emby_system.go b/internal/service/emby_system.go index c408821..eeeaff8 100644 --- a/internal/service/emby_system.go +++ b/internal/service/emby_system.go @@ -5,7 +5,7 @@ import ( "strings" "time" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // SystemInfo returns the full Emby identity payload. @@ -13,7 +13,7 @@ func (e *EmbyService) SystemInfo() map[string]any { return map[string]any{ "Id": embyServerID, "ServerId": embyServerID, - "ServerName": "MediaStationGo", + "ServerName": "MMTL", "Version": embyCompatVersion, "ServerVersion": embyCompatVersion, "ProductName": "Emby Server", @@ -42,7 +42,7 @@ func (e *EmbyService) SystemInfoPublic() map[string]any { return map[string]any{ "Id": embyServerID, "ServerId": embyServerID, - "ServerName": "MediaStationGo", + "ServerName": "MMTL", "Version": embyCompatVersion, "ServerVersion": embyCompatVersion, "ProductName": "Emby Server", @@ -85,7 +85,7 @@ func (e *EmbyService) userPayload(u *model.User) map[string]any { "Id": u.ID, "Name": u.Username, "ServerId": embyServerID, - "ServerName": "MediaStationGo", + "ServerName": "MMTL", "HasPassword": true, "HasConfiguredPassword": true, "HasConfiguredEasyPassword": false, diff --git a/internal/service/emby_user_data.go b/internal/service/emby_user_data.go index 6040b08..831d5b4 100644 --- a/internal/service/emby_user_data.go +++ b/internal/service/emby_user_data.go @@ -9,7 +9,7 @@ import ( "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // SetFavorite 把 mediaID 标为 userID 的收藏。 diff --git a/internal/service/emby_versions_test.go b/internal/service/emby_versions_test.go index 2a73ae0..9c6aec2 100644 --- a/internal/service/emby_versions_test.go +++ b/internal/service/emby_versions_test.go @@ -4,7 +4,7 @@ import ( "testing" "time" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func TestEmbyLatestItemsCollapsesMovieVersions(t *testing.T) { diff --git a/internal/service/emby_visibility.go b/internal/service/emby_visibility.go index 2278a23..1769cd2 100644 --- a/internal/service/emby_visibility.go +++ b/internal/service/emby_visibility.go @@ -7,7 +7,7 @@ import ( "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func (e *EmbyService) applyUserMediaVisibility(ctx context.Context, q *gorm.DB, userID string) *gorm.DB { diff --git a/internal/service/episode_metadata_cleanup.go b/internal/service/episode_metadata_cleanup.go index 5a92886..e5d82b5 100644 --- a/internal/service/episode_metadata_cleanup.go +++ b/internal/service/episode_metadata_cleanup.go @@ -11,7 +11,7 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // pollutedEpisodeCleanupSettingKey marks that the one-time normalization has run. diff --git a/internal/service/episode_metadata_cleanup_test.go b/internal/service/episode_metadata_cleanup_test.go index e57d3f2..8320b1b 100644 --- a/internal/service/episode_metadata_cleanup_test.go +++ b/internal/service/episode_metadata_cleanup_test.go @@ -6,8 +6,8 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func newCleanupTestContainer(t *testing.T) (*Container, *gorm.DB) { diff --git a/internal/service/fanart.go b/internal/service/fanart.go index c2523ab..02fd77e 100644 --- a/internal/service/fanart.go +++ b/internal/service/fanart.go @@ -21,7 +21,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) // FanartProvider talks to https://webservice.fanart.tv. @@ -133,7 +133,7 @@ func (f *FanartProvider) getJSON(ctx context.Context, u string, out any) error { if err != nil { return err } - req.Header.Set("User-Agent", "MediaStationGo/0.1") + req.Header.Set("User-Agent", "MMTL/0.1") resp, err := f.client.Do(req) if err != nil { return err diff --git a/internal/service/ffmpeg_auto_install.go b/internal/service/ffmpeg_auto_install.go index e9ce114..405bdd9 100644 --- a/internal/service/ffmpeg_auto_install.go +++ b/internal/service/ffmpeg_auto_install.go @@ -12,7 +12,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) // AutoInstallFFmpeg is only called by the admin tool-install endpoint. The @@ -91,7 +91,7 @@ func downloadFFmpegWindows(log *zap.Logger, installDir string) (bool, error) { return false, fmt.Errorf("创建安装目录失败: %w", err) } - tempDir, err := os.MkdirTemp("", "mediastationgo-ffmpeg-*") + tempDir, err := os.MkdirTemp("", "mmtl-ffmpeg-*") if err != nil { return false, fmt.Errorf("创建临时目录失败: %w", err) } diff --git a/internal/service/ffprobe.go b/internal/service/ffprobe.go index 76321d3..f293754 100644 --- a/internal/service/ffprobe.go +++ b/internal/service/ffprobe.go @@ -18,7 +18,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) // FFprobeService wraps the external ffprobe binary. diff --git a/internal/service/ffprobe_test.go b/internal/service/ffprobe_test.go index c1bde87..d689af8 100644 --- a/internal/service/ffprobe_test.go +++ b/internal/service/ffprobe_test.go @@ -7,7 +7,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) func TestFFprobeServiceDefaultsToSingleConcurrentProbe(t *testing.T) { diff --git a/internal/service/filemanager.go b/internal/service/filemanager.go index d840036..f5e2059 100644 --- a/internal/service/filemanager.go +++ b/internal/service/filemanager.go @@ -16,8 +16,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/repository" ) // FileManagerService browses and mutates the server-side filesystem. diff --git a/internal/service/filemanager_roots.go b/internal/service/filemanager_roots.go index c694426..3a4118a 100644 --- a/internal/service/filemanager_roots.go +++ b/internal/service/filemanager_roots.go @@ -67,8 +67,8 @@ func (s *FileManagerService) allowedRoots() (map[string]string, error) { add("movies", s.cfg.Media.MoviesDir) add("tv", s.cfg.Media.TVDir) add("anime", s.cfg.Media.AnimeDir) - add("downloads", envOrDefault("MEDIASTATION_DOWNLOAD_CONTAINER_DIR", "/downloads")) - add("media", envOrDefault("MEDIASTATION_MEDIA_CONTAINER_DIR", "/media")) + add("downloads", envOrDefault("MMTL_DOWNLOAD_CONTAINER_DIR", "/downloads")) + add("media", envOrDefault("MMTL_MEDIA_CONTAINER_DIR", "/media")) if s.repo != nil && s.repo.Setting != nil { addSetting := func(label, key string) { if value, err := s.repo.Setting.Get(context.Background(), key); err == nil { diff --git a/internal/service/filemanager_test.go b/internal/service/filemanager_test.go index f2c0e01..b2af25e 100644 --- a/internal/service/filemanager_test.go +++ b/internal/service/filemanager_test.go @@ -8,9 +8,9 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func newFileManagerTestServiceWithRepo(t *testing.T, root string) (*FileManagerService, *repository.Container) { diff --git a/internal/service/image_proxy.go b/internal/service/image_proxy.go index b73772e..6b68dd7 100644 --- a/internal/service/image_proxy.go +++ b/internal/service/image_proxy.go @@ -2,7 +2,7 @@ // // Some deployments cannot reach image.tmdb.org directly (GFW, internal-only // networks). ImageProxy fronts a remote image URL so the browser only ever -// talks to the MediaStationGo origin. The proxy: +// talks to the MMTL origin. The proxy: // // - validates the URL scheme is http/https, // - streams bytes through with a small disk cache under cache/images, @@ -20,7 +20,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) // ImageProxy fetches and caches remote images on behalf of the browser. diff --git a/internal/service/image_proxy_remote_test.go b/internal/service/image_proxy_remote_test.go index 1d83bd6..80939d4 100644 --- a/internal/service/image_proxy_remote_test.go +++ b/internal/service/image_proxy_remote_test.go @@ -14,7 +14,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) func TestImageProxyDoesNotNegativeCacheFailedRemoteImageFetch(t *testing.T) { diff --git a/internal/service/image_proxy_test.go b/internal/service/image_proxy_test.go index d591d2e..0568f49 100644 --- a/internal/service/image_proxy_test.go +++ b/internal/service/image_proxy_test.go @@ -10,7 +10,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) var testJPEG = []byte{ diff --git a/internal/service/local_availability.go b/internal/service/local_availability.go index da11769..e446c07 100644 --- a/internal/service/local_availability.go +++ b/internal/service/local_availability.go @@ -6,8 +6,8 @@ import ( "regexp" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) var availabilityNoiseRE = regexp.MustCompile(`(?i)(自动订阅|订阅|全集|合集|complete|batch|s\d{1,2}e\d{1,3}|season\s*\d+|s\d{1,2}|第\s*\d+\s*季|第\s*\d+\s*[集话話期]|\(\d{4}\)|\b\d{4}\b|2160p|1080p|720p|4k|uhd|bluray|blu-ray|web-?dl|hdtv|remux|x26[45]|h\.?26[45]|hevc|avc|hdr10?\+?|dovi|dv|atmos|aac|ddp?5\.1|truehd|flac)`) diff --git a/internal/service/local_metadata_apply.go b/internal/service/local_metadata_apply.go index 474ba62..1a640fe 100644 --- a/internal/service/local_metadata_apply.go +++ b/internal/service/local_metadata_apply.go @@ -1,6 +1,6 @@ package service -import "github.com/ShukeBta/MediaStationGo/internal/model" +import "github.com/ShukeBta/MMTL/internal/model" func applyLocalMetadata(m *model.Media, local *LocalMetadata) { applyLocalIdentityMetadata(m, local) diff --git a/internal/service/local_metadata_apply_test.go b/internal/service/local_metadata_apply_test.go index 3d75bf6..7228e71 100644 --- a/internal/service/local_metadata_apply_test.go +++ b/internal/service/local_metadata_apply_test.go @@ -3,7 +3,7 @@ package service import ( "testing" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func TestApplyLocalMetadataPreservesPathHintAsPending(t *testing.T) { diff --git a/internal/service/manual_scrape.go b/internal/service/manual_scrape.go index 125e0ad..0c5ddb9 100644 --- a/internal/service/manual_scrape.go +++ b/internal/service/manual_scrape.go @@ -5,7 +5,7 @@ import ( "errors" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) type ManualScrapeRequest struct { diff --git a/internal/service/manual_scrape_providers.go b/internal/service/manual_scrape_providers.go index cd5603e..ec66883 100644 --- a/internal/service/manual_scrape_providers.go +++ b/internal/service/manual_scrape_providers.go @@ -4,7 +4,7 @@ import ( "context" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) type manualTMDbCandidate struct { diff --git a/internal/service/manual_scrape_search.go b/internal/service/manual_scrape_search.go index baa0913..794f90e 100644 --- a/internal/service/manual_scrape_search.go +++ b/internal/service/manual_scrape_search.go @@ -5,7 +5,7 @@ import ( "errors" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func (s *ScraperService) ManualSearch(ctx context.Context, media *model.Media, query, provider, mediaType string) ([]ExternalMediaResult, error) { diff --git a/internal/service/manual_scrape_test.go b/internal/service/manual_scrape_test.go index 2497123..8dae327 100644 --- a/internal/service/manual_scrape_test.go +++ b/internal/service/manual_scrape_test.go @@ -13,9 +13,9 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func TestManualRequestMatchFallsBackToCandidatePayload(t *testing.T) { diff --git a/internal/service/media.go b/internal/service/media.go index 165ce8d..6e834cc 100644 --- a/internal/service/media.go +++ b/internal/service/media.go @@ -4,9 +4,9 @@ package service import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) // MediaService offers high-level CRUD over libraries and media items. diff --git a/internal/service/media_cache.go b/internal/service/media_cache.go index c5cef9f..32d69b2 100644 --- a/internal/service/media_cache.go +++ b/internal/service/media_cache.go @@ -8,8 +8,8 @@ import ( "sort" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) type mediaListCacheValue struct { diff --git a/internal/service/media_classifier.go b/internal/service/media_classifier.go index 56645a5..6d5769b 100644 --- a/internal/service/media_classifier.go +++ b/internal/service/media_classifier.go @@ -5,7 +5,7 @@ import ( "regexp" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) var ( diff --git a/internal/service/media_display_library.go b/internal/service/media_display_library.go index 2af44cf..f85d7f9 100644 --- a/internal/service/media_display_library.go +++ b/internal/service/media_display_library.go @@ -4,8 +4,8 @@ import ( "context" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func (s *MediaService) attachLibraryMetadata(ctx context.Context, items []model.Media) { diff --git a/internal/service/media_library.go b/internal/service/media_library.go index ffb6948..a9ae985 100644 --- a/internal/service/media_library.go +++ b/internal/service/media_library.go @@ -3,7 +3,7 @@ package service import ( "context" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" "gorm.io/gorm" ) diff --git a/internal/service/media_library_roots.go b/internal/service/media_library_roots.go index 47a57fb..014cb10 100644 --- a/internal/service/media_library_roots.go +++ b/internal/service/media_library_roots.go @@ -7,7 +7,7 @@ import ( "path/filepath" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) type LibraryRootInput struct { diff --git a/internal/service/media_library_roots_test.go b/internal/service/media_library_roots_test.go index 6b9d7ae..d643354 100644 --- a/internal/service/media_library_roots_test.go +++ b/internal/service/media_library_roots_test.go @@ -6,9 +6,9 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func TestCreateLibraryWithRootsAppendsToExistingLogicalLibrary(t *testing.T) { diff --git a/internal/service/media_listing.go b/internal/service/media_listing.go index b3afa5c..59776cf 100644 --- a/internal/service/media_listing.go +++ b/internal/service/media_listing.go @@ -6,8 +6,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) // ListMedia paginates media items inside a library. diff --git a/internal/service/media_metadata.go b/internal/service/media_metadata.go index 4e3f750..0e8b33c 100644 --- a/internal/service/media_metadata.go +++ b/internal/service/media_metadata.go @@ -5,7 +5,7 @@ import ( "errors" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) type MediaMetadataUpdate struct { diff --git a/internal/service/media_metadata_test.go b/internal/service/media_metadata_test.go index 77efaba..97665e4 100644 --- a/internal/service/media_metadata_test.go +++ b/internal/service/media_metadata_test.go @@ -5,9 +5,9 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func TestUpdateMediaMetadataMarksManualMatch(t *testing.T) { diff --git a/internal/service/media_paths.go b/internal/service/media_paths.go index 03e10a9..44939a8 100644 --- a/internal/service/media_paths.go +++ b/internal/service/media_paths.go @@ -69,8 +69,8 @@ func embeddedContainerMarkerCandidates(input string) []string { part string container string }{ - {part: "/media", container: envOrDefault("MEDIASTATION_MEDIA_CONTAINER_DIR", "/media")}, - {part: "/downloads", container: envOrDefault("MEDIASTATION_DOWNLOAD_CONTAINER_DIR", "/downloads")}, + {part: "/media", container: envOrDefault("MMTL_MEDIA_CONTAINER_DIR", "/media")}, + {part: "/downloads", container: envOrDefault("MMTL_DOWNLOAD_CONTAINER_DIR", "/downloads")}, } { part := strings.TrimRight(marker.part, "/") container := strings.TrimRight(filepath.ToSlash(marker.container), "/") @@ -83,17 +83,17 @@ func embeddedContainerMarkerCandidates(input string) []string { // describeUnresolvedLibraryPath 把「路径解析失败」变成可操作的诊断信息:列出尝试过的 // 候选路径与当前的宿主机→容器映射状态。旧库存的是宿主机路径,在新版/容器内常因为缺少 -// MEDIASTATION_MEDIA_DIR 映射而扫不出媒体——这条诊断帮助用户直接定位到底哪一步断了。 +// MMTL_MEDIA_DIR 映射而扫不出媒体——这条诊断帮助用户直接定位到底哪一步断了。 // 仅用于日志与扫描错误提示,不改变解析逻辑本身。 func describeUnresolvedLibraryPath(rawPath string) string { rawPath = strings.TrimSpace(rawPath) candidates := mappedPathCandidates(rawPath) - mediaHost := strings.TrimSpace(os.Getenv("MEDIASTATION_MEDIA_DIR")) - mediaContainer := envOrDefault("MEDIASTATION_MEDIA_CONTAINER_DIR", "/media") + mediaHost := strings.TrimSpace(os.Getenv("MMTL_MEDIA_DIR")) + mediaContainer := envOrDefault("MMTL_MEDIA_CONTAINER_DIR", "/media") var b strings.Builder fmt.Fprintf(&b, "媒体库路径无法解析为可访问目录:%s(已尝试候选:%s)", rawPath, strings.Join(candidates, " | ")) if mediaHost == "" { - b.WriteString(";未配置 MEDIASTATION_MEDIA_DIR / MEDIASTATION_MEDIA_CONTAINER_DIR。若为 Docker 部署且此库为旧宿主机路径,请设置这两个变量把宿主机路径映射到容器内路径,并确认对应 volume 已挂载。") + b.WriteString(";未配置 MMTL_MEDIA_DIR / MMTL_MEDIA_CONTAINER_DIR。若为 Docker 部署且此库为旧宿主机路径,请设置这两个变量把宿主机路径映射到容器内路径,并确认对应 volume 已挂载。") } else { fmt.Fprintf(&b, ";当前映射 %s → %s。请确认该库路径位于此宿主机目录下,或补充对应的 volume 与路径映射。", mediaHost, mediaContainer) } @@ -204,8 +204,8 @@ func dockerVolumePathCandidates(path string) []string { env string container string }{ - {env: "MEDIASTATION_MEDIA_DIR", container: envOrDefault("MEDIASTATION_MEDIA_CONTAINER_DIR", "/media")}, - {env: "MEDIASTATION_DOWNLOAD_DIR", container: envOrDefault("MEDIASTATION_DOWNLOAD_CONTAINER_DIR", "/downloads")}, + {env: "MMTL_MEDIA_DIR", container: envOrDefault("MMTL_MEDIA_CONTAINER_DIR", "/media")}, + {env: "MMTL_DOWNLOAD_DIR", container: envOrDefault("MMTL_DOWNLOAD_CONTAINER_DIR", "/downloads")}, } { container := cleanPathForVolumeMapping(mapping.container) if container == "." || container == "" || strings.HasPrefix(container, ".") { @@ -247,8 +247,8 @@ func dockerVolumePathCandidates(path string) []string { part string container string }{ - {part: "/media", container: envOrDefault("MEDIASTATION_MEDIA_CONTAINER_DIR", "/media")}, - {part: "/downloads", container: envOrDefault("MEDIASTATION_DOWNLOAD_CONTAINER_DIR", "/downloads")}, + {part: "/media", container: envOrDefault("MMTL_MEDIA_CONTAINER_DIR", "/media")}, + {part: "/downloads", container: envOrDefault("MMTL_DOWNLOAD_CONTAINER_DIR", "/downloads")}, } { part := strings.TrimRight(marker.part, "/") container := strings.TrimRight(filepath.ToSlash(marker.container), "/") diff --git a/internal/service/media_recycle.go b/internal/service/media_recycle.go index 9c959fe..996533b 100644 --- a/internal/service/media_recycle.go +++ b/internal/service/media_recycle.go @@ -5,7 +5,7 @@ import ( "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) const maxRecycleBinRecords = 200 diff --git a/internal/service/media_recycle_test.go b/internal/service/media_recycle_test.go index 1e5796d..86deecb 100644 --- a/internal/service/media_recycle_test.go +++ b/internal/service/media_recycle_test.go @@ -9,9 +9,9 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func TestListRecycleBinPrunesOldRowsOverLimit(t *testing.T) { diff --git a/internal/service/media_release_sort.go b/internal/service/media_release_sort.go index 6575328..8078420 100644 --- a/internal/service/media_release_sort.go +++ b/internal/service/media_release_sort.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func mediaReleaseSortTime(media model.Media) time.Time { diff --git a/internal/service/media_search.go b/internal/service/media_search.go index f70d03b..d41b5c3 100644 --- a/internal/service/media_search.go +++ b/internal/service/media_search.go @@ -3,8 +3,8 @@ package service import ( "context" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) // SearchMedia performs a simple LIKE search across titles. diff --git a/internal/service/media_series.go b/internal/service/media_series.go index 9290c15..704fdc2 100644 --- a/internal/service/media_series.go +++ b/internal/service/media_series.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) type SeriesCard struct { diff --git a/internal/service/media_series_key.go b/internal/service/media_series_key.go index aab17ec..0aa7731 100644 --- a/internal/service/media_series_key.go +++ b/internal/service/media_series_key.go @@ -6,7 +6,7 @@ import ( "regexp" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) var episodicPathRE = regexp.MustCompile(`(?i)[\\/](?:电视剧|剧集|连续剧|短剧|国产剧|国剧|大陆剧|华语剧|国产电视剧|大陆电视剧|华语电视剧|欧美剧|欧美电视剧|美剧|英剧|日韩剧|日韩电视剧|日剧|韩剧|港剧|台剧|港台剧|泰剧|综艺|纪录片|儿童|动漫|番剧|国漫|日番|韩漫|美漫|欧美动漫|欧美动画|其他动漫|tv|series|shows?|season[\s._-]*\d|s\d{1,2}(?:[\s._-]|[\\/])|special[\s._-]*episodes?|specials?|sp|ovas?|oads?|extras?|bonus(?:es)?|omake|特别篇|特別篇|番外篇?|特典|外传|外傳|总集篇|總集篇)[\\/]`) diff --git a/internal/service/media_series_resolver.go b/internal/service/media_series_resolver.go index 2ac2ed0..a4ce7c0 100644 --- a/internal/service/media_series_resolver.go +++ b/internal/service/media_series_resolver.go @@ -4,7 +4,7 @@ import ( "fmt" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) type mediaSeriesKeyResolver struct { diff --git a/internal/service/media_series_test.go b/internal/service/media_series_test.go index 2eca31c..67c1ffb 100644 --- a/internal/service/media_series_test.go +++ b/internal/service/media_series_test.go @@ -7,9 +7,9 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func TestListRecentSeriesCardsCountsAllEpisodesInSeries(t *testing.T) { diff --git a/internal/service/media_test.go b/internal/service/media_test.go index 48a4349..feccd94 100644 --- a/internal/service/media_test.go +++ b/internal/service/media_test.go @@ -14,8 +14,8 @@ func TestResolveAccessibleLibraryPathMapsConfiguredHostMediaDir(t *testing.T) { if err := os.MkdirAll(containerLibrary, 0o755); err != nil { t.Fatal(err) } - t.Setenv("MEDIASTATION_MEDIA_DIR", hostRoot) - t.Setenv("MEDIASTATION_MEDIA_CONTAINER_DIR", containerRoot) + t.Setenv("MMTL_MEDIA_DIR", hostRoot) + t.Setenv("MMTL_MEDIA_CONTAINER_DIR", containerRoot) got, err := resolveAccessibleLibraryPath(filepath.Join(hostRoot, "电视剧", "国产剧")) if err != nil { @@ -33,8 +33,8 @@ func TestResolveAccessibleLibraryPathMapsWindowsDriveBeforeLinuxAbs(t *testing.T if err := os.MkdirAll(containerLibrary, 0o755); err != nil { t.Fatal(err) } - t.Setenv("MEDIASTATION_MEDIA_DIR", `Q:\media`) - t.Setenv("MEDIASTATION_MEDIA_CONTAINER_DIR", containerRoot) + t.Setenv("MMTL_MEDIA_DIR", `Q:\media`) + t.Setenv("MMTL_MEDIA_CONTAINER_DIR", containerRoot) for _, input := range []string{ `Q:\media\电视剧\国产剧`, @@ -61,8 +61,8 @@ func TestResolveAccessibleLibraryPathRecoversDockerPollutedWindowsDrive(t *testi if err := os.MkdirAll(containerLibrary, 0o755); err != nil { t.Fatal(err) } - t.Setenv("MEDIASTATION_MEDIA_DIR", `F:\media`) - t.Setenv("MEDIASTATION_MEDIA_CONTAINER_DIR", containerRoot) + t.Setenv("MMTL_MEDIA_DIR", `F:\media`) + t.Setenv("MMTL_MEDIA_CONTAINER_DIR", containerRoot) got, err := resolveAccessibleLibraryPath(`/app/F:\media\电视剧\国产剧`) if err != nil { @@ -95,7 +95,7 @@ func TestResolveAccessibleLibraryPathMapsRelativeDockerMediaMarker(t *testing.T) if err := os.MkdirAll(containerLibrary, 0o755); err != nil { t.Fatal(err) } - t.Setenv("MEDIASTATION_MEDIA_CONTAINER_DIR", containerRoot) + t.Setenv("MMTL_MEDIA_CONTAINER_DIR", containerRoot) got, err := resolveAccessibleLibraryPath(filepath.Join("media", "电视剧", "国产剧")) if err != nil { @@ -116,7 +116,7 @@ func TestResolveAccessibleLibraryPathMapsEmbeddedHostMediaMarker(t *testing.T) { if err := os.MkdirAll(containerLibrary, 0o755); err != nil { t.Fatal(err) } - t.Setenv("MEDIASTATION_MEDIA_CONTAINER_DIR", containerRoot) + t.Setenv("MMTL_MEDIA_CONTAINER_DIR", containerRoot) got, err := resolveAccessibleLibraryPath("/vol1/1000/Docker/moviepilot-v2/media/电视剧/国产剧") if err != nil { @@ -134,7 +134,7 @@ func TestResolveAccessibleMappedPathMapsEmbeddedHostDownloadMarker(t *testing.T) if err := os.MkdirAll(containerItem, 0o755); err != nil { t.Fatal(err) } - t.Setenv("MEDIASTATION_DOWNLOAD_CONTAINER_DIR", containerDownloads) + t.Setenv("MMTL_DOWNLOAD_CONTAINER_DIR", containerDownloads) got, _, err := resolveAccessibleMappedPath("/vol1/1000/Docker/qbittorrent/downloads/国产剧") if err != nil { @@ -180,7 +180,7 @@ func TestMappedPathCandidatesMapWindowsDriveDownloadMarker(t *testing.T) { root := t.TempDir() containerDownloads := filepath.Join(root, "container", "downloads") containerLibrary := filepath.Join(containerDownloads, "国产剧") - t.Setenv("MEDIASTATION_DOWNLOAD_CONTAINER_DIR", containerDownloads) + t.Setenv("MMTL_DOWNLOAD_CONTAINER_DIR", containerDownloads) want := filepath.Clean(containerLibrary) for _, got := range mappedPathCandidates(`F:\downloads\国产剧`) { @@ -197,8 +197,8 @@ func TestResolveMappedDestinationPathPrefersConfiguredContainerMapping(t *testin if err := os.MkdirAll(containerMedia, 0o755); err != nil { t.Fatal(err) } - t.Setenv("MEDIASTATION_MEDIA_DIR", `Q:\media`) - t.Setenv("MEDIASTATION_MEDIA_CONTAINER_DIR", containerMedia) + t.Setenv("MMTL_MEDIA_DIR", `Q:\media`) + t.Setenv("MMTL_MEDIA_CONTAINER_DIR", containerMedia) for _, input := range []string{`Q:\media`, `Q:/media`, `/app/Q:\media`} { t.Run(input, func(t *testing.T) { @@ -221,7 +221,7 @@ func TestResolveMappedDestinationPathPrefersContainerForRelativeMediaMarker(t *t t.Fatal(err) } t.Chdir(workDir) - t.Setenv("MEDIASTATION_MEDIA_CONTAINER_DIR", containerMedia) + t.Setenv("MMTL_MEDIA_CONTAINER_DIR", containerMedia) got := resolveMappedDestinationPath(filepath.Join("media", "电视剧", "国产剧")) want := filepath.Join(containerMedia, "电视剧", "国产剧") @@ -237,8 +237,8 @@ func TestResolveAccessibleMappedPathMapsWindowsDownloadVariants(t *testing.T) { if err := os.MkdirAll(containerSource, 0o755); err != nil { t.Fatal(err) } - t.Setenv("MEDIASTATION_DOWNLOAD_DIR", `Q:\downloads`) - t.Setenv("MEDIASTATION_DOWNLOAD_CONTAINER_DIR", containerDownloads) + t.Setenv("MMTL_DOWNLOAD_DIR", `Q:\downloads`) + t.Setenv("MMTL_DOWNLOAD_CONTAINER_DIR", containerDownloads) for _, input := range []string{`Q:\downloads\国产剧`, `Q:/downloads/国产剧`, `/app/Q:\downloads\国产剧`} { t.Run(input, func(t *testing.T) { diff --git a/internal/service/media_versions.go b/internal/service/media_versions.go index aee7ab3..10c5420 100644 --- a/internal/service/media_versions.go +++ b/internal/service/media_versions.go @@ -5,7 +5,7 @@ import ( "sort" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) type MediaItem struct { diff --git a/internal/service/media_versions_test.go b/internal/service/media_versions_test.go index 89344fa..2515d26 100644 --- a/internal/service/media_versions_test.go +++ b/internal/service/media_versions_test.go @@ -6,9 +6,9 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func TestGroupMediaVersionsMergesEpisodeByExternalIDAcrossLibraries(t *testing.T) { diff --git a/internal/service/media_visibility_test.go b/internal/service/media_visibility_test.go index 42dfd2a..1264ada 100644 --- a/internal/service/media_visibility_test.go +++ b/internal/service/media_visibility_test.go @@ -5,9 +5,9 @@ import ( "slices" "testing" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" "go.uber.org/zap" ) diff --git a/internal/service/metatube.go b/internal/service/metatube.go index 6b7df6c..002c88b 100644 --- a/internal/service/metatube.go +++ b/internal/service/metatube.go @@ -273,7 +273,7 @@ func (p *MetaTubeProvider) applyAuthHeader(req *http.Request, token string) { req.Header.Set("X-Token", token) } req.Header.Set("Accept", "application/json") - req.Header.Set("User-Agent", "MediaStationGo/1.0 (MetaTube Client)") + req.Header.Set("User-Agent", "MMTL/1.0 (MetaTube Client)") } func (p *MetaTubeProvider) convertSearchResultToMatch(query string, res *MetaTubeSearchResult) *Match { diff --git a/internal/service/nfo.go b/internal/service/nfo.go index 3d0ee65..a78b75a 100644 --- a/internal/service/nfo.go +++ b/internal/service/nfo.go @@ -22,8 +22,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) // NFOService is the entry point used by the admin "导出 NFO" action. diff --git a/internal/service/nfo_test.go b/internal/service/nfo_test.go index 67e385b..db70eeb 100644 --- a/internal/service/nfo_test.go +++ b/internal/service/nfo_test.go @@ -6,13 +6,13 @@ import ( "strings" "testing" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func TestWriteMediaNFOUsesMappedDestinationPath(t *testing.T) { root := t.TempDir() - t.Setenv("MEDIASTATION_MEDIA_DIR", root) - t.Setenv("MEDIASTATION_MEDIA_CONTAINER_DIR", "/media") + t.Setenv("MMTL_MEDIA_DIR", root) + t.Setenv("MMTL_MEDIA_CONTAINER_DIR", "/media") mediaPath := filepath.Join(root, "电影", "测试电影.mkv") if err := os.MkdirAll(filepath.Dir(mediaPath), 0o755); err != nil { t.Fatal(err) diff --git a/internal/service/organize_naming_test.go b/internal/service/organize_naming_test.go index 5eb8b47..f511edc 100644 --- a/internal/service/organize_naming_test.go +++ b/internal/service/organize_naming_test.go @@ -8,8 +8,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" ) // TestOrganizeNaming locks in the rename pipeline used by OrganizeDirectory: diff --git a/internal/service/organize_pipeline.go b/internal/service/organize_pipeline.go index 6b819b7..b22f2f2 100644 --- a/internal/service/organize_pipeline.go +++ b/internal/service/organize_pipeline.go @@ -8,7 +8,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/repository" ) type OrganizeScope string diff --git a/internal/service/organize_pipeline_audit.go b/internal/service/organize_pipeline_audit.go index be6214e..9be6a8e 100644 --- a/internal/service/organize_pipeline_audit.go +++ b/internal/service/organize_pipeline_audit.go @@ -7,7 +7,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func organizeFatalResultError(res *OrganizeResult) error { diff --git a/internal/service/organize_pipeline_sync.go b/internal/service/organize_pipeline_sync.go index 1f0344d..47c22ce 100644 --- a/internal/service/organize_pipeline_sync.go +++ b/internal/service/organize_pipeline_sync.go @@ -7,7 +7,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func (p *OrganizePipelineService) syncScrapedOrganizedNames(ctx context.Context, opts OrganizeOptions, res *OrganizeResult, path string) { diff --git a/internal/service/organize_pipeline_test.go b/internal/service/organize_pipeline_test.go index ca933b8..b712f46 100644 --- a/internal/service/organize_pipeline_test.go +++ b/internal/service/organize_pipeline_test.go @@ -8,7 +8,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func TestOrganizeScanRootUsesActualOrganizedTarget(t *testing.T) { diff --git a/internal/service/organizer.go b/internal/service/organizer.go index b6b1511..a8d7c68 100644 --- a/internal/service/organizer.go +++ b/internal/service/organizer.go @@ -20,9 +20,9 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) // OrganizerService moves/renames files into library structures. diff --git a/internal/service/organizer_classification_test.go b/internal/service/organizer_classification_test.go index 12b84b9..67d8509 100644 --- a/internal/service/organizer_classification_test.go +++ b/internal/service/organizer_classification_test.go @@ -11,8 +11,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" ) func TestOrganizeDirectoryClassifiesScraperMatchBeforeRename(t *testing.T) { diff --git a/internal/service/organizer_classify.go b/internal/service/organizer_classify.go index 6b33882..0a87852 100644 --- a/internal/service/organizer_classify.go +++ b/internal/service/organizer_classify.go @@ -5,7 +5,7 @@ import ( "path/filepath" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // isSmartClassifyEnabled checks database settings first, then config.yaml. diff --git a/internal/service/organizer_directory_classification_test.go b/internal/service/organizer_directory_classification_test.go index e9550e1..7f209e1 100644 --- a/internal/service/organizer_directory_classification_test.go +++ b/internal/service/organizer_directory_classification_test.go @@ -7,8 +7,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" ) func TestOrganizeDirectoryUsesDownloadCategoryLayout(t *testing.T) { diff --git a/internal/service/organizer_directory_dedup_test.go b/internal/service/organizer_directory_dedup_test.go index c7ff86f..4f1dcaa 100644 --- a/internal/service/organizer_directory_dedup_test.go +++ b/internal/service/organizer_directory_dedup_test.go @@ -7,8 +7,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" ) // TestOrganizeDirectoryDedup verifies that media already present in the diff --git a/internal/service/organizer_directory_libraries.go b/internal/service/organizer_directory_libraries.go index a7a7ddb..a3582f3 100644 --- a/internal/service/organizer_directory_libraries.go +++ b/internal/service/organizer_directory_libraries.go @@ -8,7 +8,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func (o *OrganizerService) organizeLibraryRootForLayout(ctx context.Context, destRoot, mediaType, category string) (string, bool) { diff --git a/internal/service/organizer_directory_metadata.go b/internal/service/organizer_directory_metadata.go index ea92722..36c7575 100644 --- a/internal/service/organizer_directory_metadata.go +++ b/internal/service/organizer_directory_metadata.go @@ -7,7 +7,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func (o *OrganizerService) lookupOrganizeMetadata(ctx context.Context, src, sourceRoot, mediaType, title string, year, season, episode int, cache map[string]*Match) *Match { diff --git a/internal/service/organizer_directory_metadata_persist.go b/internal/service/organizer_directory_metadata_persist.go index f784e8b..80f8dff 100644 --- a/internal/service/organizer_directory_metadata_persist.go +++ b/internal/service/organizer_directory_metadata_persist.go @@ -8,7 +8,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func (o *OrganizerService) persistOrganizedSourceMetadata(ctx context.Context, plan organizeSourceFilePlan) { diff --git a/internal/service/organizer_directory_source.go b/internal/service/organizer_directory_source.go index 15c4c37..5ec59be 100644 --- a/internal/service/organizer_directory_source.go +++ b/internal/service/organizer_directory_source.go @@ -6,7 +6,7 @@ import ( "path/filepath" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) type organizeDirectoryLayout struct { diff --git a/internal/service/organizer_directory_source_test.go b/internal/service/organizer_directory_source_test.go index 1a83ae5..d8ea801 100644 --- a/internal/service/organizer_directory_source_test.go +++ b/internal/service/organizer_directory_source_test.go @@ -7,7 +7,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) func TestOrganizeDirectoryUsesConfiguredSourceWhenRequestSourceEmpty(t *testing.T) { @@ -42,10 +42,10 @@ func TestOrganizeDirectoryMapsConfiguredHostPathsToContainerPaths(t *testing.T) containerSource := filepath.Join(containerDownloads, "国产剧") writeOrgFile(t, filepath.Join(containerSource, "Some Show S01E01 2024 1080p.mkv"), "show-e01") - t.Setenv("MEDIASTATION_DOWNLOAD_DIR", hostDownloads) - t.Setenv("MEDIASTATION_DOWNLOAD_CONTAINER_DIR", containerDownloads) - t.Setenv("MEDIASTATION_MEDIA_DIR", hostMedia) - t.Setenv("MEDIASTATION_MEDIA_CONTAINER_DIR", containerMedia) + t.Setenv("MMTL_DOWNLOAD_DIR", hostDownloads) + t.Setenv("MMTL_DOWNLOAD_CONTAINER_DIR", containerDownloads) + t.Setenv("MMTL_MEDIA_DIR", hostMedia) + t.Setenv("MMTL_MEDIA_CONTAINER_DIR", containerMedia) repos := newOrganizerTestRepo(t) for key, value := range map[string]string{ @@ -106,8 +106,8 @@ func TestOrganizeSourceCandidatesOnlyReturnAccessibleDirectories(t *testing.T) { if err := os.MkdirAll(downloadDir, 0o755); err != nil { t.Fatal(err) } - t.Setenv("MEDIASTATION_DOWNLOAD_CONTAINER_DIR", downloadDir) - t.Setenv("MEDIASTATION_MEDIA_CONTAINER_DIR", filepath.Join(root, "missing-media")) + t.Setenv("MMTL_DOWNLOAD_CONTAINER_DIR", downloadDir) + t.Setenv("MMTL_MEDIA_CONTAINER_DIR", filepath.Join(root, "missing-media")) repos := newOrganizerTestRepo(t) if err := repos.Setting.Set(t.Context(), "organize.source_dir", configuredDir); err != nil { @@ -128,7 +128,7 @@ func TestOrganizeSourceCandidatesOnlyReturnAccessibleDirectories(t *testing.T) { if err := os.MkdirAll(mediaDir, 0o755); err != nil { t.Fatal(err) } - t.Setenv("MEDIASTATION_MEDIA_CONTAINER_DIR", mediaDir) + t.Setenv("MMTL_MEDIA_CONTAINER_DIR", mediaDir) candidates = org.OrganizeSourceCandidates(t.Context()) if len(candidates) != 3 { t.Fatalf("candidates = %#v, want configured source, download and media dirs", candidates) diff --git a/internal/service/organizer_directory_sources.go b/internal/service/organizer_directory_sources.go index 78302e3..e8de025 100644 --- a/internal/service/organizer_directory_sources.go +++ b/internal/service/organizer_directory_sources.go @@ -41,8 +41,8 @@ func (o *OrganizerService) OrganizeSourceCandidates(ctx context.Context) []Organ } add("默认整理源", o.settingValue(ctx, "organize.source_dir"), "source") add("下载器保存目录", o.settingValue(ctx, "qbittorrent.savepath"), "download") - add("下载目录", envOrDefault("MEDIASTATION_DOWNLOAD_CONTAINER_DIR", "/downloads"), "download") - add("媒体目录", envOrDefault("MEDIASTATION_MEDIA_CONTAINER_DIR", "/media"), "media") + add("下载目录", envOrDefault("MMTL_DOWNLOAD_CONTAINER_DIR", "/downloads"), "download") + add("媒体目录", envOrDefault("MMTL_MEDIA_CONTAINER_DIR", "/media"), "media") return out } @@ -69,7 +69,7 @@ func (o *OrganizerService) defaultSourceRoot(ctx context.Context, override strin if v := o.settingValue(ctx, "qbittorrent.savepath"); v != "" { return v } - return envOrDefault("MEDIASTATION_DOWNLOAD_CONTAINER_DIR", "/downloads") + return envOrDefault("MMTL_DOWNLOAD_CONTAINER_DIR", "/downloads") } // defaultDestRoot resolves the destination root for a directory organize: @@ -83,7 +83,7 @@ func (o *OrganizerService) defaultDestRoot(ctx context.Context, override string) return strings.TrimSpace(v) } } - return envOrDefault("MEDIASTATION_MEDIA_CONTAINER_DIR", "/media") + return envOrDefault("MMTL_MEDIA_CONTAINER_DIR", "/media") } func ensureOrganizeDestinationWritable(dest string) error { @@ -97,7 +97,7 @@ func ensureOrganizeDestinationWritable(dest string) error { if err := os.MkdirAll(dest, 0o755); err != nil { // #nosec G301 -- organized media directories must remain readable by NAS/player users. return fmt.Errorf("destination path is not a writable directory: %s: %w", dest, err) } - probe, err := os.CreateTemp(dest, ".mediastation-write-test-*") // #nosec G304 -- dest is operator-configured organize root. + probe, err := os.CreateTemp(dest, ".mmtl-write-test-*") // #nosec G304 -- dest is operator-configured organize root. if err != nil { return fmt.Errorf("destination path is not writable: %s: %w", dest, err) } diff --git a/internal/service/organizer_directory_test.go b/internal/service/organizer_directory_test.go index a84d11a..e74923d 100644 --- a/internal/service/organizer_directory_test.go +++ b/internal/service/organizer_directory_test.go @@ -7,7 +7,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) func writeOrgFile(t *testing.T, path, content string) { diff --git a/internal/service/organizer_directory_versions.go b/internal/service/organizer_directory_versions.go index fcc6b57..dfaa369 100644 --- a/internal/service/organizer_directory_versions.go +++ b/internal/service/organizer_directory_versions.go @@ -10,7 +10,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // existingVersionPaths returns existing destination files that represent the diff --git a/internal/service/organizer_library_classification.go b/internal/service/organizer_library_classification.go index e3012f6..4a22d3c 100644 --- a/internal/service/organizer_library_classification.go +++ b/internal/service/organizer_library_classification.go @@ -5,7 +5,7 @@ import ( "path/filepath" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func organizeLibraryModelType(mediaType string) string { diff --git a/internal/service/organizer_localized_title_test.go b/internal/service/organizer_localized_title_test.go index 215cee1..0c1e27f 100644 --- a/internal/service/organizer_localized_title_test.go +++ b/internal/service/organizer_localized_title_test.go @@ -13,9 +13,9 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func TestOrganizeDirectoryUsesTMDbChineseAlternativeTitle(t *testing.T) { diff --git a/internal/service/organizer_media.go b/internal/service/organizer_media.go index d918d03..03ed401 100644 --- a/internal/service/organizer_media.go +++ b/internal/service/organizer_media.go @@ -9,7 +9,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) type organizeMediaRequest struct { diff --git a/internal/service/organizer_media_metadata.go b/internal/service/organizer_media_metadata.go index 2ac8364..c2b22d5 100644 --- a/internal/service/organizer_media_metadata.go +++ b/internal/service/organizer_media_metadata.go @@ -6,7 +6,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func (o *OrganizerService) refreshOrganizeMediaMetadata(ctx context.Context, media *model.Media, lib *model.Library, requestedType string) { diff --git a/internal/service/organizer_metadata_match.go b/internal/service/organizer_metadata_match.go index ac946ba..63bb1d6 100644 --- a/internal/service/organizer_metadata_match.go +++ b/internal/service/organizer_metadata_match.go @@ -6,7 +6,7 @@ import ( "path/filepath" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func organizeMetadataMatchTrusted(query string, sourceYear int, match *Match) bool { diff --git a/internal/service/organizer_reclassify_anime_test.go b/internal/service/organizer_reclassify_anime_test.go index c3414fc..2aa117e 100644 --- a/internal/service/organizer_reclassify_anime_test.go +++ b/internal/service/organizer_reclassify_anime_test.go @@ -7,8 +7,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" ) func TestOrganizeDirectoryReclassifiesScannedAnimeUsingDBMetadata(t *testing.T) { diff --git a/internal/service/organizer_reclassify_duplicates_test.go b/internal/service/organizer_reclassify_duplicates_test.go index 4c5e8cf..4174228 100644 --- a/internal/service/organizer_reclassify_duplicates_test.go +++ b/internal/service/organizer_reclassify_duplicates_test.go @@ -10,8 +10,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" ) func TestOrganizeDirectoryCleansWrongCategoryDuplicateWhenTargetExists(t *testing.T) { diff --git a/internal/service/organizer_reclassify_media_rows.go b/internal/service/organizer_reclassify_media_rows.go index 270fa9d..13a0a65 100644 --- a/internal/service/organizer_reclassify_media_rows.go +++ b/internal/service/organizer_reclassify_media_rows.go @@ -4,7 +4,7 @@ import ( "context" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func (o *OrganizerService) updateReclassifiedMediaRow(ctx context.Context, oldPath, newPath string, req organizeExistingReclassifyRequest) error { diff --git a/internal/service/organizer_reclassify_metadata.go b/internal/service/organizer_reclassify_metadata.go index fdf3d99..d6e62a0 100644 --- a/internal/service/organizer_reclassify_metadata.go +++ b/internal/service/organizer_reclassify_metadata.go @@ -6,7 +6,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func (o *OrganizerService) lookupReclassifyMetadata(ctx context.Context, media model.Media, lib model.Library, mediaType string) *Match { diff --git a/internal/service/organizer_reclassify_metadata_test.go b/internal/service/organizer_reclassify_metadata_test.go index babb664..ca6b734 100644 --- a/internal/service/organizer_reclassify_metadata_test.go +++ b/internal/service/organizer_reclassify_metadata_test.go @@ -10,8 +10,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" ) func TestOrganizeDirectoryCleansReleaseNoiseBeforeMetadataClassify(t *testing.T) { diff --git a/internal/service/organizer_reclassify_scanned.go b/internal/service/organizer_reclassify_scanned.go index b3a4730..5a98443 100644 --- a/internal/service/organizer_reclassify_scanned.go +++ b/internal/service/organizer_reclassify_scanned.go @@ -9,7 +9,7 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // MediaCategoryReclassifyOptions controls the metadata-based category audit. diff --git a/internal/service/organizer_reclassify_test.go b/internal/service/organizer_reclassify_test.go index 3876b70..b06db08 100644 --- a/internal/service/organizer_reclassify_test.go +++ b/internal/service/organizer_reclassify_test.go @@ -10,8 +10,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" ) func TestOrganizeDirectoryReclassifiesExistingWrongCategoryMedia(t *testing.T) { diff --git a/internal/service/organizer_scan.go b/internal/service/organizer_scan.go index 3f99128..243f5a2 100644 --- a/internal/service/organizer_scan.go +++ b/internal/service/organizer_scan.go @@ -5,8 +5,8 @@ import ( "path/filepath" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) // OrganizeScanSummary reports a library scan triggered after directory diff --git a/internal/service/organizer_scrape_providers_test.go b/internal/service/organizer_scrape_providers_test.go index 3a62908..78b0a60 100644 --- a/internal/service/organizer_scrape_providers_test.go +++ b/internal/service/organizer_scrape_providers_test.go @@ -11,8 +11,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" ) func TestOrganizeDirectoryUsesAdultMetadataBeforeRename(t *testing.T) { diff --git a/internal/service/organizer_scrape_safety_test.go b/internal/service/organizer_scrape_safety_test.go index 18b8d90..9f478e9 100644 --- a/internal/service/organizer_scrape_safety_test.go +++ b/internal/service/organizer_scrape_safety_test.go @@ -10,8 +10,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" ) func TestOrganizeDirectoryRejectsWrongYearScraperRename(t *testing.T) { diff --git a/internal/service/organizer_scrape_test.go b/internal/service/organizer_scrape_test.go index a9a853c..25aaa36 100644 --- a/internal/service/organizer_scrape_test.go +++ b/internal/service/organizer_scrape_test.go @@ -7,8 +7,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" ) func TestOrganizeDirectoryScanAndScrapeAfter(t *testing.T) { diff --git a/internal/service/organizer_settings.go b/internal/service/organizer_settings.go index 244386e..0e5991a 100644 --- a/internal/service/organizer_settings.go +++ b/internal/service/organizer_settings.go @@ -5,7 +5,7 @@ import ( "path/filepath" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // resolveBaseRoot picks the organize destination root (目的地目录): a diff --git a/internal/service/organizer_source_test.go b/internal/service/organizer_source_test.go index 085cc1e..5c0af59 100644 --- a/internal/service/organizer_source_test.go +++ b/internal/service/organizer_source_test.go @@ -8,8 +8,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" ) // TestOrganizeLibraryScopesToSourceDir verifies organize reads from the diff --git a/internal/service/organizer_test.go b/internal/service/organizer_test.go index b877d00..7885ba5 100644 --- a/internal/service/organizer_test.go +++ b/internal/service/organizer_test.go @@ -7,9 +7,9 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func TestOrganizeMediaReDetectsSeasonFromPath(t *testing.T) { diff --git a/internal/service/organizer_transfer_test.go b/internal/service/organizer_transfer_test.go index 2327915..05ed0e0 100644 --- a/internal/service/organizer_transfer_test.go +++ b/internal/service/organizer_transfer_test.go @@ -8,9 +8,9 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func newOrganizerTestRepo(t *testing.T) *repository.Container { diff --git a/internal/service/permission.go b/internal/service/permission.go index 0c95ba9..b58e855 100644 --- a/internal/service/permission.go +++ b/internal/service/permission.go @@ -11,8 +11,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) // PermissionService manages user permissions. diff --git a/internal/service/play_profile.go b/internal/service/play_profile.go index a85be7c..848c1e0 100644 --- a/internal/service/play_profile.go +++ b/internal/service/play_profile.go @@ -18,8 +18,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) // PlayProfileService manages PlayProfile rows. diff --git a/internal/service/play_profile_model.go b/internal/service/play_profile_model.go index c600b5a..d9301df 100644 --- a/internal/service/play_profile_model.go +++ b/internal/service/play_profile_model.go @@ -7,7 +7,7 @@ import ( "fmt" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // PlayProfileInput is the create/update payload accepted by the API. diff --git a/internal/service/play_profile_test.go b/internal/service/play_profile_test.go index ed9dd2a..7147486 100644 --- a/internal/service/play_profile_test.go +++ b/internal/service/play_profile_test.go @@ -4,8 +4,8 @@ import ( "errors" "testing" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" "go.uber.org/zap" ) diff --git a/internal/service/playback.go b/internal/service/playback.go index 3031720..c46ee5a 100644 --- a/internal/service/playback.go +++ b/internal/service/playback.go @@ -13,8 +13,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) // PlaybackService bundles history / favourite / playlist business logic. diff --git a/internal/service/profile.go b/internal/service/profile.go index 1b72d05..08e950d 100644 --- a/internal/service/profile.go +++ b/internal/service/profile.go @@ -8,8 +8,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) // ProfileService handles non-credential user mutations. diff --git a/internal/service/public_url.go b/internal/service/public_url.go index b1ce2db..d59cfbc 100644 --- a/internal/service/public_url.go +++ b/internal/service/public_url.go @@ -5,11 +5,11 @@ import ( "net/url" "strings" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/repository" ) -// PublicServerURL returns the operator-configured public MediaStationGo base +// PublicServerURL returns the operator-configured public MMTL base // URL. It is intentionally read from Setting first so Docker users only need to // fill one domain in the admin settings page after deployment. func PublicServerURL(ctx context.Context, repo *repository.Container, cfg *config.Config) string { diff --git a/internal/service/recognition_words.go b/internal/service/recognition_words.go index 93c4949..69406c2 100644 --- a/internal/service/recognition_words.go +++ b/internal/service/recognition_words.go @@ -11,8 +11,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) const ( diff --git a/internal/service/runtime_cache.go b/internal/service/runtime_cache.go index 1434fa3..6297d24 100644 --- a/internal/service/runtime_cache.go +++ b/internal/service/runtime_cache.go @@ -10,7 +10,7 @@ import ( "github.com/redis/go-redis/v9" "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) type RuntimeCacheService struct { @@ -35,7 +35,7 @@ func NewRuntimeCacheService(cfg *config.Config, log *zap.Logger) *RuntimeCacheSe } c.prefix = strings.Trim(strings.TrimSpace(cfg.Cache.RedisPrefix), ":") if c.prefix == "" { - c.prefix = "mediastationgo" + c.prefix = "mmtl" } rawURL := strings.TrimSpace(cfg.Cache.RedisURL) if rawURL == "" { diff --git a/internal/service/runtime_settings.go b/internal/service/runtime_settings.go index d10625c..d53777c 100644 --- a/internal/service/runtime_settings.go +++ b/internal/service/runtime_settings.go @@ -7,8 +7,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/repository" ) func ApplyRuntimeSettings(ctx context.Context, cfg *config.Config, repos *repository.Container, log *zap.Logger) { diff --git a/internal/service/runtime_settings_test.go b/internal/service/runtime_settings_test.go index b05ecfc..171d097 100644 --- a/internal/service/runtime_settings_test.go +++ b/internal/service/runtime_settings_test.go @@ -3,7 +3,7 @@ package service import ( "testing" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) func TestApplyRuntimeSettingTranscodeSwitches(t *testing.T) { diff --git a/internal/service/scanner.go b/internal/service/scanner.go index 521af10..5004e45 100644 --- a/internal/service/scanner.go +++ b/internal/service/scanner.go @@ -17,8 +17,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/repository" ) // videoExtensions lists the file extensions treated as media. Matches the diff --git a/internal/service/scanner_existing_media.go b/internal/service/scanner_existing_media.go index 15f224c..6411c7d 100644 --- a/internal/service/scanner_existing_media.go +++ b/internal/service/scanner_existing_media.go @@ -5,7 +5,7 @@ import ( "path/filepath" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func (s *ScannerService) existingLocalMediaSnapshot(ctx context.Context, libraryID string) (map[string]existingLocalMedia, error) { diff --git a/internal/service/scanner_existing_media_test.go b/internal/service/scanner_existing_media_test.go index 8d1aa7e..6a75ef2 100644 --- a/internal/service/scanner_existing_media_test.go +++ b/internal/service/scanner_existing_media_test.go @@ -4,9 +4,9 @@ import ( "path/filepath" "testing" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" "go.uber.org/zap" ) diff --git a/internal/service/scanner_incremental_test.go b/internal/service/scanner_incremental_test.go index 24502c5..f5655dd 100644 --- a/internal/service/scanner_incremental_test.go +++ b/internal/service/scanner_incremental_test.go @@ -10,9 +10,9 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func newScannerTestEnv(t *testing.T) (*ScannerService, *repository.Container) { @@ -425,8 +425,8 @@ func TestScanLibraryMapsPersistedHostLibraryPath(t *testing.T) { if err := os.WriteFile(file, []byte("episode"), 0o644); err != nil { t.Fatal(err) } - t.Setenv("MEDIASTATION_MEDIA_DIR", `Q:\media`) - t.Setenv("MEDIASTATION_MEDIA_CONTAINER_DIR", containerRoot) + t.Setenv("MMTL_MEDIA_DIR", `Q:\media`) + t.Setenv("MMTL_MEDIA_CONTAINER_DIR", containerRoot) lib := model.Library{Name: "国产剧", Path: `Q:\media\电视剧\国产剧`, Type: "tv", Enabled: true} if err := repos.Library.Create(t.Context(), &lib); err != nil { diff --git a/internal/service/scanner_library_roots_test.go b/internal/service/scanner_library_roots_test.go index a5c2ba9..9ea569b 100644 --- a/internal/service/scanner_library_roots_test.go +++ b/internal/service/scanner_library_roots_test.go @@ -7,8 +7,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func TestScanLibraryScansMultipleRootsAndPrunesPerRoot(t *testing.T) { diff --git a/internal/service/scanner_local_ingest.go b/internal/service/scanner_local_ingest.go index d649d66..8b523d4 100644 --- a/internal/service/scanner_local_ingest.go +++ b/internal/service/scanner_local_ingest.go @@ -8,7 +8,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // ingestFile upserts a single media file. seenInodes dedups hardlinks within a diff --git a/internal/service/scanner_local_metadata_test.go b/internal/service/scanner_local_metadata_test.go index b001085..3569e3f 100644 --- a/internal/service/scanner_local_metadata_test.go +++ b/internal/service/scanner_local_metadata_test.go @@ -7,9 +7,9 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func TestScanLibraryUsesLocalMetadata(t *testing.T) { diff --git a/internal/service/scanner_local_probe_queue.go b/internal/service/scanner_local_probe_queue.go index fd6d9e9..2bac0a4 100644 --- a/internal/service/scanner_local_probe_queue.go +++ b/internal/service/scanner_local_probe_queue.go @@ -7,7 +7,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func (s *ScannerService) localMediaProbeWorker() { diff --git a/internal/service/scanner_local_write_batch.go b/internal/service/scanner_local_write_batch.go index 7b38825..e85a53c 100644 --- a/internal/service/scanner_local_write_batch.go +++ b/internal/service/scanner_local_write_batch.go @@ -6,7 +6,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) type localMediaWriteBatch struct { diff --git a/internal/service/scanner_metadata_refresh.go b/internal/service/scanner_metadata_refresh.go index c46a079..693e807 100644 --- a/internal/service/scanner_metadata_refresh.go +++ b/internal/service/scanner_metadata_refresh.go @@ -3,7 +3,7 @@ package service import ( "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) type scanDerivedMetadata struct { diff --git a/internal/service/scanner_prune.go b/internal/service/scanner_prune.go index 415b5c5..a42bbce 100644 --- a/internal/service/scanner_prune.go +++ b/internal/service/scanner_prune.go @@ -8,7 +8,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // RemovePath deletes the media row for a path that has disappeared from disk diff --git a/internal/service/scanner_roots.go b/internal/service/scanner_roots.go index 2a18d67..3e5f5a9 100644 --- a/internal/service/scanner_roots.go +++ b/internal/service/scanner_roots.go @@ -8,7 +8,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func (s *ScannerService) localLibraryScanRoots(ctx context.Context, lib *model.Library) ([]model.LibraryRoot, error) { diff --git a/internal/service/scanner_scan.go b/internal/service/scanner_scan.go index 010bee9..2b22b54 100644 --- a/internal/service/scanner_scan.go +++ b/internal/service/scanner_scan.go @@ -9,7 +9,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // ScanLibrary walks the library root and persists discovered media files. @@ -100,8 +100,8 @@ func (s *ScannerService) scanLibrary(ctx context.Context, libraryID string, auto zap.String("root_id", root.ID), zap.String("path", root.Path), zap.Strings("candidates", mappedPathCandidates(root.Path)), - zap.String("media_dir_env", os.Getenv("MEDIASTATION_MEDIA_DIR")), - zap.String("media_container_env", envOrDefault("MEDIASTATION_MEDIA_CONTAINER_DIR", "/media")), + zap.String("media_dir_env", os.Getenv("MMTL_MEDIA_DIR")), + zap.String("media_container_env", envOrDefault("MMTL_MEDIA_CONTAINER_DIR", "/media")), zap.String("diagnostic", diag), zap.Error(err)) if scanErr == nil { diff --git a/internal/service/scheduler.go b/internal/service/scheduler.go index 9c2f66c..55abba2 100644 --- a/internal/service/scheduler.go +++ b/internal/service/scheduler.go @@ -25,7 +25,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/repository" ) // SchedulerService runs the periodic jobs. diff --git a/internal/service/scheduler_local_jobs.go b/internal/service/scheduler_local_jobs.go index e93af0a..8b51b1d 100644 --- a/internal/service/scheduler_local_jobs.go +++ b/internal/service/scheduler_local_jobs.go @@ -9,7 +9,7 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // jobScanLibraries re-walks every enabled library. diff --git a/internal/service/scheduler_organize_test.go b/internal/service/scheduler_organize_test.go index 1c1fea9..fc5947d 100644 --- a/internal/service/scheduler_organize_test.go +++ b/internal/service/scheduler_organize_test.go @@ -8,8 +8,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" ) func TestSchedulerOrganizeSourceDisabledByDefault(t *testing.T) { diff --git a/internal/service/scheduler_scan_test.go b/internal/service/scheduler_scan_test.go index d8686dd..98c7e09 100644 --- a/internal/service/scheduler_scan_test.go +++ b/internal/service/scheduler_scan_test.go @@ -7,9 +7,9 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func TestSchedulerPeriodicLocalScanRunsAtMostOncePerDay(t *testing.T) { diff --git a/internal/service/scraper.go b/internal/service/scraper.go index c60a7e4..17cbe30 100644 --- a/internal/service/scraper.go +++ b/internal/service/scraper.go @@ -11,7 +11,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // EnrichOne runs the provider chain for a single media row. diff --git a/internal/service/scraper_alias_match_test.go b/internal/service/scraper_alias_match_test.go index ad3bf38..d65006b 100644 --- a/internal/service/scraper_alias_match_test.go +++ b/internal/service/scraper_alias_match_test.go @@ -8,8 +8,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" ) func TestEnrichOneUsesAlternateLanguageTitleAndKeepsLocalizedMetadata(t *testing.T) { diff --git a/internal/service/scraper_artwork_test.go b/internal/service/scraper_artwork_test.go index 9c536ef..7b0603e 100644 --- a/internal/service/scraper_artwork_test.go +++ b/internal/service/scraper_artwork_test.go @@ -13,8 +13,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" ) func TestScrapeDelayUsesSettings(t *testing.T) { diff --git a/internal/service/scraper_episode_details_test.go b/internal/service/scraper_episode_details_test.go index a108179..c1885a7 100644 --- a/internal/service/scraper_episode_details_test.go +++ b/internal/service/scraper_episode_details_test.go @@ -13,9 +13,9 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func TestEnrichLibraryDefersEpisodeDetailsUntilMainMetadataFinishes(t *testing.T) { diff --git a/internal/service/scraper_library.go b/internal/service/scraper_library.go index 2b4bab3..c444bec 100644 --- a/internal/service/scraper_library.go +++ b/internal/service/scraper_library.go @@ -7,7 +7,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // lookup runs the provider chain after local NFO has been considered: diff --git a/internal/service/scraper_library_test.go b/internal/service/scraper_library_test.go index 9f7afd4..a48ac83 100644 --- a/internal/service/scraper_library_test.go +++ b/internal/service/scraper_library_test.go @@ -4,7 +4,7 @@ import ( "path/filepath" "testing" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func TestManualEnrichLibraryRetriesNoMatchAndCountsRealMatches(t *testing.T) { diff --git a/internal/service/scraper_local_metadata.go b/internal/service/scraper_local_metadata.go index 20ef214..800cadb 100644 --- a/internal/service/scraper_local_metadata.go +++ b/internal/service/scraper_local_metadata.go @@ -6,7 +6,7 @@ import ( "strconv" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func mediaYearHint(m *model.Media) int { diff --git a/internal/service/scraper_local_metadata_test.go b/internal/service/scraper_local_metadata_test.go index c8b171b..22cccbc 100644 --- a/internal/service/scraper_local_metadata_test.go +++ b/internal/service/scraper_local_metadata_test.go @@ -12,9 +12,9 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func TestEnrichOneRejectsWrongYearMatchFromSeriesFolder(t *testing.T) { diff --git a/internal/service/scraper_lookup.go b/internal/service/scraper_lookup.go index d8ada68..9ee7f51 100644 --- a/internal/service/scraper_lookup.go +++ b/internal/service/scraper_lookup.go @@ -6,7 +6,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func (s *ScraperService) matchFromMediaExternalIDs(ctx context.Context, m *model.Media, lib *model.Library) *Match { diff --git a/internal/service/scraper_lookup_test.go b/internal/service/scraper_lookup_test.go index cac7e2f..bc31b86 100644 --- a/internal/service/scraper_lookup_test.go +++ b/internal/service/scraper_lookup_test.go @@ -5,7 +5,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func TestMediaExternalIDMatchTrustsExactEpisodeID(t *testing.T) { diff --git a/internal/service/scraper_query.go b/internal/service/scraper_query.go index c5ea779..136df9b 100644 --- a/internal/service/scraper_query.go +++ b/internal/service/scraper_query.go @@ -6,8 +6,8 @@ import ( "regexp" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) var ( diff --git a/internal/service/scraper_query_candidates_test.go b/internal/service/scraper_query_candidates_test.go index bdb005f..3bfd070 100644 --- a/internal/service/scraper_query_candidates_test.go +++ b/internal/service/scraper_query_candidates_test.go @@ -4,7 +4,7 @@ import ( "strings" "testing" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func TestScrapeQueryCandidatesPreferSeriesFolderAndCJKTitle(t *testing.T) { diff --git a/internal/service/scraper_query_movie_test.go b/internal/service/scraper_query_movie_test.go index b98caae..f0fe5c3 100644 --- a/internal/service/scraper_query_movie_test.go +++ b/internal/service/scraper_query_movie_test.go @@ -11,9 +11,9 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func TestScrapeQueryCandidatesUseMovieFolderForGenericFilename(t *testing.T) { diff --git a/internal/service/scraper_query_test.go b/internal/service/scraper_query_test.go index 9d54c0b..4ba98d2 100644 --- a/internal/service/scraper_query_test.go +++ b/internal/service/scraper_query_test.go @@ -12,9 +12,9 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func TestCleanQuery(t *testing.T) { diff --git a/internal/service/scraper_service.go b/internal/service/scraper_service.go index e3150d2..ccb0ed9 100644 --- a/internal/service/scraper_service.go +++ b/internal/service/scraper_service.go @@ -5,9 +5,9 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) // ScraperService coordinates metadata enrichment across providers. diff --git a/internal/service/scraper_test.go b/internal/service/scraper_test.go index 5fc02a4..2500645 100644 --- a/internal/service/scraper_test.go +++ b/internal/service/scraper_test.go @@ -8,7 +8,7 @@ import ( "strings" "testing" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" "gorm.io/gorm" ) diff --git a/internal/service/scraper_test_helpers_test.go b/internal/service/scraper_test_helpers_test.go index d07eec4..c5e9932 100644 --- a/internal/service/scraper_test_helpers_test.go +++ b/internal/service/scraper_test_helpers_test.go @@ -11,9 +11,9 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func firstIndexFunc(values []string, match func(string) bool) int { diff --git a/internal/service/scraper_tmdb_details.go b/internal/service/scraper_tmdb_details.go index 16a4484..21c55aa 100644 --- a/internal/service/scraper_tmdb_details.go +++ b/internal/service/scraper_tmdb_details.go @@ -7,7 +7,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func (s *ScraperService) fetchAndSaveTMDbExtendedMetadata(ctx context.Context, mediaID string, tmdbID int, mediaType string) { diff --git a/internal/service/scraper_write_metadata_files.go b/internal/service/scraper_write_metadata_files.go index b49e465..8dbf510 100644 --- a/internal/service/scraper_write_metadata_files.go +++ b/internal/service/scraper_write_metadata_files.go @@ -8,7 +8,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // writeMediaArtworkFilesAfterScrape downloads the scraped poster/backdrop into diff --git a/internal/service/scraper_write_metadata_files_test.go b/internal/service/scraper_write_metadata_files_test.go index 5876853..e9e5416 100644 --- a/internal/service/scraper_write_metadata_files_test.go +++ b/internal/service/scraper_write_metadata_files_test.go @@ -7,7 +7,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) // TestWriteArtworkDataToPathWritesJellyfinSidecar verifies that in-memory diff --git a/internal/service/security_safety_test.go b/internal/service/security_safety_test.go index c5dede3..c859af3 100644 --- a/internal/service/security_safety_test.go +++ b/internal/service/security_safety_test.go @@ -4,7 +4,7 @@ import ( "path/filepath" "testing" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) func TestBackupFilePathRejectsTraversal(t *testing.T) { @@ -15,7 +15,7 @@ func TestBackupFilePathRejectsTraversal(t *testing.T) { t.Fatalf("backupFilePath(%q) allowed traversal or non-backup file", name) } } - path, err := svc.backupFilePath("mediastation_20260611_010203.db") + path, err := svc.backupFilePath("mmtl_20260611_010203.db") if err != nil { t.Fatalf("backupFilePath(valid) = %v", err) } diff --git a/internal/service/service.go b/internal/service/service.go index 25b67d4..c149d27 100644 --- a/internal/service/service.go +++ b/internal/service/service.go @@ -1,4 +1,4 @@ -// Package service 包含 MediaStationGo 的业务逻辑。 +// Package service 包含 MMTL 的业务逻辑。 // Handler 反序列化 HTTP 请求,调用 Service 方法,然后序列化响应。 // Services 拥有所有横切策略(认证、扫描、转码等)且不直接处理 HTTP 类型。 package service @@ -9,8 +9,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/repository" ) // Container 持有在启动时初始化的每个服务。Handler 接收指向它的指针并选择相关字段。 diff --git a/internal/service/service_builder.go b/internal/service/service_builder.go index fd2c8d1..5152685 100644 --- a/internal/service/service_builder.go +++ b/internal/service/service_builder.go @@ -6,8 +6,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/repository" ) type serviceContainerBuilder struct { diff --git a/internal/service/service_builder_library_roots_test.go b/internal/service/service_builder_library_roots_test.go index 92e179b..3c10a96 100644 --- a/internal/service/service_builder_library_roots_test.go +++ b/internal/service/service_builder_library_roots_test.go @@ -4,8 +4,8 @@ import ( "path/filepath" "testing" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func TestServiceBuilderLibraryRootsIncludesAllEnabledRoots(t *testing.T) { diff --git a/internal/service/service_library_normalize.go b/internal/service/service_library_normalize.go index d33bedd..fbda877 100644 --- a/internal/service/service_library_normalize.go +++ b/internal/service/service_library_normalize.go @@ -5,7 +5,7 @@ import ( "path/filepath" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func (c *Container) NormalizeLocalLibraryPaths(ctx context.Context) error { diff --git a/internal/service/service_library_normalize_test.go b/internal/service/service_library_normalize_test.go index 55ea372..df9133f 100644 --- a/internal/service/service_library_normalize_test.go +++ b/internal/service/service_library_normalize_test.go @@ -5,8 +5,8 @@ import ( "path/filepath" "testing" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func TestNormalizeLocalLibraryPathsRewritesRelativeDockerMediaRoot(t *testing.T) { @@ -16,7 +16,7 @@ func TestNormalizeLocalLibraryPathsRewritesRelativeDockerMediaRoot(t *testing.T) if err := os.MkdirAll(containerLibrary, 0o755); err != nil { t.Fatal(err) } - t.Setenv("MEDIASTATION_MEDIA_CONTAINER_DIR", containerRoot) + t.Setenv("MMTL_MEDIA_CONTAINER_DIR", containerRoot) db := newServiceTestDB(t, &model.Library{}, &model.LibraryRoot{}, &model.Media{}) repos := repository.New(db) diff --git a/internal/service/service_search_warmup.go b/internal/service/service_search_warmup.go index 6aa0250..df1c3de 100644 --- a/internal/service/service_search_warmup.go +++ b/internal/service/service_search_warmup.go @@ -8,7 +8,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/repository" ) func (c *Container) warmMediaSearchIndex(ctx context.Context) { diff --git a/internal/service/session_tracker_activity.go b/internal/service/session_tracker_activity.go index 00a97d4..3088ba2 100644 --- a/internal/service/session_tracker_activity.go +++ b/internal/service/session_tracker_activity.go @@ -5,7 +5,7 @@ import ( "strings" "time" - "github.com/ShukeBta/MediaStationGo/internal/model" + "github.com/ShukeBta/MMTL/internal/model" ) func (s *SessionTrackerService) ApplyToUsers(ctx context.Context, users []model.User) { diff --git a/internal/service/session_tracker_test.go b/internal/service/session_tracker_test.go index 04a431a..a3b5409 100644 --- a/internal/service/session_tracker_test.go +++ b/internal/service/session_tracker_test.go @@ -6,8 +6,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func TestSessionTrackerAppliesRealtimeActivityToUsers(t *testing.T) { diff --git a/internal/service/storage.go b/internal/service/storage.go index 7ba20ba..858c798 100644 --- a/internal/service/storage.go +++ b/internal/service/storage.go @@ -10,7 +10,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/repository" ) // StorageService is the read-only aggregator. diff --git a/internal/service/stream_cloud_settings.go b/internal/service/stream_cloud_settings.go index 210ea99..72cb27b 100644 --- a/internal/service/stream_cloud_settings.go +++ b/internal/service/stream_cloud_settings.go @@ -4,7 +4,7 @@ import ( "context" "strings" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/repository" ) func CloudPlaybackSettings(ctx context.Context, repo *repository.Container) CloudPlaybackOptions { diff --git a/internal/service/stream_file.go b/internal/service/stream_file.go index 1cfe242..eefacce 100644 --- a/internal/service/stream_file.go +++ b/internal/service/stream_file.go @@ -7,8 +7,8 @@ import ( "os" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) // ServeFile streams the file backing the given media ID using diff --git a/internal/service/stream_service.go b/internal/service/stream_service.go index 823bcc8..3908d35 100644 --- a/internal/service/stream_service.go +++ b/internal/service/stream_service.go @@ -6,8 +6,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/repository" ) const ( diff --git a/internal/service/stream_test.go b/internal/service/stream_test.go index c40fb0b..d623a82 100644 --- a/internal/service/stream_test.go +++ b/internal/service/stream_test.go @@ -10,9 +10,9 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func TestWithAuthTokenPropagatesToInternalRedirect(t *testing.T) { diff --git a/internal/service/strm_115_oauth.go b/internal/service/strm_115_oauth.go index a496184..d590fc9 100644 --- a/internal/service/strm_115_oauth.go +++ b/internal/service/strm_115_oauth.go @@ -19,8 +19,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/service/cloud115" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/service/cloud115" ) // strm115RelayKeySetting 是中继授权共享 AES 密钥的设置键。 diff --git a/internal/service/strm_115_oauth_test.go b/internal/service/strm_115_oauth_test.go index 45292e2..40a1f86 100644 --- a/internal/service/strm_115_oauth_test.go +++ b/internal/service/strm_115_oauth_test.go @@ -8,8 +8,8 @@ import ( "testing" "time" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/service/cloud115" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/service/cloud115" ) // Test115OAuthQRFlow 用 mock 的 115 开放平台接口走完设备码扫码授权: diff --git a/internal/service/strm_play.go b/internal/service/strm_play.go index afa7fa1..c6ce701 100644 --- a/internal/service/strm_play.go +++ b/internal/service/strm_play.go @@ -14,8 +14,8 @@ import ( "path/filepath" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/service/cloud" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/service/cloud" ) // ErrStrmPlayNotFound 表示 strm 播放目标不存在(handler 返回 404)。 diff --git a/internal/service/strm_queue.go b/internal/service/strm_queue.go index 7fd9817..20d87cc 100644 --- a/internal/service/strm_queue.go +++ b/internal/service/strm_queue.go @@ -17,9 +17,9 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/service/cloud" - "github.com/ShukeBta/MediaStationGo/internal/service/cloud115" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/service/cloud" + "github.com/ShukeBta/MMTL/internal/service/cloud115" ) const ( diff --git a/internal/service/strm_service.go b/internal/service/strm_service.go index 5226341..05e19f1 100644 --- a/internal/service/strm_service.go +++ b/internal/service/strm_service.go @@ -23,10 +23,10 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" - "github.com/ShukeBta/MediaStationGo/internal/service/cloud" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" + "github.com/ShukeBta/MMTL/internal/service/cloud" ) // strm 全局设置键(存于 Setting 表,strm.* 前缀)。 diff --git a/internal/service/strm_sync.go b/internal/service/strm_sync.go index f9aa9f1..7775dc0 100644 --- a/internal/service/strm_sync.go +++ b/internal/service/strm_sync.go @@ -17,8 +17,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/service/cloud" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/service/cloud" ) // strmSyncState 是一次同步执行的上下文。 diff --git a/internal/service/strm_sync_test.go b/internal/service/strm_sync_test.go index 2b05a2c..b14791c 100644 --- a/internal/service/strm_sync_test.go +++ b/internal/service/strm_sync_test.go @@ -14,9 +14,9 @@ import ( "gorm.io/gorm" "gorm.io/gorm/logger" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) // testStrmService 构建带内存库的 StrmService。 diff --git a/internal/service/subtitle.go b/internal/service/subtitle.go index 8ddf4cf..6b6f870 100644 --- a/internal/service/subtitle.go +++ b/internal/service/subtitle.go @@ -26,7 +26,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/repository" ) // SubtitleService is the discovery + conversion entry point. diff --git a/internal/service/subtitle_test.go b/internal/service/subtitle_test.go index 080cfa7..f86000e 100644 --- a/internal/service/subtitle_test.go +++ b/internal/service/subtitle_test.go @@ -10,8 +10,8 @@ import ( "go.uber.org/zap" "gorm.io/gorm" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func TestSubtitleDiscoverNoTracksReturnsEmptySlice(t *testing.T) { diff --git a/internal/service/system_update.go b/internal/service/system_update.go index ef6c68a..b793bc8 100644 --- a/internal/service/system_update.go +++ b/internal/service/system_update.go @@ -10,8 +10,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/repository" ) const ( @@ -20,7 +20,7 @@ const ( SystemUpdateCommandSettingKey = "system.update.command" SystemUpdateComposeDirSettingKey = "system.update.compose_dir" - DefaultSystemUpdateImage = "ghcr.io/shukebta/mediastation-go:latest" + DefaultSystemUpdateImage = "ghcr.io/shukebta/mmtl:latest" DefaultSystemUpdateWatchtowerImage = "containrrr/watchtower:latest" ) @@ -198,11 +198,11 @@ func (s *SystemUpdateService) startUpdateTask(status SystemUpdateStatus) *TaskHa } func (s *SystemUpdateService) baseStatus(ctx context.Context) SystemUpdateStatus { - image := s.setting(ctx, SystemUpdateImageSettingKey, os.Getenv("MEDIASTATION_UPDATE_IMAGE")) + image := s.setting(ctx, SystemUpdateImageSettingKey, os.Getenv("MMTL_UPDATE_IMAGE")) if image == "" { image = DefaultSystemUpdateImage } - watchtowerImage := s.setting(ctx, SystemUpdateWatchtowerImageSettingKey, os.Getenv("MEDIASTATION_UPDATE_WATCHTOWER_IMAGE")) + watchtowerImage := s.setting(ctx, SystemUpdateWatchtowerImageSettingKey, os.Getenv("MMTL_UPDATE_WATCHTOWER_IMAGE")) if watchtowerImage == "" { watchtowerImage = DefaultSystemUpdateWatchtowerImage } diff --git a/internal/service/system_update_command.go b/internal/service/system_update_command.go index 7720950..a27bafd 100644 --- a/internal/service/system_update_command.go +++ b/internal/service/system_update_command.go @@ -19,7 +19,7 @@ func (s *SystemUpdateService) updateCommand(ctx context.Context, status SystemUp } func (s *SystemUpdateService) rawUpdateCommand(ctx context.Context) string { - return s.setting(ctx, SystemUpdateCommandSettingKey, os.Getenv("MEDIASTATION_UPDATE_COMMAND")) + return s.setting(ctx, SystemUpdateCommandSettingKey, os.Getenv("MMTL_UPDATE_COMMAND")) } func defaultSystemUpdateCommand() string { @@ -33,7 +33,7 @@ func renderSystemUpdateCommand(template string, status SystemUpdateStatus) strin "{{compose_dir}}": shellQuote(status.ComposeDir), "{{compose_file}}": shellQuote(status.ComposeFile), "{{compose_command}}": firstNonEmpty(status.ComposeCommand, "docker compose"), - "{{container}}": shellQuote(firstNonEmpty(status.ContainerName, status.ContainerID, "mediastation-go")), + "{{container}}": shellQuote(firstNonEmpty(status.ContainerName, status.ContainerID, "mmtl")), "{{container_id}}": shellQuote(status.ContainerID), "{{container_name}}": shellQuote(status.ContainerName), } diff --git a/internal/service/system_update_compose.go b/internal/service/system_update_compose.go index 5849ee6..2172ba9 100644 --- a/internal/service/system_update_compose.go +++ b/internal/service/system_update_compose.go @@ -32,7 +32,7 @@ func (s *SystemUpdateService) resolveComposeTarget(ctx context.Context) (systemU } func (s *SystemUpdateService) composeTargetFromConfiguredDir(ctx context.Context) systemUpdateComposeTarget { - configured := s.setting(ctx, SystemUpdateComposeDirSettingKey, firstNonEmpty(os.Getenv("MEDIASTATION_UPDATE_COMPOSE_DIR"), os.Getenv("MEDIASTATION_UPDATE_WORKDIR"))) + configured := s.setting(ctx, SystemUpdateComposeDirSettingKey, firstNonEmpty(os.Getenv("MMTL_UPDATE_COMPOSE_DIR"), os.Getenv("MMTL_UPDATE_WORKDIR"))) return composeTargetInDir(configured) } @@ -143,7 +143,7 @@ func composeFileMatches(file string) bool { return false } content := strings.ToLower(string(raw)) - return strings.Contains(content, "mediastation-go") || strings.Contains(content, strings.ToLower(DefaultSystemUpdateImage)) + return strings.Contains(content, "mmtl") || strings.Contains(content, strings.ToLower(DefaultSystemUpdateImage)) } func preferredComposeCommand() string { diff --git a/internal/service/system_update_docker.go b/internal/service/system_update_docker.go index b904298..1fe9180 100644 --- a/internal/service/system_update_docker.go +++ b/internal/service/system_update_docker.go @@ -70,7 +70,7 @@ func (s *SystemUpdateService) check(ctx context.Context) SystemUpdateStatus { status.ContainerID = containerID if containerID == "" { if status.CanApply { - status.Message = "已识别 Docker Compose 安装目录;无法识别当前容器 ID,将使用默认容器名 mediastation-go 重启" + status.Message = "已识别 Docker Compose 安装目录;无法识别当前容器 ID,将使用默认容器名 mmtl 重启" } return status } diff --git a/internal/service/system_update_test.go b/internal/service/system_update_test.go index ddcf576..9bb8a2e 100644 --- a/internal/service/system_update_test.go +++ b/internal/service/system_update_test.go @@ -10,10 +10,10 @@ import ( func TestRenderSystemUpdateCommand(t *testing.T) { status := SystemUpdateStatus{ - Image: "ghcr.io/shukebta/mediastation-go:latest", + Image: "ghcr.io/shukebta/mmtl:latest", WatchtowerImage: "containrrr/watchtower:latest", ContainerID: "abc123def456", - ContainerName: "mediastation-go", + ContainerName: "mmtl", } got := renderSystemUpdateCommand( @@ -27,8 +27,8 @@ func TestRenderSystemUpdateCommand(t *testing.T) { } for _, want := range []string{ "containrrr/watchtower:latest", - "mediastation-go", - "ghcr.io/shukebta/mediastation-go:latest", + "mmtl", + "ghcr.io/shukebta/mmtl:latest", "abc123def456", } { if !strings.Contains(got, want) { @@ -39,17 +39,17 @@ func TestRenderSystemUpdateCommand(t *testing.T) { func TestDefaultSystemUpdateCommandUsesCompose(t *testing.T) { status := SystemUpdateStatus{ - ComposeDir: "/opt/mediastation-go", + ComposeDir: "/opt/mmtl", ComposeCommand: "docker compose", - ContainerName: "mediastation-go", + ContainerName: "mmtl", } got := renderSystemUpdateCommand(defaultSystemUpdateCommand(), status) for _, want := range []string{ - "cd " + shellQuote("/opt/mediastation-go"), + "cd " + shellQuote("/opt/mmtl"), "docker compose pull", "docker compose up -d", "docker image prune -f", - "docker restart " + shellQuote("mediastation-go"), + "docker restart " + shellQuote("mmtl"), } { if !strings.Contains(got, want) { t.Fatalf("default command %q does not contain %q", got, want) @@ -60,12 +60,12 @@ func TestDefaultSystemUpdateCommandUsesCompose(t *testing.T) { } } -func TestComposeTargetInDirMatchesMediaStationCompose(t *testing.T) { +func TestComposeTargetInDirMatchesMMTLCompose(t *testing.T) { dir := t.TempDir() if err := os.WriteFile(filepath.Join(dir, "docker-compose.yml"), []byte(` services: - mediastation-go: - image: ghcr.io/shukebta/mediastation-go:latest + mmtl: + image: ghcr.io/shukebta/mmtl:latest `), 0o600); err != nil { t.Fatal(err) } @@ -90,8 +90,8 @@ services: } func TestParseContainerInspectLine(t *testing.T) { - name, imageID := parseContainerInspectLine("/mediastation-go|sha256:abc") - if name != "mediastation-go" || imageID != "sha256:abc" { + name, imageID := parseContainerInspectLine("/mmtl|sha256:abc") + if name != "mmtl" || imageID != "sha256:abc" { t.Fatalf("parse inspect line = %q %q", name, imageID) } @@ -155,11 +155,11 @@ func TestSystemUpdateOutputDetailsKeepsTail(t *testing.T) { } func TestSystemUpdateStatusIncludesCurrentVersion(t *testing.T) { - svc := NewSystemUpdateService(nil, nil, nil, nil, "MediaStationGo-v0.0.99") + svc := NewSystemUpdateService(nil, nil, nil, nil, "MMTL-v0.0.99") status := svc.Status(context.Background()) - if status.CurrentVersion != "MediaStationGo-v0.0.99" { - t.Fatalf("current_version = %q, want MediaStationGo-v0.0.99", status.CurrentVersion) + if status.CurrentVersion != "MMTL-v0.0.99" { + t.Fatalf("current_version = %q, want MMTL-v0.0.99", status.CurrentVersion) } } diff --git a/internal/service/thetvdb.go b/internal/service/thetvdb.go index 40d2be2..c3a74cd 100644 --- a/internal/service/thetvdb.go +++ b/internal/service/thetvdb.go @@ -24,7 +24,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) // TheTVDBProvider talks to https://api4.thetvdb.com/v4. diff --git a/internal/service/tmdb.go b/internal/service/tmdb.go index 9d3852e..e75368c 100644 --- a/internal/service/tmdb.go +++ b/internal/service/tmdb.go @@ -24,7 +24,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) // TMDbProvider talks to https://api.themoviedb.org/3. diff --git a/internal/service/tmdb_chinese_title_test.go b/internal/service/tmdb_chinese_title_test.go index fb2ea12..8ac91a0 100644 --- a/internal/service/tmdb_chinese_title_test.go +++ b/internal/service/tmdb_chinese_title_test.go @@ -9,7 +9,7 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) func TestApplyTMDbChineseTitlePrefersMainlandAlternative(t *testing.T) { diff --git a/internal/service/token_svc.go b/internal/service/token_svc.go index 5a6be94..9b3ceb1 100644 --- a/internal/service/token_svc.go +++ b/internal/service/token_svc.go @@ -12,9 +12,9 @@ import ( "github.com/golang-jwt/jwt/v5" "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) const ( @@ -150,7 +150,7 @@ func (s *TokenService) issueAccessToken(userID, role, tier string) (string, erro RegisteredClaims: jwt.RegisteredClaims{ IssuedAt: jwt.NewNumericDate(time.Now()), ExpiresAt: jwt.NewNumericDate(time.Now().Add(AccessTokenDuration)), - Issuer: "mediastationgo", + Issuer: "mmtl", Subject: userID, }, } diff --git a/internal/service/token_svc_pending.go b/internal/service/token_svc_pending.go index 9ab296a..2ca62aa 100644 --- a/internal/service/token_svc_pending.go +++ b/internal/service/token_svc_pending.go @@ -7,8 +7,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) const loginRefreshTokenStoreTimeout = 750 * time.Millisecond diff --git a/internal/service/token_svc_pending_test.go b/internal/service/token_svc_pending_test.go index d79653b..6668f4e 100644 --- a/internal/service/token_svc_pending_test.go +++ b/internal/service/token_svc_pending_test.go @@ -6,9 +6,9 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func newTokenTestRepo(t *testing.T) *repository.Container { diff --git a/internal/service/transcoder.go b/internal/service/transcoder.go index 1f29974..ec4069b 100644 --- a/internal/service/transcoder.go +++ b/internal/service/transcoder.go @@ -32,8 +32,8 @@ import ( "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/config" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/config" + "github.com/ShukeBta/MMTL/internal/repository" ) // TranscoderService orchestrates background ffmpeg transcodes. diff --git a/internal/service/transcoder_ffmpeg_args.go b/internal/service/transcoder_ffmpeg_args.go index 30bb026..1ffb629 100644 --- a/internal/service/transcoder_ffmpeg_args.go +++ b/internal/service/transcoder_ffmpeg_args.go @@ -4,7 +4,7 @@ import ( "fmt" "strconv" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) type ffmpegArgSettings struct { diff --git a/internal/service/transcoder_test.go b/internal/service/transcoder_test.go index a7ccb49..f201df4 100644 --- a/internal/service/transcoder_test.go +++ b/internal/service/transcoder_test.go @@ -4,7 +4,7 @@ import ( "strings" "testing" - "github.com/ShukeBta/MediaStationGo/internal/config" + "github.com/ShukeBta/MMTL/internal/config" ) func TestBuildFFmpegArgs(t *testing.T) { diff --git a/internal/service/visibility.go b/internal/service/visibility.go index b805cae..3a9bccf 100644 --- a/internal/service/visibility.go +++ b/internal/service/visibility.go @@ -5,8 +5,8 @@ import ( "encoding/json" "strings" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) const AdultLibraryIDsSettingKey = "adult.library_ids" diff --git a/internal/service/watcher.go b/internal/service/watcher.go index 47cc4cd..b49bc38 100644 --- a/internal/service/watcher.go +++ b/internal/service/watcher.go @@ -22,8 +22,8 @@ import ( "github.com/fsnotify/fsnotify" "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) // pendingEvent records the most recent change to a path and the library it diff --git a/internal/service/watcher_test.go b/internal/service/watcher_test.go index 46000e1..abc7cbb 100644 --- a/internal/service/watcher_test.go +++ b/internal/service/watcher_test.go @@ -8,8 +8,8 @@ import ( "github.com/fsnotify/fsnotify" "go.uber.org/zap" - "github.com/ShukeBta/MediaStationGo/internal/model" - "github.com/ShukeBta/MediaStationGo/internal/repository" + "github.com/ShukeBta/MMTL/internal/model" + "github.com/ShukeBta/MMTL/internal/repository" ) func TestWatcherRefreshMapsHostLibraryPathToContainerPath(t *testing.T) { @@ -20,8 +20,8 @@ func TestWatcherRefreshMapsHostLibraryPathToContainerPath(t *testing.T) { if err := os.MkdirAll(containerLibrary, 0o755); err != nil { t.Fatalf("mkdir container library: %v", err) } - t.Setenv("MEDIASTATION_MEDIA_DIR", hostMedia) - t.Setenv("MEDIASTATION_MEDIA_CONTAINER_DIR", containerMedia) + t.Setenv("MMTL_MEDIA_DIR", hostMedia) + t.Setenv("MMTL_MEDIA_CONTAINER_DIR", containerMedia) db := newServiceTestDB(t, &model.Library{}) repos := repository.New(db) diff --git a/web/public/artwork-cache-sw.js b/web/public/artwork-cache-sw.js index 591691e..fef4a5c 100644 --- a/web/public/artwork-cache-sw.js +++ b/web/public/artwork-cache-sw.js @@ -1,4 +1,4 @@ -const ARTWORK_CACHE_PREFIX = 'mediastationgo-artwork-' +const ARTWORK_CACHE_PREFIX = 'mmtl-artwork-' const ARTWORK_CACHE = `${ARTWORK_CACHE_PREFIX}v2` const MIN_CACHEABLE_ARTWORK_BYTES = 128 const STRIP_QUERY_KEYS = ['token', 'profile_id', 'profile_pin_token'] diff --git a/web/src/api/playback.ts b/web/src/api/playback.ts index 90b364d..f925314 100644 --- a/web/src/api/playback.ts +++ b/web/src/api/playback.ts @@ -29,7 +29,7 @@ export interface ExternalPlayer { function publicOriginHeader() { if (typeof window === 'undefined' || !window.location?.origin) return undefined - return { 'X-MediaStation-Public-Origin': window.location.origin } + return { 'X-MMTL-Public-Origin': window.location.origin } } export const playbackAPI = { diff --git a/web/src/components/useThemeMode.ts b/web/src/components/useThemeMode.ts index 736ed8b..816e372 100644 --- a/web/src/components/useThemeMode.ts +++ b/web/src/components/useThemeMode.ts @@ -3,12 +3,13 @@ import { useCallback, useEffect, useState } from 'react' export type ThemeMode = 'light' | 'dark' | 'system' export type ResolvedTheme = 'light' | 'dark' -const THEME_STORAGE_KEY = 'mediastationgo.theme' +const THEME_STORAGE_KEY = 'mmtl.theme' +const THEME_LEGACY_STORAGE_KEY = 'mediastationgo.theme' const DARK_QUERY = '(prefers-color-scheme: dark)' function readStoredTheme(): ThemeMode { if (typeof window === 'undefined') return 'system' - const value = window.localStorage.getItem(THEME_STORAGE_KEY) + const value = window.localStorage.getItem(THEME_STORAGE_KEY) || window.localStorage.getItem(THEME_LEGACY_STORAGE_KEY) return value === 'light' || value === 'dark' || value === 'system' ? value : 'system' } diff --git a/web/src/stores/auth.ts b/web/src/stores/auth.ts index ba8a5d4..d92a1a2 100644 --- a/web/src/stores/auth.ts +++ b/web/src/stores/auth.ts @@ -56,7 +56,7 @@ export const useAuthStore = create()( }, }), { - name: 'mediastationgo-auth', + name: 'mmtl-auth', partialize: (state) => ({ token: state.token, refreshToken: state.refreshToken, diff --git a/web/src/stores/playProfile.ts b/web/src/stores/playProfile.ts index 1bc6f77..71adffd 100644 --- a/web/src/stores/playProfile.ts +++ b/web/src/stores/playProfile.ts @@ -22,7 +22,7 @@ export const usePlayProfileStore = create()( })), }), { - name: 'mediastationgo-play-profile', + name: 'mmtl-play-profile', storage: createJSONStorage(() => sessionStorage), }, ),