From 43047ec499b77de456fbc52d6948400b8d434354 Mon Sep 17 00:00:00 2001 From: safe Date: Fri, 16 Jan 2026 22:53:04 +0100 Subject: [PATCH] Initial commit --- .env.example | 11 + .gitignore | 3 + Makefile | 23 + app/CApp.php | 307 ++ app/Container.php | 44 + app/bootstrap.php | 133 + app/controllers/BaseController.php | 42 + app/controllers/account.php | 265 ++ app/controllers/admin.php | 106 + app/controllers/auth.php | 236 ++ app/controllers/debug.php | 214 + app/controllers/events.php | 353 ++ app/controllers/items.php | 112 + app/controllers/jobs.php | 167 + app/controllers/layout.php | 34 + app/controllers/logs.php | 72 + app/controllers/media.php | 166 + app/controllers/metadata.php | 89 + app/controllers/pages.php | 170 + app/controllers/scan_profiles.php | 76 + app/controllers/settings.php | 130 + app/controllers/sources.php | 216 + app/controllers/tasks.php | 158 + app/controllers/tools.php | 37 + app/db/Db.php | 74 + app/db/SchemaTool.php | 355 ++ app/http/Response.php | 58 + app/http/Router.php | 89 + app/http/helpers.php | 225 ++ app/services/AuthService.php | 1145 ++++++ app/services/ExportService.php | 55 + app/services/HttpClient.php | 69 + app/services/JobsService.php | 166 + app/services/LayoutService.php | 227 ++ app/services/LogService.php | 184 + app/services/MediaApplyService.php | 194 + app/services/MediaLibraryService.php | 751 ++++ app/services/MetadataService.php | 372 ++ app/services/MkvToolnixService.php | 274 ++ app/services/PathTool.php | 85 + app/services/ScanProfilesService.php | 158 + app/services/ScannerService.php | 524 +++ app/services/SettingsService.php | 177 + app/services/ShellTool.php | 28 + app/services/SourcesService.php | 163 + app/services/TransmissionService.php | 228 ++ app/services/export/ExporterInterface.php | 14 + app/services/export/JellyfinExporter.php | 57 + app/services/export/KodiExporter.php | 57 + app/services/metadata/MetadataProvider.php | 14 + app/services/metadata/OmdbProvider.php | 101 + app/services/metadata/TvdbProvider.php | 127 + app/views/pages/account.php | 119 + app/views/pages/index.php | 159 + app/views/pages/login.php | 83 + app/views/pages/settings.php | 786 ++++ app/views/partials/header.php | 119 + app/views/partials/table.php | 68 + cli/scan.php | 31 + cli/worker.php | 81 + config/config.php | 86 + docker-compose.yml | 98 + docker/nginx/default.conf | 42 + docker/php/Dockerfile | 40 + docker/php/conf/events.conf | 10 + docker/scripts/entrypoint.sh | 48 + docker/scripts/init-db.sh | 100 + docker/scripts/wait-for-db.sh | 17 + .../assets/assets/branding/scmedia/CODEX.md | 38 + .../assets/assets/branding/scmedia/README.md | 31 + .../scmedia/icons/icon_grid_on_dark.png | Bin 0 -> 298405 bytes .../scmedia/logo/app_icon_square_128.png | Bin 0 -> 8301 bytes .../scmedia/logo/app_icon_square_256.png | Bin 0 -> 22572 bytes .../scmedia/logo/app_icon_square_512.png | Bin 0 -> 57410 bytes .../scmedia/logo/app_icon_square_64.png | Bin 0 -> 3384 bytes .../scmedia/logo/logo_horizontal_on_dark.png | Bin 0 -> 125958 bytes .../branding/scmedia/logo/logo_on_dark.png | Bin 0 -> 105510 bytes .../assets/branding/scmedia/manifest.json | 78 + .../scmedia/ui/ui_preview_on_dark.png | Bin 0 -> 351724 bytes public/assets/css/account.css | 41 + public/assets/css/admin.css | 54 + public/assets/css/auth.css | 96 + public/assets/css/common.css | 599 +++ public/assets/css/settings.css | 481 +++ public/assets/css/style.css | 419 ++ public/assets/i18n/de.json | 543 +++ public/assets/i18n/en.json | 543 +++ public/assets/i18n/ru.json | 545 +++ public/assets/icons/scmedia.png | Bin 0 -> 3384 bytes public/assets/js/account.js | 161 + public/assets/js/admin.js | 157 + public/assets/js/api.js | 86 + public/assets/js/app-config.js | 1 + public/assets/js/app.js | 1743 ++++++++ public/assets/js/auth.js | 217 + public/assets/js/http.js | 12 + public/assets/js/login.js | 211 + public/assets/js/prefs.js | 80 + public/assets/js/settings.js | 3510 +++++++++++++++++ public/assets/js/sse.js | 209 + public/assets/js/table.js | 835 ++++ public/assets/js/ui.js | 343 ++ public/index.php | 10 + readme.md | 19 + sql/schema.sql | 461 +++ 105 files changed, 22545 insertions(+) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 app/CApp.php create mode 100644 app/Container.php create mode 100644 app/bootstrap.php create mode 100644 app/controllers/BaseController.php create mode 100644 app/controllers/account.php create mode 100644 app/controllers/admin.php create mode 100644 app/controllers/auth.php create mode 100644 app/controllers/debug.php create mode 100644 app/controllers/events.php create mode 100644 app/controllers/items.php create mode 100644 app/controllers/jobs.php create mode 100644 app/controllers/layout.php create mode 100644 app/controllers/logs.php create mode 100644 app/controllers/media.php create mode 100644 app/controllers/metadata.php create mode 100644 app/controllers/pages.php create mode 100644 app/controllers/scan_profiles.php create mode 100644 app/controllers/settings.php create mode 100644 app/controllers/sources.php create mode 100644 app/controllers/tasks.php create mode 100644 app/controllers/tools.php create mode 100644 app/db/Db.php create mode 100644 app/db/SchemaTool.php create mode 100644 app/http/Response.php create mode 100644 app/http/Router.php create mode 100644 app/http/helpers.php create mode 100644 app/services/AuthService.php create mode 100644 app/services/ExportService.php create mode 100644 app/services/HttpClient.php create mode 100644 app/services/JobsService.php create mode 100644 app/services/LayoutService.php create mode 100644 app/services/LogService.php create mode 100644 app/services/MediaApplyService.php create mode 100644 app/services/MediaLibraryService.php create mode 100644 app/services/MetadataService.php create mode 100644 app/services/MkvToolnixService.php create mode 100644 app/services/PathTool.php create mode 100644 app/services/ScanProfilesService.php create mode 100644 app/services/ScannerService.php create mode 100644 app/services/SettingsService.php create mode 100644 app/services/ShellTool.php create mode 100644 app/services/SourcesService.php create mode 100644 app/services/TransmissionService.php create mode 100644 app/services/export/ExporterInterface.php create mode 100644 app/services/export/JellyfinExporter.php create mode 100644 app/services/export/KodiExporter.php create mode 100644 app/services/metadata/MetadataProvider.php create mode 100644 app/services/metadata/OmdbProvider.php create mode 100644 app/services/metadata/TvdbProvider.php create mode 100644 app/views/pages/account.php create mode 100644 app/views/pages/index.php create mode 100644 app/views/pages/login.php create mode 100644 app/views/pages/settings.php create mode 100644 app/views/partials/header.php create mode 100644 app/views/partials/table.php create mode 100644 cli/scan.php create mode 100644 cli/worker.php create mode 100644 config/config.php create mode 100644 docker-compose.yml create mode 100644 docker/nginx/default.conf create mode 100644 docker/php/Dockerfile create mode 100644 docker/php/conf/events.conf create mode 100644 docker/scripts/entrypoint.sh create mode 100644 docker/scripts/init-db.sh create mode 100644 docker/scripts/wait-for-db.sh create mode 100644 public/assets/assets/branding/scmedia/CODEX.md create mode 100644 public/assets/assets/branding/scmedia/README.md create mode 100644 public/assets/assets/branding/scmedia/icons/icon_grid_on_dark.png create mode 100644 public/assets/assets/branding/scmedia/logo/app_icon_square_128.png create mode 100644 public/assets/assets/branding/scmedia/logo/app_icon_square_256.png create mode 100644 public/assets/assets/branding/scmedia/logo/app_icon_square_512.png create mode 100644 public/assets/assets/branding/scmedia/logo/app_icon_square_64.png create mode 100644 public/assets/assets/branding/scmedia/logo/logo_horizontal_on_dark.png create mode 100644 public/assets/assets/branding/scmedia/logo/logo_on_dark.png create mode 100644 public/assets/assets/branding/scmedia/manifest.json create mode 100644 public/assets/assets/branding/scmedia/ui/ui_preview_on_dark.png create mode 100644 public/assets/css/account.css create mode 100644 public/assets/css/admin.css create mode 100644 public/assets/css/auth.css create mode 100644 public/assets/css/common.css create mode 100644 public/assets/css/settings.css create mode 100644 public/assets/css/style.css create mode 100644 public/assets/i18n/de.json create mode 100644 public/assets/i18n/en.json create mode 100644 public/assets/i18n/ru.json create mode 100644 public/assets/icons/scmedia.png create mode 100644 public/assets/js/account.js create mode 100644 public/assets/js/admin.js create mode 100644 public/assets/js/api.js create mode 100644 public/assets/js/app-config.js create mode 100644 public/assets/js/app.js create mode 100644 public/assets/js/auth.js create mode 100644 public/assets/js/http.js create mode 100644 public/assets/js/login.js create mode 100644 public/assets/js/prefs.js create mode 100644 public/assets/js/settings.js create mode 100644 public/assets/js/sse.js create mode 100644 public/assets/js/table.js create mode 100644 public/assets/js/ui.js create mode 100644 public/index.php create mode 100644 readme.md create mode 100644 sql/schema.sql diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..2b5627d --- /dev/null +++ b/.env.example @@ -0,0 +1,11 @@ +APP_ENV=production +APP_ID=CHANGE_ME_UUID +DEBUG=false + +DB_HOST=db +DB_PORT=3306 +DB_NAME=scmedia +DB_USER=scmedia +DB_PASS=changeme + +JWT_SECRET=CHANGE_ME_LONG_RANDOM diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2cef73e --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.env +.env.* +!.env.example diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ada3731 --- /dev/null +++ b/Makefile @@ -0,0 +1,23 @@ +.PHONY: up down build logs init shell worker + +up: + docker compose up -d + +down: + docker compose down + +build: + docker compose build --no-cache + +logs: + docker compose logs -f --tail=200 + +init: + docker compose up -d db + docker compose run --rm php bash /var/www/docker/scripts/init-db.sh + +shell: + docker compose exec php sh + +worker: + docker compose logs -f --tail=200 worker diff --git a/app/CApp.php b/app/CApp.php new file mode 100644 index 0000000..cf9ce9a --- /dev/null +++ b/app/CApp.php @@ -0,0 +1,307 @@ +loadEnv(__DIR__ . '/../.env'); + $this->registerErrorHandlers(); + + require_once __DIR__ . '/http/helpers.php'; + require_once __DIR__ . '/http/Router.php'; + require_once __DIR__ . '/http/Response.php'; + require_once __DIR__ . '/Container.php'; + require_once __DIR__ . '/controllers/BaseController.php'; + + $this->router = new Router(); + + $method = $_SERVER['REQUEST_METHOD'] ?? 'GET'; + $uri = $_SERVER['REQUEST_URI'] ?? '/'; + $path = parse_url($uri, PHP_URL_PATH) ?: '/'; + + try { + $services = require __DIR__ . '/bootstrap.php'; + } catch (Throwable $e) { + $this->writeErrorResponse($e, $this->isDebugEnabled(), str_starts_with($path, '/api/')); + exit; + } + + $this->container = new Container($services); + $this->registerControllers(); + + $path = $this->handleLanguageRouting($path); + $this->authorizeRequest($path); + + $this->router->dispatch($method, $path); + } + + private function registerControllers(): void { + require_once __DIR__ . '/controllers/pages.php'; + require_once __DIR__ . '/controllers/settings.php'; + require_once __DIR__ . '/controllers/scan_profiles.php'; + require_once __DIR__ . '/controllers/tools.php'; + require_once __DIR__ . '/controllers/layout.php'; + require_once __DIR__ . '/controllers/debug.php'; + require_once __DIR__ . '/controllers/media.php'; + require_once __DIR__ . '/controllers/logs.php'; + require_once __DIR__ . '/controllers/metadata.php'; + require_once __DIR__ . '/controllers/sources.php'; + require_once __DIR__ . '/controllers/events.php'; + require_once __DIR__ . '/controllers/tasks.php'; + require_once __DIR__ . '/controllers/auth.php'; + require_once __DIR__ . '/controllers/admin.php'; + require_once __DIR__ . '/controllers/account.php'; + require_once __DIR__ . '/controllers/items.php'; + require_once __DIR__ . '/controllers/jobs.php'; + + $router = $this->router; + $container = $this->container; + PagesController::register($router, $container); + SettingsController::register($router, $container); + ScanProfilesController::register($router, $container); + ToolsController::register($router, $container); + LayoutController::register($router, $container); + DebugController::register($router, $container); + MediaController::register($router, $container); + LogsController::register($router, $container); + MetadataController::register($router, $container); + SourcesController::register($router, $container); + EventsController::register($router, $container); + TasksController::register($router, $container); + AuthController::register($router, $container); + AdminController::register($router, $container); + AccountController::register($router, $container); + ItemsController::register($router, $container); + JobsController::register($router, $container); + } + + private function authorizeRequest(string $path): void { + $services = $this->container->all(); + if (str_starts_with($path, '/api/')) { + $publicApi = [ + '/api/auth/register', + '/api/auth/login', + '/api/auth/2fa/verify', + '/api/auth/refresh', + '/api/auth/logout', + '/api/auth/password/forgot', + '/api/auth/password/reset', + '/api/language', + '/api/events', + ]; + if (!in_array($path, $publicApi, true)) { + $requiredRole = str_starts_with($path, '/api/admin/') ? 'admin' : null; + /** @var \ScMedia\Services\AuthService $auth */ + $auth = $services['auth']; + $this->container->set('auth_user', $auth->requireAuth($requiredRole)); + } + return; + } + + header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0'); + header('Pragma: no-cache'); + header('Expires: 0'); + if ($path !== '/login') { + /** @var \ScMedia\Services\AuthService $auth */ + $auth = $services['auth']; + $this->container->set('auth_user', $auth->requirePageAuth()); + } + } + + private function handleLanguageRouting(string $path): string { + if (str_starts_with($path, '/api/')) { + return $path; + } + + $supportedLangs = ['en', 'ru', 'de']; + if ($path === '/lang') { + $lang = isset($_GET['lang']) ? strtolower((string)$_GET['lang']) : 'en'; + if (!in_array($lang, $supportedLangs, true)) { + $lang = 'en'; + } + $next = isset($_GET['next']) ? (string)$_GET['next'] : '/'; + if ($next === '' || $next[0] !== '/' || str_contains($next, '..')) { + $next = '/'; + } + $target = '/' . $lang . ($next === '/' ? '' : $next); + setcookie('scmedia_lang', $lang, [ + 'expires' => time() + 31536000, + 'path' => '/', + 'samesite' => 'Lax', + ]); + header('Location: ' . $target, true, 302); + exit; + } + + $first = explode('/', trim($path, '/'))[0] ?? ''; + $hasPrefix = in_array($first, $supportedLangs, true); + if ($hasPrefix) { + setcookie('scmedia_lang', $first, [ + 'expires' => time() + 31536000, + 'path' => '/', + 'samesite' => 'Lax', + ]); + $_COOKIE['scmedia_lang'] = $first; + $path = '/' . ltrim(substr($path, strlen($first) + 1), '/'); + if ($path === '/') { + $path = '/'; + } + return $path; + } + + if (!str_starts_with($path, '/assets') && $path !== '/favicon.ico') { + $lang = isset($_COOKIE['scmedia_lang']) ? (string)$_COOKIE['scmedia_lang'] : ''; + $token = (string)($_COOKIE['access_token'] ?? ''); + if ($lang === '' && $token !== '' && isset($this->container->all()['auth'])) { + /** @var \ScMedia\Services\AuthService $auth */ + $auth = $this->container->all()['auth']; + $lang = $auth->resolveUserLanguageFromToken($token); + } + if ($lang === '' || $lang === null) { + $lang = $this->pickLangFromHeader((string)($_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? ''), $supportedLangs); + } + if ($lang === '') $lang = 'en'; + $target = '/' . $lang . $path; + header('Location: ' . $target, true, 302); + exit; + } + + return $path; + } + + private function pickLangFromHeader(string $header, array $supported): string { + $header = strtolower($header); + $parts = array_map('trim', explode(',', $header)); + foreach ($parts as $part) { + if ($part === '') continue; + $lang = explode(';', $part)[0] ?? ''; + $lang = substr($lang, 0, 2); + if (in_array($lang, $supported, true)) return $lang; + } + return 'en'; + } + + private function registerErrorHandlers(): void { + set_exception_handler(function (Throwable $e): void { + $uri = $_SERVER['REQUEST_URI'] ?? '/'; + $path = parse_url($uri, PHP_URL_PATH) ?: '/'; + $this->writeErrorResponse($e, $this->isDebugEnabled(), str_starts_with($path, '/api/')); + }); + set_error_handler(function (int $severity, string $message, string $file, int $line): bool { + throw new ErrorException($message, 0, $severity, $file, $line); + }); + register_shutdown_function(function (): void { + $error = error_get_last(); + if ($error === null) { + return; + } + $fatal = [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR]; + if (!in_array($error['type'], $fatal, true)) { + return; + } + $exception = new ErrorException($error['message'] ?? 'Fatal error', 0, $error['type'], $error['file'] ?? '', (int)($error['line'] ?? 0)); + $uri = $_SERVER['REQUEST_URI'] ?? '/'; + $path = parse_url($uri, PHP_URL_PATH) ?: '/'; + $this->writeErrorResponse($exception, $this->isDebugEnabled(), str_starts_with($path, '/api/')); + }); + } + + private function isDebugEnabled(): bool { + $val = getenv('DEBUG'); + if ($val === false) { + return false; + } + $bool = filter_var($val, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); + return $bool ?? false; + } + + private function writeErrorResponse(?Throwable $e, bool $debug, bool $isApi): void { + static $sent = false; + if ($sent) { + return; + } + $sent = true; + if (headers_sent()) { + return; + } + $code = 500; + $title = 'Internal Server Error'; + $message = 'Something went wrong. Please try again later.'; + if ($e instanceof PDOException) { + $code = 503; + $title = 'Database Unavailable'; + $message = 'Database is not available. Please try again later.'; + } + @http_response_code($code); + if ($isApi) { + header('Content-Type: application/json; charset=utf-8'); + $payload = [ + 'ok' => false, + 'error' => [ + 'code' => 'SERVER_ERROR', + 'message' => $message, + ], + ]; + if ($debug && $e !== null) { + $payload['error']['details'] = [ + 'type' => get_class($e), + 'message' => $e->getMessage(), + 'trace' => $e->getTraceAsString(), + ]; + } + echo json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + return; + } + header('Content-Type: text/html; charset=utf-8'); + $details = ''; + if ($debug && $e !== null) { + $details = '
' . htmlspecialchars($e->getMessage() . "\n\n" . $e->getTraceAsString(), ENT_QUOTES) . '
'; + } + echo ''; + echo '' . htmlspecialchars($title, ENT_QUOTES) . ''; + echo '

' . htmlspecialchars($title, ENT_QUOTES) . '

'; + echo '

' . htmlspecialchars($message, ENT_QUOTES) . '

'; + echo $details; + echo ''; + } + + private function loadEnv(string $path): void { + if (!is_file($path)) { + return; + } + $lines = file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + if (!is_array($lines)) { + return; + } + foreach ($lines as $line) { + $line = trim($line); + if ($line === '' || str_starts_with($line, '#')) { + continue; + } + $parts = explode('=', $line, 2); + if (count($parts) !== 2) { + continue; + } + $key = trim($parts[0]); + if ($key === '' || getenv($key) !== false) { + continue; + } + $value = trim($parts[1]); + if ($value !== '' && ($value[0] === '"' || $value[0] === "'")) { + $quote = $value[0]; + if (str_ends_with($value, $quote)) { + $value = substr($value, 1, -1); + } + } + putenv("{$key}={$value}"); + $_ENV[$key] = $value; + $_SERVER[$key] = $value; + } + } +} diff --git a/app/Container.php b/app/Container.php new file mode 100644 index 0000000..2980114 --- /dev/null +++ b/app/Container.php @@ -0,0 +1,44 @@ +services = $services; + } + + public function get(string $key) { + return $this->services[$key] ?? null; + } + + public function set(string $key, $value): void { + $this->services[$key] = $value; + } + + public function all(): array { + return $this->services; + } + + public function db() { + return $this->get('db'); + } + + public function settings() { + return $this->get('settings'); + } + + public function auth() { + return $this->get('auth'); + } + + public function logger() { + return $this->get('logger'); + } + + public function config(): array { + return (array)($this->get('config') ?? []); + } +} diff --git a/app/bootstrap.php b/app/bootstrap.php new file mode 100644 index 0000000..df5d9d1 --- /dev/null +++ b/app/bootstrap.php @@ -0,0 +1,133 @@ + $db, + 'config' => $config, + 'schema' => new \ScMedia\Db\SchemaTool($db, __DIR__ . '/../sql/schema.sql'), + + 'settings' => $settings, + 'scan_profiles' => $scanProfiles, + 'layout' => new \ScMedia\Services\LayoutService($db, $config), + 'path_tool' => new \ScMedia\Services\PathTool(), + + 'jobs' => $jobs, + 'logger' => $logger, + 'shell' => $shell, + 'mkvtoolnix' => $mkvtoolnix, + 'media_library' => $mediaLibrary, + 'media_apply' => $mediaApply, + 'metadata' => $metadata, + 'export_service' => $exportService, + 'transmission' => $transmission, + 'sources' => $sources, + 'auth' => $auth, + 'scanner' => new \ScMedia\Services\ScannerService($db, $settings, $scanProfiles, $jobs, $mkvtoolnix, $mediaLibrary), +]; + +return $services; diff --git a/app/controllers/BaseController.php b/app/controllers/BaseController.php new file mode 100644 index 0000000..ceee4fd --- /dev/null +++ b/app/controllers/BaseController.php @@ -0,0 +1,42 @@ +container = $container; + } + + protected function services(): array { + return $this->container->all(); + } + + protected function db() { + return $this->container->db(); + } + + protected function settings() { + return $this->container->settings(); + } + + protected function auth() { + return $this->container->auth(); + } + + protected function logger() { + return $this->container->logger(); + } + + protected function config(): array { + return $this->container->config(); + } + + protected function json($payload, int $status = 200): void { + Response::json($payload, $status); + } +} diff --git a/app/controllers/account.php b/app/controllers/account.php new file mode 100644 index 0000000..d1ac2af --- /dev/null +++ b/app/controllers/account.php @@ -0,0 +1,265 @@ +add('GET', '/account', fn() => $self->page()); + $router->add('GET', '/api/account', fn() => $self->getAccount()); + $router->add('POST', '/api/account', fn() => $self->updateAccount()); + $router->add('POST', '/api/account/email', fn() => $self->updateEmail()); + $router->add('POST', '/api/account/password', fn() => $self->updatePassword()); + $router->add('POST', '/api/account/avatar', fn() => $self->uploadAvatar()); + $router->add('GET', '/api/account/avatar', fn() => $self->getAvatar()); + } + + private function page(): void { + $i18n = $this->loadI18n(['common', 'account']); + $this->renderView(__DIR__ . '/../views/pages/account.php', $i18n); + } + + private function getAccount(): void { + /** @var AuthService $auth */ + $auth = $this->auth(); + $user = $auth->requireAuth(); + $profile = self::getProfile($this->services(), (int)$user['id']); + Response::json(['ok' => true, 'data' => $profile]); + } + + private function updateAccount(): void { + /** @var AuthService $auth */ + $auth = $this->auth(); + $user = $auth->requireAuth(); + $body = read_json_body(); + $nickname = isset($body['nickname']) ? trim((string)$body['nickname']) : null; + $ui = is_array($body['ui'] ?? null) ? $body['ui'] : null; + self::updateProfile($this->services(), (int)$user['id'], $nickname, $ui); + Response::json(['ok' => true]); + } + + private function updateEmail(): void { + /** @var AuthService $auth */ + $auth = $this->auth(); + $user = $auth->requireAuth(); + $body = read_json_body(); + $email = (string)($body['email'] ?? ''); + $res = $auth->changeEmail((int)$user['id'], $email); + if (empty($res['ok'])) { + Response::json(['ok' => false, 'error' => ['code' => 'EMAIL_FAILED', 'message' => $res['error'] ?? 'failed']], 400); + return; + } + Response::json(['ok' => true]); + } + + private function updatePassword(): void { + /** @var AuthService $auth */ + $auth = $this->auth(); + $user = $auth->requireAuth(); + $body = read_json_body(); + $current = (string)($body['current'] ?? ''); + $next = (string)($body['next'] ?? ''); + $res = $auth->changePassword((int)$user['id'], $current, $next); + if (empty($res['ok'])) { + Response::json(['ok' => false, 'error' => ['code' => 'PASSWORD_FAILED', 'message' => $res['error'] ?? 'failed']], 400); + return; + } + Response::json(['ok' => true]); + } + + private function uploadAvatar(): void { + /** @var AuthService $auth */ + $auth = $this->auth(); + $user = $auth->requireAuth(); + if (!isset($_FILES['avatar'])) { + Response::json(['ok' => false, 'error' => ['code' => 'FILE_REQUIRED', 'message' => 'avatar required']], 400); + return; + } + $file = $_FILES['avatar']; + if (!is_array($file) || ($file['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) { + Response::json(['ok' => false, 'error' => ['code' => 'UPLOAD_FAILED', 'message' => 'upload failed']], 400); + return; + } + $size = (int)($file['size'] ?? 0); + if ($size <= 0 || $size > 5 * 1024 * 1024) { + Response::json(['ok' => false, 'error' => ['code' => 'FILE_TOO_LARGE', 'message' => 'max 5MB']], 400); + return; + } + $tmp = (string)($file['tmp_name'] ?? ''); + $mime = (string)($file['type'] ?? ''); + $data = $tmp !== '' ? file_get_contents($tmp) : false; + if ($data === false) { + Response::json(['ok' => false, 'error' => ['code' => 'READ_FAILED', 'message' => 'read failed']], 400); + return; + } + self::updateAvatar($this->services(), (int)$user['id'], $mime, $data); + Response::json(['ok' => true]); + } + + private function getAvatar(): void { + /** @var AuthService $auth */ + $auth = $this->auth(); + $user = $auth->requireAuth(); + $row = self::getAvatarRow($this->services(), (int)$user['id']); + if (!$row || empty($row['avatar_blob'])) { + http_response_code(404); + return; + } + $mime = (string)($row['avatar_mime'] ?? 'image/png'); + header('Content-Type: ' . $mime); + echo $row['avatar_blob']; + } + + private function loadI18n(array $packages = ['common']): array { + $settings = $this->settings(); + $all = $settings->getAll(); + $lang = (string)($all['general']['language'] ?? 'en'); + $cookieLang = isset($_COOKIE['scmedia_lang']) ? (string)$_COOKIE['scmedia_lang'] : ''; + if (preg_match('/^[a-z]{2}$/', $cookieLang)) { + $lang = $cookieLang; + } + + $dict = $this->readI18nDict($lang); + if ($lang !== 'en' && count($dict) === 0) { + $lang = 'en'; + $dict = $this->readI18nDict($lang); + } + + $dict = $this->filterI18nPackages($dict, $packages); + $t = function(string $key, string $fallback = '') use ($dict): string { + $val = $dict[$key] ?? ''; + return $val !== '' ? $val : ($fallback !== '' ? $fallback : $key); + }; + + return [ + 'lang' => $lang, + 'dict' => $dict, + 't' => $t, + 'debugToolsEnabled' => (bool)($this->config()['app']['debug_tools_enabled'] ?? false), + ]; + } + + private function renderView(string $path, array $vars = []): void { + if (!is_file($path)) { + Response::json(['ok' => false, 'error' => 'View not found'], 404); + return; + } + extract($vars, EXTR_SKIP); + ob_start(); + require $path; + $html = ob_get_clean(); + Response::html($html); + } + + private function readI18nDict(string $lang): array { + $path = __DIR__ . '/../../public/assets/i18n/' . basename($lang) . '.json'; + if (!is_file($path)) return []; + $raw = file_get_contents($path); + if ($raw === false) return []; + $data = json_decode($raw, true); + return is_array($data) ? $data : []; + } + + private function i18nPackages(): array { + return [ + 'common' => [ + 'prefixes' => ['common', 'nav', 'queue', 'job'], + 'keys' => ['auth.logout', 'actions.theme', 'settings.language'], + ], + 'account' => [ + 'prefixes' => ['account', 'theme', 'settings.ui'], + 'keys' => ['settings.language'], + ], + ]; + } + + private function filterI18nPackages(array $dict, array $packages): array { + $map = $this->i18nPackages(); + $out = []; + $wanted = []; + foreach ($packages as $p) { + if (isset($map[$p])) { + $wanted[] = $map[$p]; + } + } + foreach ($wanted as $pkg) { + foreach (($pkg['prefixes'] ?? []) as $prefix) { + foreach ($dict as $k => $v) { + if (str_starts_with($k, $prefix . '.')) { + $out[$k] = $v; + } + } + } + foreach (($pkg['keys'] ?? []) as $key) { + if (array_key_exists($key, $dict)) { + $out[$key] = $dict[$key]; + } + } + } + return $out; + } + + private static function getProfile(array $services, int $userId): array { + $db = $services['db']; + self::ensureProfile($db, $userId); + $user = $db->fetchOne("SELECT email FROM users WHERE id = :id", [':id' => $userId]) ?? []; + $row = $db->fetchOne("SELECT nickname, ui_prefs_json, avatar_blob FROM user_profiles WHERE user_id = :id", [':id' => $userId]) ?? []; + $ui = json_decode((string)($row['ui_prefs_json'] ?? '{}'), true); + return [ + 'profile' => [ + 'email' => (string)($user['email'] ?? ''), + 'nickname' => (string)($row['nickname'] ?? ''), + 'avatar_present' => !empty($row['avatar_blob']), + ], + 'ui' => is_array($ui) ? $ui : [], + ]; + } + + private static function updateProfile(array $services, int $userId, ?string $nickname, ?array $ui): void { + $db = $services['db']; + self::ensureProfile($db, $userId); + if ($nickname !== null) { + $db->exec("UPDATE user_profiles SET nickname = :n, updated_at = NOW() WHERE user_id = :id", [ + ':n' => $nickname, + ':id' => $userId, + ]); + } + if ($ui !== null) { + $row = $db->fetchOne("SELECT ui_prefs_json FROM user_profiles WHERE user_id = :id", [':id' => $userId]) ?? []; + $current = json_decode((string)($row['ui_prefs_json'] ?? '{}'), true); + $current = is_array($current) ? $current : []; + $merged = array_replace_recursive($current, $ui); + $db->exec("UPDATE user_profiles SET ui_prefs_json = :j, updated_at = NOW() WHERE user_id = :id", [ + ':j' => json_encode($merged, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), + ':id' => $userId, + ]); + } + } + + private static function updateAvatar(array $services, int $userId, string $mime, string $data): void { + $db = $services['db']; + self::ensureProfile($db, $userId); + $db->exec("UPDATE user_profiles SET avatar_blob = :b, avatar_mime = :m, updated_at = NOW() WHERE user_id = :id", [ + ':b' => $data, + ':m' => $mime, + ':id' => $userId, + ]); + } + + private static function getAvatarRow(array $services, int $userId): ?array { + $db = $services['db']; + self::ensureProfile($db, $userId); + return $db->fetchOne("SELECT avatar_blob, avatar_mime FROM user_profiles WHERE user_id = :id", [':id' => $userId]); + } + + private static function ensureProfile($db, int $userId): void { + $db->exec("INSERT IGNORE INTO user_profiles (user_id, created_at, updated_at) VALUES (:id, NOW(), NOW())", [ + ':id' => $userId, + ]); + } +} diff --git a/app/controllers/admin.php b/app/controllers/admin.php new file mode 100644 index 0000000..b1aa82f --- /dev/null +++ b/app/controllers/admin.php @@ -0,0 +1,106 @@ +add('GET', '/api/admin/users', fn() => $self->listUsers()); + $router->add('POST', '/api/admin/users/{id}/roles', fn($params) => $self->setRoles($params)); + $router->add('POST', '/api/admin/users/{id}/disable', fn($params) => $self->disableUser($params)); + $router->add('POST', '/api/admin/users/{id}/reset-2fa', fn($params) => $self->resetMfa($params)); + $router->add('GET', '/api/admin/roles', fn() => $self->listRoles()); + $router->add('POST', '/api/admin/audit', fn() => $self->audit()); + } + + private function listUsers(): void { + /** @var AuthService $auth */ + $auth = $this->auth(); + $auth->requireAuth('admin'); + $items = $auth->listUsers(); + Response::json(['ok' => true, 'data' => ['items' => $items]]); + } + + private function setRoles(array $params): void { + /** @var AuthService $auth */ + $auth = $this->auth(); + $actor = $auth->requireAuth('admin'); + $userId = (int)($params['id'] ?? 0); + $body = read_json_body(); + $roles = is_array($body['roles'] ?? null) ? $body['roles'] : []; + $res = $auth->setUserRoles((int)($actor['id'] ?? 0), $userId, $roles); + if (empty($res['ok'])) { + Response::json(['ok' => false, 'error' => ['code' => 'ROLES_FAILED', 'message' => $res['error'] ?? 'failed']], 400); + return; + } + Response::json(['ok' => true]); + } + + private function disableUser(array $params): void { + /** @var AuthService $auth */ + $auth = $this->auth(); + $actor = $auth->requireAuth('admin'); + $userId = (int)($params['id'] ?? 0); + $body = read_json_body(); + $disabled = (bool)($body['disabled'] ?? true); + $res = $auth->disableUser((int)($actor['id'] ?? 0), $userId, $disabled); + if (empty($res['ok'])) { + Response::json(['ok' => false, 'error' => ['code' => 'USER_DISABLE_FAILED', 'message' => $res['error'] ?? 'failed']], 400); + return; + } + Response::json(['ok' => true]); + } + + private function resetMfa(array $params): void { + /** @var AuthService $auth */ + $auth = $this->auth(); + $actor = $auth->requireAuth('admin'); + $userId = (int)($params['id'] ?? 0); + $res = $auth->resetUserMfa((int)($actor['id'] ?? 0), $userId); + if (empty($res['ok'])) { + Response::json(['ok' => false, 'error' => ['code' => 'MFA_RESET_FAILED', 'message' => $res['error'] ?? 'failed']], 400); + return; + } + Response::json(['ok' => true]); + } + + private function listRoles(): void { + /** @var AuthService $auth */ + $auth = $this->auth(); + $auth->requireAuth('admin'); + $items = $auth->listRoles(); + Response::json(['ok' => true, 'data' => ['items' => $items]]); + } + + private function audit(): void { + /** @var AuthService $auth */ + $auth = $this->auth(); + $auth->requireAuth('admin'); + [$page, $perPage, $sort, $dir, $filters, $params] = table_body_params(50, 200); + $from = ''; + $to = ''; + $action = ''; + $rangeValue = filter_value($filters, 'created_at'); + $rangeOp = filter_op($filters, 'created_at'); + if ($rangeOp === 'between' && is_array($rangeValue)) { + $from = (string)($rangeValue[0] ?? ''); + $to = (string)($rangeValue[1] ?? ''); + } + $actionValue = filter_value($filters, 'action'); + if (is_string($actionValue)) { + $action = $actionValue; + } + $res = $auth->listAuditFiltered($page, $perPage, $from, $to, $action); + Response::json(['ok' => true, 'data' => [ + 'items' => $res['items'], + 'total' => $res['total'], + 'page' => $page, + 'per_page' => $perPage, + ]]); + } +} diff --git a/app/controllers/auth.php b/app/controllers/auth.php new file mode 100644 index 0000000..2822ae8 --- /dev/null +++ b/app/controllers/auth.php @@ -0,0 +1,236 @@ +add('POST', '/api/auth/register', fn() => $self->registerUser()); + $router->add('POST', '/api/auth/login', fn() => $self->login()); + $router->add('POST', '/api/auth/2fa/verify', fn() => $self->verifyMfa()); + $router->add('POST', '/api/auth/refresh', fn() => $self->refresh()); + $router->add('POST', '/api/auth/logout', fn() => $self->logout()); + $router->add('POST', '/api/auth/password/forgot', fn() => $self->passwordForgot()); + $router->add('POST', '/api/auth/password/reset', fn() => $self->passwordReset()); + $router->add('POST', '/api/auth/2fa/setup', fn() => $self->setupMfa()); + $router->add('POST', '/api/auth/2fa/confirm', fn() => $self->confirmMfa()); + $router->add('POST', '/api/auth/2fa/disable', fn() => $self->disableMfa()); + $router->add('POST', '/api/auth/sse-key', fn() => $self->issueSseKey()); + } + + private function registerUser(): void { + /** @var AuthService $auth */ + $auth = $this->auth(); + $body = read_json_body(); + $email = (string)($body['email'] ?? ''); + $password = (string)($body['password'] ?? ''); + $res = $auth->register($email, $password); + if (empty($res['ok'])) { + Response::json(['ok' => false, 'error' => ['code' => 'REGISTER_FAILED', 'message' => $res['error'] ?? 'failed']], 400); + return; + } + Response::json(['ok' => true, 'data' => ['user_id' => $res['user_id'], 'role' => $res['role']]]); + } + + private function login(): void { + /** @var AuthService $auth */ + $auth = $this->auth(); + $body = read_json_body(); + $email = (string)($body['email'] ?? ''); + $password = (string)($body['password'] ?? ''); + $clientType = (string)($body['client_type'] ?? 'web'); + $deviceId = (string)($body['device_id'] ?? ''); + $res = $auth->login($email, $password, $clientType, $deviceId); + if (empty($res['ok'])) { + $err = ['code' => 'LOGIN_FAILED', 'message' => $res['error'] ?? 'failed']; + $status = 401; + if (!empty($res['retry_after'])) { + $err['retry_after'] = (int)$res['retry_after']; + $status = 429; + } + Response::json(['ok' => false, 'error' => $err], $status); + return; + } + if (!empty($res['mfa_required'])) { + Response::json(['ok' => true, 'data' => [ + 'mfa_required' => true, + 'challenge_token' => $res['challenge_token'] ?? '', + ]]); + return; + } + $tokens = $res['tokens'] ?? []; + if (!empty($tokens['access_token'])) { + setcookie('access_token', $tokens['access_token'], [ + 'expires' => (int)($tokens['access_expires_at'] ?? 0), + 'path' => '/', + 'httponly' => true, + 'samesite' => 'Lax', + ]); + } + Response::json(['ok' => true, 'data' => $tokens]); + } + + private function verifyMfa(): void { + /** @var AuthService $auth */ + $auth = $this->auth(); + $body = read_json_body(); + $challenge = (string)($body['challenge_token'] ?? ''); + $code = (string)($body['code'] ?? ''); + $clientType = (string)($body['client_type'] ?? 'web'); + $deviceId = (string)($body['device_id'] ?? ''); + $res = $auth->verifyMfa($challenge, $code, $clientType, $deviceId); + if (empty($res['ok'])) { + $err = ['code' => 'MFA_FAILED', 'message' => $res['error'] ?? 'failed']; + $status = 401; + if (!empty($res['retry_after'])) { + $err['retry_after'] = (int)$res['retry_after']; + $status = 429; + } + Response::json(['ok' => false, 'error' => $err], $status); + return; + } + $tokens = $res['tokens'] ?? []; + if (!empty($tokens['access_token'])) { + setcookie('access_token', $tokens['access_token'], [ + 'expires' => (int)($tokens['access_expires_at'] ?? 0), + 'path' => '/', + 'httponly' => true, + 'samesite' => 'Lax', + ]); + } + Response::json(['ok' => true, 'data' => $tokens]); + } + + private function refresh(): void { + /** @var AuthService $auth */ + $auth = $this->auth(); + $body = read_json_body(); + $refresh = (string)($body['refresh_token'] ?? ''); + $clientType = (string)($body['client_type'] ?? 'web'); + $deviceId = (string)($body['device_id'] ?? ''); + $res = $auth->refresh($refresh, $clientType, $deviceId); + if (empty($res['ok'])) { + Response::json(['ok' => false, 'error' => ['code' => 'REFRESH_FAILED', 'message' => $res['error'] ?? 'failed']], 401); + return; + } + $tokens = $res['tokens'] ?? []; + if (!empty($tokens['access_token'])) { + setcookie('access_token', $tokens['access_token'], [ + 'expires' => (int)($tokens['access_expires_at'] ?? 0), + 'path' => '/', + 'httponly' => true, + 'samesite' => 'Lax', + ]); + } + Response::json(['ok' => true, 'data' => $tokens]); + } + + private function logout(): void { + /** @var AuthService $auth */ + $auth = $this->auth(); + $body = read_json_body(); + $refresh = (string)($body['refresh_token'] ?? ''); + if ($refresh !== '') { + $auth->logout($refresh); + } else { + $token = (string)($_COOKIE['access_token'] ?? ''); + $auth->logoutByAccessToken($token); + } + setcookie('access_token', '', [ + 'expires' => time() - 3600, + 'path' => '/', + 'httponly' => true, + 'samesite' => 'Lax', + ]); + setcookie('sse_key', '', [ + 'expires' => time() - 3600, + 'path' => '/', + 'httponly' => true, + 'samesite' => 'Lax', + ]); + Response::json(['ok' => true]); + } + + private function passwordForgot(): void { + /** @var AuthService $auth */ + $auth = $this->auth(); + $body = read_json_body(); + $email = (string)($body['email'] ?? ''); + $res = $auth->passwordForgot($email); + $data = $res; + unset($data['ok']); + Response::json(['ok' => true, 'data' => $data]); + } + + private function passwordReset(): void { + /** @var AuthService $auth */ + $auth = $this->auth(); + $body = read_json_body(); + $token = (string)($body['token'] ?? ''); + $password = (string)($body['password'] ?? ''); + $res = $auth->passwordReset($token, $password); + if (empty($res['ok'])) { + Response::json(['ok' => false, 'error' => ['code' => 'RESET_FAILED', 'message' => $res['error'] ?? 'failed']], 400); + return; + } + Response::json(['ok' => true]); + } + + private function setupMfa(): void { + /** @var AuthService $auth */ + $auth = $this->auth(); + $user = $auth->requireAuth(); + $res = $auth->setupMfa((int)$user['id']); + if (empty($res['ok'])) { + Response::json(['ok' => false, 'error' => ['code' => 'MFA_SETUP_FAILED', 'message' => $res['error'] ?? 'failed']], 400); + return; + } + Response::json(['ok' => true, 'data' => $res]); + } + + private function confirmMfa(): void { + /** @var AuthService $auth */ + $auth = $this->auth(); + $user = $auth->requireAuth(); + $body = read_json_body(); + $code = (string)($body['code'] ?? ''); + $res = $auth->confirmMfa((int)$user['id'], $code); + if (empty($res['ok'])) { + Response::json(['ok' => false, 'error' => ['code' => 'MFA_CONFIRM_FAILED', 'message' => $res['error'] ?? 'failed']], 400); + return; + } + Response::json(['ok' => true, 'data' => $res]); + } + + private function disableMfa(): void { + /** @var AuthService $auth */ + $auth = $this->auth(); + $user = $auth->requireAuth(); + $res = $auth->disableMfa((int)$user['id']); + if (empty($res['ok'])) { + Response::json(['ok' => false, 'error' => ['code' => 'MFA_DISABLE_FAILED', 'message' => $res['error'] ?? 'failed']], 400); + return; + } + Response::json(['ok' => true]); + } + + private function issueSseKey(): void { + /** @var AuthService $auth */ + $auth = $this->auth(); + $user = $auth->requireAuth(); + $key = $auth->issueSseKey((int)$user['id']); + $ttl = (int)($key['expires_in'] ?? 60); + setcookie('sse_key', $key['key'], [ + 'expires' => time() + max(10, $ttl), + 'path' => '/', + 'httponly' => true, + 'samesite' => 'Lax', + ]); + Response::json(['ok' => true, 'data' => $key]); + } +} diff --git a/app/controllers/debug.php b/app/controllers/debug.php new file mode 100644 index 0000000..32bee89 --- /dev/null +++ b/app/controllers/debug.php @@ -0,0 +1,214 @@ +add('POST', '/api/debug/event', fn() => $self->debugEvent()); + $router->add('GET', '/api/debug/stats', fn() => $self->stats()); + $router->add('GET', '/api/debug/db-tables', fn() => $self->dbTables()); + $router->add('GET', '/api/debug/db-table', fn() => $self->dbTable()); + $router->add('POST', '/api/debug/clear-content', fn() => $self->clearContent()); + $router->add('POST', '/api/debug/clear-index', fn() => $self->clearIndex()); + $router->add('POST', '/api/debug/reset-db', fn() => $self->resetDb()); + $router->add('GET', '/api/debug/db-dump', fn() => $self->dbDump()); + $router->add('POST', '/api/debug/db-restore', fn() => $self->dbRestore()); + $router->add('GET', '/api/debug/mkvmerge-check', fn() => $self->mkvmergeCheck()); + } + + private function debugEvent(): void { + require_debug($this->config(), false); + $logger = $this->logger(); + $body = read_json_body(); + $name = (string)($body['name'] ?? 'debug'); + $payload = is_array($body['payload'] ?? null) ? $body['payload'] : []; + $logger->log('debug', 'Debug event', ['name' => $name, 'payload' => $payload]); + Response::json(['ok' => true, 'data' => ['name' => $name]]); + } + + private function stats(): void { + require_debug($this->config(), false); + $logger = $this->logger(); + + try { + $schema = $this->services()['schema']; + $content = $schema->getContentStats(); + $db = $schema->getDbStats(); + $dbInfo = $schema->getDbInfo(); + Response::json(['ok' => true, 'data' => ['content' => $content, 'db' => $db, 'db_info' => $dbInfo]]); + } catch (Throwable $e) { + $logger->log('error', 'Debug stats failed', ['error' => $e->getMessage()]); + Response::json(['ok' => false, 'error' => ['code' => 'STATS_FAILED', 'message' => $e->getMessage()]], 500); + } + } + + private function dbTables(): void { + require_debug($this->config(), false); + $logger = $this->logger(); + try { + $items = $this->services()['schema']->listTablesWithCounts(); + Response::json(['ok' => true, 'data' => ['items' => $items]]); + } catch (Throwable $e) { + $logger->log('error', 'Debug db tables failed', ['error' => $e->getMessage()]); + Response::json(['ok' => false, 'error' => ['code' => 'DB_TABLES_FAILED', 'message' => $e->getMessage()]], 500); + } + } + + private function dbTable(): void { + require_debug($this->config(), false); + $logger = $this->logger(); + $name = (string)($_GET['name'] ?? ''); + $limit = isset($_GET['limit']) ? (int)$_GET['limit'] : 50; + try { + $data = $this->services()['schema']->fetchTableRows($name, $limit); + Response::json(['ok' => true, 'data' => $data]); + } catch (Throwable $e) { + $logger->log('error', 'Debug db table preview failed', ['error' => $e->getMessage()]); + Response::json(['ok' => false, 'error' => ['code' => 'DB_TABLE_FAILED', 'message' => $e->getMessage()]], 500); + } + } + + private function clearContent(): void { + require_debug($this->config(), false); + $logger = $this->logger(); + + $body = read_json_body(); + if ((string)($body['confirm'] ?? '') !== 'CLEAR CONTENT') { + $logger->log('warn', 'Clear content denied: bad confirmation'); + Response::json(['ok' => false, 'error' => ['code' => 'CONFIRM_REQUIRED', 'message' => 'Type CLEAR CONTENT']], 400); + return; + } + + try { + $this->services()['schema']->clearContent(); + $logger->log('warn', 'Content cleared'); + Response::json(['ok' => true, 'data' => ['reload' => true]]); + } catch (Throwable $e) { + $logger->log('error', 'Clear content failed', ['error' => $e->getMessage()]); + Response::json(['ok' => false, 'error' => ['code' => 'CLEAR_FAILED', 'message' => $e->getMessage()]], 500); + } + } + + private function clearIndex(): void { + require_debug($this->config(), false); + $logger = $this->logger(); + + $body = read_json_body(); + if ((string)($body['confirm'] ?? '') !== 'CLEAR') { + $logger->log('warn', 'Clear index denied: bad confirmation'); + Response::json(['ok' => false, 'error' => ['code' => 'CONFIRM_REQUIRED', 'message' => 'Type CLEAR']], 400); + return; + } + + try { + $this->services()['schema']->clearIndex(); + $logger->log('info', 'Index cleared'); + Response::json(['ok' => true]); + } catch (Throwable $e) { + $logger->log('error', 'Clear index failed', ['error' => $e->getMessage()]); + Response::json(['ok' => false, 'error' => ['code' => 'CLEAR_FAILED', 'message' => $e->getMessage()]], 500); + } + } + + private function resetDb(): void { + require_debug($this->config(), true); + $logger = $this->logger(); + + $body = read_json_body(); + if ((string)($body['confirm'] ?? '') !== 'RESET DATABASE') { + $logger->log('warn', 'Reset DB denied: bad confirmation'); + Response::json(['ok' => false, 'error' => ['code' => 'CONFIRM_REQUIRED', 'message' => 'Type RESET DATABASE']], 400); + return; + } + + try { + $log = $this->services()['schema']->resetDatabase(); + $logger->log('warn', 'Database reset', ['log' => $log]); + Response::json(['ok' => true, 'data' => ['log' => $log, 'reload' => true]]); + } catch (Throwable $e) { + $logger->log('error', 'Reset DB failed', ['error' => $e->getMessage()]); + Response::json(['ok' => false, 'error' => ['code' => 'RESET_FAILED', 'message' => $e->getMessage()]], 500); + } + } + + private function dbDump(): void { + require_debug($this->config(), false); + $logger = $this->logger(); + try { + $sql = $this->services()['schema']->dumpDatabase(); + $filename = 'scmedia_dump_' . date('Ymd_His') . '.sql'; + header('Content-Type: application/sql; charset=utf-8'); + header('Content-Disposition: attachment; filename="' . $filename . '"'); + echo $sql; + } catch (Throwable $e) { + $logger->log('error', 'DB dump failed', ['error' => $e->getMessage()]); + Response::json(['ok' => false, 'error' => ['code' => 'DUMP_FAILED', 'message' => $e->getMessage()]], 500); + } + } + + private function dbRestore(): void { + require_debug($this->config(), true); + $logger = $this->logger(); + + $body = read_json_body(); + if ((string)($body['confirm'] ?? '') !== 'RESTORE DATABASE') { + $logger->log('warn', 'Restore DB denied: bad confirmation'); + Response::json(['ok' => false, 'error' => ['code' => 'CONFIRM_REQUIRED', 'message' => 'Type RESTORE DATABASE']], 400); + return; + } + $sql = (string)($body['sql'] ?? ''); + if (trim($sql) === '') { + Response::json(['ok' => false, 'error' => ['code' => 'SQL_REQUIRED', 'message' => 'SQL required']], 400); + return; + } + + try { + $log = $this->services()['schema']->restoreDatabaseFromSql($sql); + $logger->log('warn', 'Database restored', ['log' => $log]); + Response::json(['ok' => true, 'data' => ['log' => $log, 'reload' => true]]); + } catch (Throwable $e) { + $logger->log('error', 'Restore DB failed', ['error' => $e->getMessage()]); + Response::json(['ok' => false, 'error' => ['code' => 'RESTORE_FAILED', 'message' => $e->getMessage()]], 500); + } + } + + private function mkvmergeCheck(): void { + require_debug($this->config(), false); + $logger = $this->logger(); + $path = (string)($_GET['path'] ?? ''); + if ($path === '') { + Response::json(['ok' => false, 'error' => ['code' => 'PATH_REQUIRED', 'message' => 'path required']], 400); + return; + } + + $shell = $this->services()['shell'] ?? null; + $bin = ($shell instanceof \ScMedia\Services\ShellTool) ? ($shell->which('mkvmerge') ?? '') : ''; + if ($bin === '') { + $logger->log('warn', 'mkvmerge check failed: binary not found'); + Response::json(['ok' => false, 'error' => ['code' => 'NO_MKVMERGE', 'message' => 'mkvmerge not found']]); + return; + } + + $cmdBase = $bin . ' -J ' . escapeshellarg($path) . ' 2>/dev/null'; + $out = ($shell instanceof \ScMedia\Services\ShellTool) ? $shell->exec($cmdBase) : null; + if (!is_string($out) || $out === '') { + $logger->log('warn', 'mkvmerge check returned empty output', ['path' => $path]); + Response::json(['ok' => true, 'data' => ['bin' => $bin, 'output' => null]]); + return; + } + + $json = json_decode($out, true); + if (!is_array($json)) { + $logger->log('warn', 'mkvmerge check failed: bad json', ['path' => $path]); + Response::json(['ok' => false, 'error' => ['code' => 'BAD_JSON', 'message' => 'invalid mkvmerge json']], 400); + return; + } + + Response::json(['ok' => true, 'data' => ['bin' => $bin, 'output' => $json]]); + } +} diff --git a/app/controllers/events.php b/app/controllers/events.php new file mode 100644 index 0000000..30dd7f7 --- /dev/null +++ b/app/controllers/events.php @@ -0,0 +1,353 @@ +logger = $container->logger(); + $this->auth = $container->auth(); + } + + public static function register(Router $router, Container $container): void { + $router->add('GET', '/api/events', function() use ($container) { + (new self($container))->handle(); + }); + } + + public function handle(): void { + $userId = $this->readUserId(); + if (!$userId) { + http_response_code(401); + header('Content-Type: text/plain; charset=utf-8'); + echo "Unauthorized"; + return; + } + + $sessionToken = $this->auth->startSseSession($userId); + $this->initSseHeaders(); + $this->sendReady(); + + $this->logger->log('debug', 'SSE connected', [ + 'user_id' => $userId, + 'session' => $sessionToken, + 'ip' => $_SERVER['REMOTE_ADDR'] ?? null, + 'ua' => $_SERVER['HTTP_USER_AGENT'] ?? null, + ]); + + $start = time(); + $maxSeconds = 3600; + + $bg = $this->settings()->getAll()['background'] ?? []; + $this->auth->setSseSessionTtl((int)($bg['sse_session_ttl_seconds'] ?? 20)); + + $exitReason = 'max_seconds'; + while ((time() - $start) < $maxSeconds) { + $now = microtime(true); + try { + if (connection_aborted()) { + $this->logger->log('debug', 'SSE client aborted', [ + 'user_id' => $userId, + 'session' => $sessionToken, + ]); + $exitReason = 'client_aborted'; + break; + } + $this->sendKeepalive($now); + if (!$this->checkSession($now, $userId, $sessionToken)) { + $exitReason = 'superseded'; + break; + } + $this->maybeUpdateTick($now); + $this->sendJobs($now); + $this->sendSources($now); + } catch (Throwable $e) { + $this->logger->log('error', 'SSE loop error', [ + 'error' => $e->getMessage(), + 'file' => $e->getFile(), + 'line' => $e->getLine(), + ]); + $exitReason = 'loop_error'; + break; + } + usleep(300000); + } + + $this->logger->log('debug', 'SSE closed', [ + 'user_id' => $userId, + 'session' => $sessionToken, + 'reason' => $exitReason, + 'ip' => $_SERVER['REMOTE_ADDR'] ?? null, + 'ua' => $_SERVER['HTTP_USER_AGENT'] ?? null, + ]); + } + + // Read and validate SSE key. + private function readUserId(): ?int { + $key = isset($_COOKIE['sse_key']) ? (string)$_COOKIE['sse_key'] : ''; + $key = trim($key, "\"'"); + $key = urldecode($key); + $userId = $this->auth->validateSseKey($key); + if (!$userId) { + $this->logger->log('warn', 'SSE auth failed', [ + 'ip' => $_SERVER['REMOTE_ADDR'] ?? null, + 'has_cookie' => $key !== '', + ]); + return null; + } + return $userId; + } + + // Initialize SSE headers and buffers. + private function initSseHeaders(): void { + @set_time_limit(0); + @ignore_user_abort(true); + header('Content-Type: text/event-stream; charset=utf-8'); + header('Cache-Control: no-cache'); + header('Connection: keep-alive'); + header('X-Accel-Buffering: no'); + + @ini_set('output_buffering', 'off'); + @ini_set('zlib.output_compression', '0'); + while (ob_get_level() > 0) { + ob_end_flush(); + } + @ob_implicit_flush(true); + @flush(); + } + + // Send initial SSE meta events. + private function sendReady(): void { + echo "retry: 5000\n"; + echo "event: ready\n"; + echo "data: {}\n\n"; + @flush(); + } + + // Emit keepalive comments. + private function sendKeepalive(float $now): void { + if ($now < $this->keepAliveNextAt) { + return; + } + echo ": keepalive\n\n"; + $this->keepAliveNextAt = $now + $this->keepAliveInterval; + if (ob_get_level() > 0) { + @ob_flush(); + } + @flush(); + } + + // Validate session and refresh heartbeat. + private function checkSession(float $now, int $userId, string $sessionToken): bool { + if ($now < $this->authCheckNextAt) { + return true; + } + if (!$this->auth->isSseSessionActive($userId, $sessionToken)) { + $this->logger->log('debug', 'SSE superseded', [ + 'user_id' => $userId, + 'session' => $sessionToken, + 'ip' => $_SERVER['REMOTE_ADDR'] ?? null, + 'ua' => $_SERVER['HTTP_USER_AGENT'] ?? null, + ]); + return false; + } + $this->auth->touchSseSession($userId, $sessionToken); + $this->authCheckNextAt = $now + $this->authCheckInterval; + return true; + } + + // Update tick/snapshot/keepalive intervals and emit tick. + private function maybeUpdateTick(float $now): void { + if ($now < $this->tickNextAt) { + return; + } + $ui = $this->settings()->getAll()['ui'] ?? []; + $bg = $this->settings()->getAll()['background'] ?? []; + $tickSeconds = (int)($ui['sse_tick_seconds'] ?? 10); + $snapSeconds = (int)($ui['sse_snapshot_seconds'] ?? 120); + $keepAliveSeconds = (float)($ui['sse_keepalive_seconds'] ?? 2); + $this->auth->setSseSessionTtl((int)($bg['sse_session_ttl_seconds'] ?? 20)); + $this->tickInterval = max(1.0, (float)$tickSeconds); + $this->snapshotInterval = max(10.0, (float)$snapSeconds); + $this->jobsSnapshotInterval = max(2.0, $this->tickInterval); + $this->keepAliveInterval = max(1.0, min(5.0, $keepAliveSeconds)); + $this->tickNextAt = $now + $this->tickInterval; + echo "event: tick\n"; + echo "data: " . json_encode(['ts' => time()], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\n\n"; + if (ob_get_level() > 0) { + @ob_flush(); + } + @flush(); + } + + // Emit jobs payload (if changed/snapshot). + private function sendJobs(float $now): void { + if ($now < $this->jobsNextAt) { + return; + } + $db = $this->db(); + $running = $db->fetchOne("SELECT COUNT(*) AS c FROM jobs WHERE status='running'"); + $queued = $db->fetchOne("SELECT COUNT(*) AS c FROM jobs WHERE status='queued'"); + $errors = $db->fetchOne("SELECT COUNT(*) AS c FROM jobs WHERE status='error'"); + $active = $db->fetchOne(" + SELECT id, type, title, status, progress_current, progress_total, progress_pct, cancel_requested + FROM jobs + WHERE status='running' + ORDER BY started_at ASC + LIMIT 1 + "); + $bg = $this->settings()->getAll()['background'] ?? []; + + $activeList = $db->fetchAll(" + SELECT id, type, title, status, progress_current, progress_total, progress_pct, cancel_requested, started_at + FROM jobs + WHERE status='running' + ORDER BY started_at ASC + LIMIT 50 + "); + $activeList = array_map(function($row) { + return [ + 'id' => (int)$row['id'], + 'type' => (string)$row['type'], + 'title' => (string)$row['title'], + 'status' => (string)$row['status'], + 'progress' => (int)($row['progress_current'] ?? 0), + 'progress_total' => (int)($row['progress_total'] ?? 0), + 'progress_pct' => (int)($row['progress_pct'] ?? 0), + 'cancel_requested' => !empty($row['cancel_requested']), + 'started_at' => $row['started_at'] ?? null, + ]; + }, $activeList); + + $payload = [ + 'paused' => !empty($bg['paused']), + 'running' => (int)($running['c'] ?? 0), + 'queued' => (int)($queued['c'] ?? 0), + 'errors' => (int)($errors['c'] ?? 0), + 'active' => $active ? [ + 'id' => (int)$active['id'], + 'type' => (string)$active['type'], + 'title' => (string)$active['title'], + 'status' => (string)$active['status'], + 'progress' => (int)($active['progress_current'] ?? 0), + 'progress_total' => (int)($active['progress_total'] ?? 0), + 'progress_pct' => (int)($active['progress_pct'] ?? 0), + 'cancel_requested' => !empty($active['cancel_requested']), + ] : null, + 'active_list' => $activeList, + ]; + + $hash = md5(json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + $changed = $hash !== $this->jobsLastHash; + $isSnapshot = $now >= $this->jobsSnapshotAt || $this->jobsSnapshotAt === 0.0; + if ($changed || $isSnapshot) { + $this->jobsLastHash = $hash; + if ($isSnapshot) { + $this->jobsSnapshotAt = $now + $this->jobsSnapshotInterval; + } + echo "event: jobs\n"; + echo "data: " . json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\n\n"; + } + $this->jobsNextAt = $now + $this->jobsInterval; + if (ob_get_level() > 0) { + @ob_flush(); + } + @flush(); + } + + // Emit sources payload and adjust interval. + private function sendSources(float $now): void { + if ($now < $this->sourcesNextAt) { + return; + } + $sourcesService = $this->services()['sources'] ?? null; + if (!$sourcesService instanceof \ScMedia\Services\SourcesService) { + return; + } + $elapsed = 0.0; + $items = []; + try { + $t0 = microtime(true); + $items = $sourcesService->list(); + $elapsed = microtime(true) - $t0; + } catch (Throwable $e) { + $this->logger->log('warn', 'SSE sources failed', ['error' => $e->getMessage()]); + } + + $map = []; + foreach ($items as $it) { + $key = (string)($it['source'] ?? '') . ':' . (string)($it['id'] ?? ''); + if ($key === ':') continue; + $map[$key] = $it; + } + + $changed = []; + foreach ($map as $key => $it) { + if (!isset($this->sourcesLastMap[$key])) { + $changed[] = $it; + continue; + } + $prev = $this->sourcesLastMap[$key]; + if (($prev['status'] ?? null) !== ($it['status'] ?? null) + || ($prev['percent_done'] ?? null) !== ($it['percent_done'] ?? null) + || ($prev['size_bytes'] ?? null) !== ($it['size_bytes'] ?? null) + || ($prev['name'] ?? null) !== ($it['name'] ?? null) + || ($prev['content_type'] ?? null) !== ($it['content_type'] ?? null) + || ($prev['file_count'] ?? null) !== ($it['file_count'] ?? null)) { + $changed[] = $it; + } + } + $removed = array_values(array_diff(array_keys($this->sourcesLastMap), array_keys($map))); + + $isSnapshot = $now >= $this->sourcesSnapshotAt || $this->sourcesSnapshotAt === 0.0; + if ($isSnapshot) { + $this->sourcesSnapshotAt = $now + $this->snapshotInterval; + } + + if ($isSnapshot || count($changed) > 0 || count($removed) > 0) { + echo "event: sources\n"; + echo "data: " . json_encode([ + 'items' => $isSnapshot ? array_values($items) : $changed, + 'removed' => $removed, + 'snapshot' => $isSnapshot, + 'ts' => time(), + ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\n\n"; + } + + $this->sourcesLastMap = $map; + $cfg = $this->settings()->getAll()['sources']['transmission'] ?? []; + $host = (string)($cfg['host'] ?? ''); + $isLocal = in_array($host, ['127.0.0.1', 'localhost', '::1'], true); + $base = $isLocal ? 2.5 : 6.0; + $penalty = max(0.0, $elapsed - 0.4) * 2.0; + $this->sourcesInterval = min(12.0, max(1.0, $base + $penalty)); + $this->sourcesNextAt = $now + $this->sourcesInterval; + if (ob_get_level() > 0) { + @ob_flush(); + } + @flush(); + } +} diff --git a/app/controllers/items.php b/app/controllers/items.php new file mode 100644 index 0000000..29af405 --- /dev/null +++ b/app/controllers/items.php @@ -0,0 +1,112 @@ +add('GET', '/api/items', fn() => $self->listItems()); + $router->add('POST', '/api/items/scan', fn() => $self->scanItems()); + } + + private function listItems(): void { + $db = $this->db(); + $status = $_GET['status'] ?? ''; + + $where = []; + $params = []; + + if ($status !== '') { + $where[] = 'i.status = :status'; + $params[':status'] = $status; + } + + $sql = " + SELECT + i.id, + i.scan_profile_id, + i.abs_path, + i.rel_path, + i.display_name, + i.kind, + i.year, + i.structure, + i.confidence, + i.video_count, + i.file_count, + i.status, + i.last_seen_at + FROM items i + "; + + if (count($where) > 0) { + $sql .= " WHERE " . implode(' AND ', $where); + } + + $sql .= " ORDER BY i.updated_at DESC, i.id DESC LIMIT 2000"; + + $st = $db->prepare($sql); + $st->execute($params); + $rows = $st->fetchAll(); + + $items = []; + foreach ($rows as $r) { + $items[] = [ + 'id' => (int)$r['id'], + 'scan_profile_id' => (int)$r['scan_profile_id'], + 'abs_path' => $r['abs_path'], + 'rel_path' => $r['rel_path'], + 'display_name' => $r['display_name'], + 'kind' => $r['kind'], + 'year' => $r['year'] !== null ? (int)$r['year'] : null, + 'structure' => $r['structure'], + 'confidence' => (int)$r['confidence'], + 'video_count' => (int)$r['video_count'], + 'file_count' => (int)$r['file_count'], + 'status' => $r['status'], + 'last_seen_at' => $r['last_seen_at'], + ]; + } + + json_response(['ok' => true, 'items' => $items]); + } + + private function scanItems(): void { + /** @var JobsService $jobs */ + $jobs = $this->services()['jobs']; + /** @var ScannerService $scanner */ + $scanner = $this->services()['scanner']; + $logger = $this->logger(); + $settings = $this->settings(); + + $bg = $settings->getAll()['background'] ?? []; + if (!empty($bg['paused'])) { + json_response(['ok' => false, 'error' => 'Background jobs paused'], 409); + } + + $jobId = $jobs->create('scan', 'Scan (UI)', ['source' => 'http']); + try { + $jobs->start($jobId); + $logger->log('info', 'Scan started', ['job_id' => $jobId, 'source' => 'http']); + $result = $scanner->runScanJob($jobId); + $status = $jobs->getStatus($jobId); + if ($status !== 'canceled') { + $jobs->finish($jobId); + $logger->log('info', 'Scan finished', ['job_id' => $jobId, 'result' => $result]); + } else { + $logger->log('warn', 'Scan canceled', ['job_id' => $jobId]); + } + json_response(['ok' => true, 'job_id' => $jobId, 'result' => $result, 'status' => $status]); + } catch (Throwable $e) { + $jobs->log($jobId, 'error', $e->getMessage()); + $jobs->fail($jobId, $e->getMessage()); + $logger->log('error', 'Scan failed', ['job_id' => $jobId, 'error' => $e->getMessage()]); + json_response(['ok' => false, 'error' => $e->getMessage()], 500); + } + } +} diff --git a/app/controllers/jobs.php b/app/controllers/jobs.php new file mode 100644 index 0000000..2fbaf2e --- /dev/null +++ b/app/controllers/jobs.php @@ -0,0 +1,167 @@ +add('GET', '/api/jobs/status', fn() => $self->status()); + $router->add('GET', '/api/jobs/recent', fn() => $self->recent()); + $router->add('GET', '/api/jobs/get', fn() => $self->getJob()); + $router->add('POST', '/api/jobs/cancel', fn() => $self->cancel()); + $router->add('POST', '/api/jobs/watchdog', fn() => $self->watchdog()); + } + + private function status(): void { + $db = $this->db(); + $settings = $this->settings(); + + $running = $db->fetchOne("SELECT COUNT(*) AS c FROM jobs WHERE status='running'"); + $queued = $db->fetchOne("SELECT COUNT(*) AS c FROM jobs WHERE status='queued'"); + $errors = $db->fetchOne("SELECT COUNT(*) AS c FROM jobs WHERE status='error'"); + $active = $db->fetchOne(" + SELECT id, type, title, status, progress_current, progress_total, progress_pct, cancel_requested + FROM jobs + WHERE status='running' + ORDER BY started_at ASC + LIMIT 1 + "); + $activeList = $db->fetchAll(" + SELECT id, type, title, status, progress_current, progress_total, progress_pct, cancel_requested, started_at + FROM jobs + WHERE status='running' + ORDER BY started_at ASC + LIMIT 50 + "); + + $bg = $settings->getAll()['background'] ?? []; + + json_response(['ok' => true, 'data' => [ + 'paused' => !empty($bg['paused']), + 'running' => (int)($running['c'] ?? 0), + 'queued' => (int)($queued['c'] ?? 0), + 'errors' => (int)($errors['c'] ?? 0), + 'active' => $active ? [ + 'id' => (int)$active['id'], + 'type' => (string)$active['type'], + 'title' => (string)$active['title'], + 'status' => (string)$active['status'], + 'progress' => (int)($active['progress_current'] ?? 0), + 'progress_total' => (int)($active['progress_total'] ?? 0), + 'progress_pct' => (int)($active['progress_pct'] ?? 0), + 'cancel_requested' => !empty($active['cancel_requested']), + ] : null, + 'active_list' => array_map(function($row) { + return [ + 'id' => (int)$row['id'], + 'type' => (string)$row['type'], + 'title' => (string)$row['title'], + 'status' => (string)$row['status'], + 'progress' => (int)($row['progress_current'] ?? 0), + 'progress_total' => (int)($row['progress_total'] ?? 0), + 'progress_pct' => (int)($row['progress_pct'] ?? 0), + 'cancel_requested' => !empty($row['cancel_requested']), + 'started_at' => $row['started_at'] ?? null, + ]; + }, $activeList), + ]]); + } + + private function recent(): void { + $db = $this->db(); + $limit = isset($_GET['limit']) ? (int)$_GET['limit'] : 20; + if ($limit < 1) $limit = 20; + if ($limit > 200) $limit = 200; + $rows = $db->fetchAll(" + SELECT id, type, title, status, error_message, finished_at + FROM jobs + WHERE status IN ('done','error','canceled') + ORDER BY finished_at DESC + LIMIT {$limit} + "); + $out = []; + foreach ($rows as $r) { + $out[] = [ + 'id' => (int)$r['id'], + 'type' => (string)$r['type'], + 'title' => (string)$r['title'], + 'status' => (string)$r['status'], + 'error_message' => $r['error_message'] ?? null, + 'finished_at' => $r['finished_at'] ?? null, + ]; + } + json_response(['ok' => true, 'data' => ['items' => $out]]); + } + + private function getJob(): void { + $db = $this->db(); + $id = (int)($_GET['id'] ?? 0); + if ($id <= 0) { + json_response(['ok' => false, 'error' => 'id required'], 400); + } + + $job = $db->fetchOne("SELECT * FROM jobs WHERE id=:id", [':id' => $id]); + if (!$job) { + json_response(['ok' => false, 'error' => 'job not found'], 404); + } + + $rows = $db->fetchAll(" + SELECT ts, level, message + FROM job_logs + WHERE job_id=:id + ORDER BY id ASC + LIMIT 5000 + ", [':id' => $id]); + + $lines = []; + foreach ($rows as $r) { + $ts = (string)($r['ts'] ?? ''); + $lvl = (string)($r['level'] ?? 'info'); + $msg = (string)($r['message'] ?? ''); + $lines[] = "{$ts} [{$lvl}] {$msg}"; + } + + $out = [ + 'id' => (int)$job['id'], + 'type' => (string)$job['type'], + 'title' => (string)$job['title'], + 'status' => (string)$job['status'], + 'cancel_requested' => !empty($job['cancel_requested']), + 'progress' => (int)($job['progress_current'] ?? 0), + 'progress_total' => (int)($job['progress_total'] ?? 0), + 'progress_pct' => (int)($job['progress_pct'] ?? 0), + 'error_message' => $job['error_message'] ?? null, + 'created_at' => $job['created_at'] ?? null, + 'started_at' => $job['started_at'] ?? null, + 'finished_at' => $job['finished_at'] ?? null, + 'last_heartbeat' => $job['last_heartbeat'] ?? null, + 'log_text' => implode("\n", $lines), + ]; + + json_response(['ok' => true, 'job' => $out]); + } + + private function cancel(): void { + /** @var \ScMedia\Services\JobsService $jobs */ + $jobs = $this->services()['jobs']; + $body = read_json_body(); + $id = (int)($body['id'] ?? 0); + if ($id <= 0) { + json_response(['ok' => false, 'error' => 'id required'], 400); + } + $jobs->requestCancel($id); + json_response(['ok' => true]); + } + + private function watchdog(): void { + /** @var \ScMedia\Services\JobsService $jobs */ + $jobs = $this->services()['jobs']; + $body = read_json_body(); + $minutes = isset($body['minutes']) ? (int)$body['minutes'] : 10; + $count = $jobs->markStalled($minutes); + json_response(['ok' => true, 'data' => ['stalled_marked' => $count]]); + } +} diff --git a/app/controllers/layout.php b/app/controllers/layout.php new file mode 100644 index 0000000..1feb420 --- /dev/null +++ b/app/controllers/layout.php @@ -0,0 +1,34 @@ +add('POST', '/api/layout/preview', fn() => $self->preview()); + } + + private function preview(): void { + $logger = $this->logger(); + $body = read_json_body(); + $all = $this->settings()->getAll(); + + $kind = (string)($body['kind'] ?? 'movies'); + $mode = (string)($body['mode'] ?? 'from_items'); + $limit = (int)($body['limit'] ?? 10); + + $data = $this->services()['layout']->preview( + $all['data'] ?? $all, + $kind === 'series' ? 'series' : 'movies', + $mode === 'samples' ? 'samples' : 'from_items', + $limit + ); + + $logger->log('info', 'Layout preview generated', ['kind' => $kind, 'mode' => $mode, 'limit' => $limit]); + Response::json(['ok' => true, 'data' => $data]); + } +} diff --git a/app/controllers/logs.php b/app/controllers/logs.php new file mode 100644 index 0000000..f8afada --- /dev/null +++ b/app/controllers/logs.php @@ -0,0 +1,72 @@ +add('POST', '/api/logs', fn() => $self->listLogs()); + $router->add('POST', '/api/logs/cleanup', fn() => $self->cleanup()); + } + + private function listLogs(): void { + /** @var LogService $logger */ + $logger = $this->logger(); + [$page, $perPage, $sort, $dir, $filters, $params] = table_body_params(100, 500); + $from = (string)($params['from'] ?? ''); + $to = (string)($params['to'] ?? ''); + $level = (string)($params['level'] ?? ''); + + if ($from === '' || $to === '') { + $rangeValue = filter_value($filters, 'ts'); + $rangeOp = filter_op($filters, 'ts'); + if ($rangeOp === 'between' && is_array($rangeValue)) { + $from = (string)($rangeValue[0] ?? ''); + $to = (string)($rangeValue[1] ?? ''); + } + } + if ($level === '') { + $levelValue = filter_value($filters, 'level'); + if (is_string($levelValue)) { + $level = $levelValue; + } + } + + if ($from === '' || $to === '') { + Response::json(['ok' => true, 'data' => [ + 'items' => [], + 'total' => 0, + 'page' => 1, + 'per_page' => $perPage, + ]]); + return; + } + + $rows = $logger->listByRangePaged($from, $to, $page, $perPage, $level, $sort, $dir); + Response::json(['ok' => true, 'data' => $rows]); + } + + private function cleanup(): void { + /** @var LogService $logger */ + $logger = $this->logger(); + /** @var SettingsService $settings */ + $settings = $this->settings(); + + $body = read_json_body(); + $keep = isset($body['keep_days']) ? (int)$body['keep_days'] : null; + if ($keep === null) { + $all = $settings->getAll(); + $keep = (int)($all['logs']['retention_days'] ?? 7); + } + + $deleted = $logger->cleanup($keep); + $logger->log('info', 'Logs cleanup', ['keep_days' => $keep, 'deleted' => $deleted]); + Response::json(['ok' => true, 'data' => ['deleted' => $deleted]]); + } +} diff --git a/app/controllers/media.php b/app/controllers/media.php new file mode 100644 index 0000000..5cfec4e --- /dev/null +++ b/app/controllers/media.php @@ -0,0 +1,166 @@ +add('POST', '/api/media/list', fn() => $self->listMedia()); + $router->add('GET', '/api/media/series', fn() => $self->seriesDetail()); + $router->add('GET', '/api/media/file', fn() => $self->fileDetail()); + $router->add('GET', '/api/media/rules', fn() => $self->getRules()); + $router->add('GET', '/api/media/dry-run', fn() => $self->dryRun()); + $router->add('POST', '/api/media/rules', fn() => $self->saveRules()); + $router->add('POST', '/api/media/apply', fn() => $self->applyChanges()); + } + + private function listMedia(): void { + /** @var MediaLibraryService $media */ + $media = $this->services()['media_library']; + $logger = $this->logger(); + [$page, $perPage, $sort, $dir, $filters, $params] = table_body_params(50, 500); + $tab = (string)($params['tab'] ?? 'movies'); + $tab = in_array($tab, ['movies','series','needs_mkv'], true) ? $tab : 'movies'; + $result = $media->listTabPaged($tab, $page, $perPage, $sort, $dir); + $items = $result['items'] ?? []; + $total = (int)($result['total'] ?? 0); + $logger->log('debug', 'Media list', ['tab' => $tab, 'count' => count($items), 'page' => $page]); + Response::json(['ok' => true, 'data' => [ + 'items' => $items, + 'total' => $total, + 'page' => $page, + 'per_page' => $perPage, + ]]); + } + + private function seriesDetail(): void { + /** @var MediaLibraryService $media */ + $media = $this->services()['media_library']; + /** @var \ScMedia\Services\MetadataService $metadata */ + $metadata = $this->services()['metadata']; + $logger = $this->logger(); + $key = (string)($_GET['key'] ?? ''); + if ($key === '') { + Response::json(['ok' => false, 'error' => ['code' => 'KEY_REQUIRED', 'message' => 'key required']], 400); + return; + } + $data = $media->getSeriesFiles($key); + $metaRow = $metadata->getSubjectMeta('series', $key); + $display = $metadata->formatDisplay($metaRow); + $meta = is_array($display['meta'] ?? null) ? $display['meta'] : []; + $meta['subject_kind'] = 'series'; + $meta['subject_key'] = $key; + $meta['title_display'] = $display['title_display']; + $meta['title_original'] = $display['title_original']; + $meta['year'] = $display['year']; + $logger->log('debug', 'Series detail', ['series_key' => $key, 'files' => count($data)]); + Response::json(['ok' => true, 'data' => ['files' => $data, 'meta' => $meta]]); + } + + private function fileDetail(): void { + /** @var MediaLibraryService $media */ + $media = $this->services()['media_library']; + $logger = $this->logger(); + $path = (string)($_GET['path'] ?? ''); + $id = (int)($_GET['id'] ?? 0); + if ($path === '' && $id > 0) { + $db = $this->db(); + $row = $db->fetchOne("SELECT abs_path FROM media_files WHERE id=:id", [':id' => $id]); + $path = $row ? (string)$row['abs_path'] : ''; + } + if ($path === '') { + Response::json(['ok' => false, 'error' => ['code' => 'PATH_REQUIRED', 'message' => 'path or id required']], 400); + return; + } + $data = $media->getFileDetail($path); + if (empty($data['ok'])) { + $logger->log('warn', 'Media file detail not found', ['path' => $path, 'id' => $id]); + Response::json(['ok' => false, 'error' => ['code' => 'NOT_FOUND', 'message' => (string)($data['error'] ?? 'not found')]], 404); + return; + } + $logger->log('debug', 'Media file detail', ['path' => $path, 'id' => $id]); + Response::json(['ok' => true, 'data' => $data]); + } + + private function getRules(): void { + /** @var MediaLibraryService $media */ + $media = $this->services()['media_library']; + Response::json(['ok' => true, 'data' => $media->getRules()]); + } + + private function dryRun(): void { + /** @var MediaLibraryService $media */ + $media = $this->services()['media_library']; + $logger = $this->logger(); + $tab = (string)($_GET['tab'] ?? 'movies'); + $tab = in_array($tab, ['movies','series','needs_mkv'], true) ? $tab : 'movies'; + $data = $media->dryRun($tab); + $logger->log('info', 'Dry run computed', ['tab' => $tab, 'files' => $data['files'] ?? null]); + Response::json(['ok' => true, 'data' => $data]); + } + + private function saveRules(): void { + /** @var SettingsService $settings */ + $settings = $this->settings(); + $logger = $this->logger(); + $body = read_json_body(); + $rules = is_array($body['media_rules'] ?? null) ? $body['media_rules'] : []; + $payload = ['media_rules' => $rules]; + if (isset($body['if_revision'])) { + $payload['if_revision'] = (int)$body['if_revision']; + } + try { + $rev = $settings->saveBulk($payload); + $logger->log('info', 'Media rules saved', ['revision' => $rev]); + Response::json(['ok' => true, 'data' => ['settings_revision' => $rev]]); + } catch (Throwable $e) { + $logger->log('error', 'Media rules save failed', ['error' => $e->getMessage()]); + Response::json(['ok' => false, 'error' => ['code' => 'SAVE_FAILED', 'message' => $e->getMessage()]], 400); + } + } + + private function applyChanges(): void { + /** @var \ScMedia\Services\MediaApplyService $apply */ + $apply = $this->services()['media_apply']; + /** @var \ScMedia\Services\JobsService $jobs */ + $jobs = $this->services()['jobs']; + $logger = $this->logger(); + $settings = $this->settings(); + + $body = read_json_body(); + $tab = (string)($body['tab'] ?? 'movies'); + $tab = in_array($tab, ['movies','series','needs_mkv'], true) ? $tab : 'movies'; + + $bg = $settings->getAll()['background'] ?? []; + if (!empty($bg['paused'])) { + Response::json(['ok' => false, 'error' => 'Background jobs paused'], 409); + return; + } + + $jobId = $jobs->create('apply', 'Apply media changes', ['tab' => $tab]); + try { + $jobs->start($jobId); + $logger->log('info', 'Apply started', ['job_id' => $jobId, 'tab' => $tab]); + $result = $apply->applyTab($tab, $jobId); + $status = $jobs->getStatus($jobId); + if ($status !== 'canceled') { + $jobs->finish($jobId); + $logger->log('info', 'Apply finished', ['job_id' => $jobId, 'tab' => $tab, 'result' => $result]); + } else { + $logger->log('warn', 'Apply canceled', ['job_id' => $jobId, 'tab' => $tab]); + } + Response::json(['ok' => true, 'job_id' => $jobId, 'result' => $result, 'status' => $status]); + } catch (Throwable $e) { + $jobs->log($jobId, 'error', $e->getMessage()); + $jobs->fail($jobId, $e->getMessage()); + $logger->log('error', 'Apply failed', ['job_id' => $jobId, 'tab' => $tab, 'error' => $e->getMessage()]); + Response::json(['ok' => false, 'error' => $e->getMessage()], 500); + } + } +} diff --git a/app/controllers/metadata.php b/app/controllers/metadata.php new file mode 100644 index 0000000..3df9fc6 --- /dev/null +++ b/app/controllers/metadata.php @@ -0,0 +1,89 @@ +add('POST', '/api/metadata/search', fn() => $self->search()); + $router->add('POST', '/api/metadata/select', fn() => $self->select()); + $router->add('POST', '/api/metadata/manual', fn() => $self->manual()); + $router->add('POST', '/api/metadata/manual/clear', fn() => $self->clearManual()); + } + + private function search(): void { + /** @var MetadataService $metadata */ + $metadata = $this->services()['metadata']; + $logger = $this->logger(); + $body = read_json_body(); + $query = (string)($body['query'] ?? ''); + $type = (string)($body['type'] ?? 'movie'); + $year = isset($body['year']) ? (int)$body['year'] : null; + $type = ($type === 'series') ? 'series' : 'movie'; + $results = $metadata->search($query, $type, $year); + $logger->log('info', 'Metadata search', ['query' => $query, 'type' => $type, 'year' => $year, 'results' => count($results)]); + Response::json(['ok' => true, 'data' => $results]); + } + + private function select(): void { + /** @var MetadataService $metadata */ + $metadata = $this->services()['metadata']; + $logger = $this->logger(); + $body = read_json_body(); + $kind = (string)($body['subject_kind'] ?? ''); + $key = (string)($body['subject_key'] ?? ''); + $sel = is_array($body['selection'] ?? null) ? $body['selection'] : []; + if ($kind === '' || $key === '') { + Response::json(['ok' => false, 'error' => ['code' => 'SUBJECT_REQUIRED', 'message' => 'subject required']], 400); + return; + } + $metadata->saveSelection($kind, $key, $sel); + $metaRow = $metadata->getSubjectMeta($kind, $key); + $display = $metadata->formatDisplay($metaRow); + $logger->log('info', 'Metadata selected', ['subject_kind' => $kind, 'subject_key' => $key, 'provider' => $sel['provider'] ?? null, 'provider_id' => $sel['provider_id'] ?? null]); + Response::json(['ok' => true, 'data' => $display]); + } + + private function manual(): void { + /** @var MetadataService $metadata */ + $metadata = $this->services()['metadata']; + $logger = $this->logger(); + $body = read_json_body(); + $kind = (string)($body['subject_kind'] ?? ''); + $key = (string)($body['subject_key'] ?? ''); + $title = (string)($body['title'] ?? ''); + $year = isset($body['year']) && $body['year'] !== '' ? (int)$body['year'] : null; + if ($kind === '' || $key === '') { + Response::json(['ok' => false, 'error' => ['code' => 'SUBJECT_REQUIRED', 'message' => 'subject required']], 400); + return; + } + $metadata->saveManual($kind, $key, $title, $year); + $metaRow = $metadata->getSubjectMeta($kind, $key); + $display = $metadata->formatDisplay($metaRow); + $logger->log('info', 'Metadata manual override', ['subject_kind' => $kind, 'subject_key' => $key, 'title' => $title, 'year' => $year]); + Response::json(['ok' => true, 'data' => $display]); + } + + private function clearManual(): void { + /** @var MetadataService $metadata */ + $metadata = $this->services()['metadata']; + $logger = $this->logger(); + $body = read_json_body(); + $kind = (string)($body['subject_kind'] ?? ''); + $key = (string)($body['subject_key'] ?? ''); + if ($kind === '' || $key === '') { + Response::json(['ok' => false, 'error' => ['code' => 'SUBJECT_REQUIRED', 'message' => 'subject required']], 400); + return; + } + $metadata->clearManual($kind, $key); + $metaRow = $metadata->getSubjectMeta($kind, $key); + $display = $metadata->formatDisplay($metaRow); + $logger->log('info', 'Metadata manual override cleared', ['subject_kind' => $kind, 'subject_key' => $key]); + Response::json(['ok' => true, 'data' => $display]); + } +} diff --git a/app/controllers/pages.php b/app/controllers/pages.php new file mode 100644 index 0000000..ca246db --- /dev/null +++ b/app/controllers/pages.php @@ -0,0 +1,170 @@ +add('GET', '/', fn() => $self->index()); + $router->add('GET', '/settings', fn() => $self->settings()); + $router->add('GET', '/login', fn() => $self->login()); + } + + protected function index(): void { + $i18n = $this->loadI18n(['common', 'index']); + $this->renderView(__DIR__ . '/../views/pages/index.php', $i18n); + } + + protected function settings(): void { + $i18n = $this->loadI18n(['common', 'settings']); + $config = $this->config(); + $debugToolsEnabled = (bool)($config['app']['debug_tools_enabled'] ?? false); + $allowDbReset = (bool)($config['app']['allow_db_reset'] ?? false); + $this->renderView(__DIR__ . '/../views/pages/settings.php', array_merge($i18n, [ + 'debugToolsEnabled' => $debugToolsEnabled, + 'allowDbReset' => $allowDbReset, + ])); + } + + protected function login(): void { + $i18n = $this->loadI18n(['login']); + $this->renderView(__DIR__ . '/../views/pages/login.php', $i18n); + } + + private function renderView(string $path, array $vars = []): void { + if (!is_file($path)) { + Response::json(['ok' => false, 'error' => 'View not found'], 404); + return; + } + extract($vars, EXTR_SKIP); + ob_start(); + require $path; + $html = ob_get_clean(); + Response::html($html); + } + + private function loadI18n(array $packages = ['common']): array { + /** @var SettingsService $settings */ + $settings = $this->container->settings(); + $all = $settings->getAll(); + $lang = (string)($all['general']['language'] ?? 'en'); + $cookieLang = isset($_COOKIE['scmedia_lang']) ? (string)$_COOKIE['scmedia_lang'] : ''; + if (preg_match('/^[a-z]{2}$/', $cookieLang)) { + $lang = $cookieLang; + } else { + $authUser = $this->services()['auth_user'] ?? null; + if (is_array($authUser) && !empty($authUser['id']) && $this->db()) { + $db = $this->db(); + $row = $db->fetchOne("SELECT ui_prefs_json FROM user_profiles WHERE user_id = :id", [ + ':id' => (int)$authUser['id'], + ]) ?? []; + $ui = json_decode((string)($row['ui_prefs_json'] ?? '{}'), true); + $uiLang = is_array($ui) ? (string)($ui['language'] ?? '') : ''; + if (preg_match('/^[a-z]{2}$/', $uiLang)) { + $lang = $uiLang; + } + } + } + + $dict = $this->readI18nDict($lang); + if ($lang !== 'en' && count($dict) === 0) { + $lang = 'en'; + $dict = $this->readI18nDict($lang); + } + + $dict = $this->filterI18nPackages($dict, $packages); + $t = function(string $key, string $fallback = '') use ($dict): string { + $val = $dict[$key] ?? ''; + return $val !== '' ? $val : ($fallback !== '' ? $fallback : $key); + }; + + return [ + 'lang' => $lang, + 'dict' => $dict, + 't' => $t, + 'debugToolsEnabled' => (bool)($this->config()['app']['debug_tools_enabled'] ?? false), + ]; + } + + private function readI18nDict(string $lang): array { + $path = __DIR__ . '/../../public/assets/i18n/' . basename($lang) . '.json'; + if (!is_file($path)) return []; + $raw = file_get_contents($path); + if ($raw === false) return []; + $data = json_decode($raw, true); + return is_array($data) ? $data : []; + } + + private function i18nPackages(): array { + return [ + 'common' => [ + 'prefixes' => ['common', 'nav', 'queue', 'job'], + 'keys' => ['auth.logout', 'actions.theme', 'settings.language'], + ], + 'login' => [ + 'prefixes' => ['auth'], + 'keys' => ['common.back', 'settings.language'], + ], + 'account' => [ + 'prefixes' => ['account', 'theme', 'settings.ui'], + 'keys' => ['settings.language'], + ], + 'settings' => [ + 'prefixes' => ['settings', 'rules', 'admin', 'filters'], + 'keys' => [], + ], + 'index' => [ + 'prefixes' => [ + 'app', + 'actions', + 'types', + 'bulk', + 'grid', + 'status', + 'sources', + 'queue', + 'incoming', + 'media', + 'job', + 'theme', + 'filters', + 'watchdog', + 'scan', + 'table', + ], + 'keys' => ['settings.language'], + ], + ]; + } + + private function filterI18nPackages(array $dict, array $packages): array { + $map = $this->i18nPackages(); + $out = []; + $wanted = []; + foreach ($packages as $p) { + if (isset($map[$p])) { + $wanted[] = $map[$p]; + } + } + foreach ($wanted as $pkg) { + foreach (($pkg['prefixes'] ?? []) as $prefix) { + foreach ($dict as $k => $v) { + if (str_starts_with($k, $prefix . '.')) { + $out[$k] = $v; + } + } + } + foreach (($pkg['keys'] ?? []) as $key) { + if (array_key_exists($key, $dict)) { + $out[$key] = $dict[$key]; + } + } + } + return $out; + } +} diff --git a/app/controllers/scan_profiles.php b/app/controllers/scan_profiles.php new file mode 100644 index 0000000..0a7cbc0 --- /dev/null +++ b/app/controllers/scan_profiles.php @@ -0,0 +1,76 @@ +add('GET', '/api/scan-profiles', fn() => $self->listProfiles()); + $router->add('POST', '/api/scan-profiles', fn() => $self->createProfile()); + $router->add('PUT', '/api/scan-profiles/{id}', fn(array $params) => $self->updateProfile($params)); + $router->add('DELETE', '/api/scan-profiles/{id}', fn(array $params) => $self->deleteProfile($params)); + $router->add('POST', '/api/scan-profiles/reorder', fn() => $self->reorderProfiles()); + } + + private function listProfiles(): void { + $rows = $this->services()['scan_profiles']->list(); + + $out = []; + foreach ($rows as $r) { + $r['sort_order'] = (int)($r['sort_order'] ?? 0); + $r['profile_type'] = (string)($r['profile_type'] ?? 'scan'); + $r['exclude_patterns'] = json_decode((string)$r['exclude_patterns_json'], true) ?: []; + $r['include_ext'] = $r['include_ext_json'] ? (json_decode((string)$r['include_ext_json'], true) ?: []) : null; + unset($r['exclude_patterns_json'], $r['include_ext_json']); + $out[] = $r; + } + + Response::json(['ok' => true, 'data' => $out]); + } + + private function createProfile(): void { + $logger = $this->logger(); + $body = read_json_body(); + try { + $id = $this->services()['scan_profiles']->create($body); + $logger->log('info', 'Scan profile created', ['id' => $id, 'name' => $body['name'] ?? null]); + Response::json(['ok' => true, 'data' => ['id' => $id]]); + } catch (Throwable $e) { + $logger->log('error', 'Scan profile create failed', ['error' => $e->getMessage()]); + Response::json(['ok' => false, 'error' => ['code' => 'VALIDATION_ERROR', 'message' => $e->getMessage()]], 400); + } + } + + private function updateProfile(array $params): void { + $logger = $this->logger(); + $body = read_json_body(); + try { + $this->services()['scan_profiles']->update((int)$params['id'], $body); + $logger->log('info', 'Scan profile updated', ['id' => (int)$params['id'], 'name' => $body['name'] ?? null]); + Response::json(['ok' => true]); + } catch (Throwable $e) { + $logger->log('error', 'Scan profile update failed', ['id' => (int)$params['id'], 'error' => $e->getMessage()]); + Response::json(['ok' => false, 'error' => ['code' => 'VALIDATION_ERROR', 'message' => $e->getMessage()]], 400); + } + } + + private function deleteProfile(array $params): void { + $logger = $this->logger(); + $this->services()['scan_profiles']->delete((int)$params['id']); + $logger->log('info', 'Scan profile deleted', ['id' => (int)$params['id']]); + Response::json(['ok' => true]); + } + + private function reorderProfiles(): void { + $logger = $this->logger(); + $body = read_json_body(); + $ids = is_array($body['ids'] ?? null) ? $body['ids'] : []; + $this->services()['scan_profiles']->reorder($ids); + $logger->log('info', 'Scan profiles reordered', ['count' => count($ids)]); + Response::json(['ok' => true]); + } +} diff --git a/app/controllers/settings.php b/app/controllers/settings.php new file mode 100644 index 0000000..ff9baf5 --- /dev/null +++ b/app/controllers/settings.php @@ -0,0 +1,130 @@ +add('GET', '/api/settings', fn() => $self->getSettings()); + $router->add('POST', '/api/language', fn() => $self->updateLanguage()); + $router->add('POST', '/api/settings', fn() => $self->saveSettings()); + $router->add('GET', '/api/settings/diagnostics', fn() => $self->getDiagnostics()); + $router->add('GET', '/api/settings/snapshots', fn() => $self->listSnapshots()); + $router->add('POST', '/api/settings/snapshots', fn() => $self->createSnapshot()); + $router->add('POST', '/api/settings/snapshots/restore', fn() => $self->restoreSnapshot()); + $router->add('DELETE', '/api/settings/snapshots/{id}', fn(array $params) => $self->deleteSnapshot($params)); + } + + private function getSettings(): void { + $all = $this->settings()->getAll(); + Response::json(['ok' => true, 'data' => $all]); + } + + private function updateLanguage(): void { + $logger = $this->logger(); + $body = read_json_body(); + $lang = (string)($body['language'] ?? ''); + if (!preg_match('/^[a-z]{2}$/', $lang)) { + Response::json(['ok' => false, 'error' => ['code' => 'INVALID_LANGUAGE', 'message' => 'Invalid language']], 400); + return; + } + try { + $newRev = $this->settings()->saveBulk(['general' => ['language' => $lang]]); + $logger->log('info', 'Language updated', ['language' => $lang, 'revision' => $newRev]); + Response::json(['ok' => true, 'data' => ['settings_revision' => $newRev]]); + } catch (Throwable $e) { + $logger->log('error', 'Language update failed', ['error' => $e->getMessage()]); + Response::json(['ok' => false, 'error' => ['code' => 'SAVE_FAILED', 'message' => $e->getMessage()]], 400); + } + } + + private function saveSettings(): void { + $logger = $this->logger(); + $body = read_json_body(); + try { + $newRev = $this->settings()->saveBulk($body); + $logger->log('info', 'Settings saved', ['revision' => $newRev]); + Response::json(['ok' => true, 'data' => ['settings_revision' => $newRev]]); + } catch (Throwable $e) { + $logger->log('error', 'Settings save failed', ['error' => $e->getMessage()]); + Response::json(['ok' => false, 'error' => ['code' => 'SAVE_FAILED', 'message' => $e->getMessage()]], 400); + } + } + + private function getDiagnostics(): void { + $db = $this->db(); + $shell = $this->services()['shell'] ?? null; + $bins = ['mkvmerge', 'mkvpropedit', 'ffmpeg']; + $binOut = []; + foreach ($bins as $b) { + $binOut[$b] = ($shell instanceof \ScMedia\Services\ShellTool) ? ($shell->which($b) ?? '') : ''; + } + + $root = dirname(__DIR__, 2); + $free = @disk_free_space($root); + $total = @disk_total_space($root); + $disk = [ + 'path' => $root, + 'free_bytes' => is_int($free) ? $free : null, + 'total_bytes' => is_int($total) ? $total : null, + ]; + + $running = $db->fetchOne("SELECT COUNT(*) AS c FROM jobs WHERE status='running'"); + $queued = $db->fetchOne("SELECT COUNT(*) AS c FROM jobs WHERE status='queued'"); + $errors = $db->fetchOne("SELECT COUNT(*) AS c FROM jobs WHERE status='error'"); + + Response::json(['ok' => true, 'data' => [ + 'php_version' => PHP_VERSION, + 'disk' => $disk, + 'binaries' => $binOut, + 'jobs' => [ + 'running' => (int)($running['c'] ?? 0), + 'queued' => (int)($queued['c'] ?? 0), + 'errors' => (int)($errors['c'] ?? 0), + ], + ]]); + } + + private function listSnapshots(): void { + $items = $this->settings()->listSnapshots(); + Response::json(['ok' => true, 'data' => ['items' => $items]]); + } + + private function createSnapshot(): void { + $logger = $this->logger(); + $body = read_json_body(); + $label = (string)($body['label'] ?? ''); + $user = $this->container->get('auth_user'); + $userId = is_array($user) ? (int)($user['id'] ?? 0) : null; + $id = $this->settings()->createSnapshot($label, $userId > 0 ? $userId : null); + $logger->log('info', 'Settings snapshot created', ['id' => $id, 'label' => $label ?: null, 'user_id' => $userId ?: null]); + Response::json(['ok' => true, 'data' => ['id' => $id]]); + } + + private function restoreSnapshot(): void { + $logger = $this->logger(); + $body = read_json_body(); + $id = (int)($body['id'] ?? 0); + if ($id <= 0) { + Response::json(['ok' => false, 'error' => ['code' => 'ID_REQUIRED', 'message' => 'Snapshot id required']], 400); + return; + } + $this->settings()->restoreSnapshot($id); + $logger->log('warn', 'Settings snapshot restored', ['id' => $id]); + Response::json(['ok' => true]); + } + + private function deleteSnapshot(array $params): void { + $id = (int)($params['id'] ?? 0); + if ($id <= 0) { + Response::json(['ok' => false, 'error' => ['code' => 'ID_REQUIRED', 'message' => 'Snapshot id required']], 400); + return; + } + $this->settings()->deleteSnapshot($id); + Response::json(['ok' => true]); + } +} diff --git a/app/controllers/sources.php b/app/controllers/sources.php new file mode 100644 index 0000000..590ef34 --- /dev/null +++ b/app/controllers/sources.php @@ -0,0 +1,216 @@ +add('POST', '/api/sources/list', fn() => $self->listSources()); + $router->add('GET', '/api/sources/detail', fn() => $self->getDetail()); + $router->add('POST', '/api/sources/test', fn() => $self->testSource()); + $router->add('GET', '/api/sources/preview', fn() => $self->getPreview()); + $router->add('POST', '/api/sources/approve', fn() => $self->approveSource()); + } + + private function listSources(): void { + /** @var SourcesService $sources */ + $sources = $this->services()['sources']; + [$page, $perPage, $sort, $dir, $filters] = table_body_params(50, 500); + $items = $sources->list(); + $items = apply_filters_array($items, $filters, [ + 'source' => 'source', + 'type' => 'content_type', + 'name' => 'name', + 'size' => 'size_bytes', + 'status' => 'status', + 'progress' => fn($it) => (float)($it['percent_done'] ?? 0) * 100, + ]); + $sortMap = ['name' => 'name', 'size' => 'size_bytes', 'status' => 'status']; + $sortKey = $sortMap[$sort] ?? $sort; + if ($sortKey !== '') { + usort($items, function ($a, $b) use ($sortKey, $dir) { + $av = $a[$sortKey] ?? null; + $bv = $b[$sortKey] ?? null; + if ($av === $bv) return 0; + if (strtolower($dir) === 'desc') return ($av < $bv) ? 1 : -1; + return ($av < $bv) ? -1 : 1; + }); + } + [$slice, $total] = paginate_array($items, $page, $perPage); + Response::json(['ok' => true, 'data' => [ + 'items' => $slice, + 'total' => $total, + 'page' => $page, + 'per_page' => $perPage, + ]]); + } + + private function getDetail(): void { + $source = (string)($_GET['source'] ?? ''); + $id = (int)($_GET['id'] ?? 0); + if ($source === '' || $id <= 0) { + Response::json(['ok' => false, 'error' => ['code' => 'PARAMS_REQUIRED', 'message' => 'source and id required']], 400); + return; + } + + if ($source === 'transmission') { + /** @var TransmissionService $transmission */ + $transmission = $this->services()['transmission']; + $settings = $this->settings(); + $res = $transmission->detail($id); + if (empty($res['ok'])) { + Response::json(['ok' => false, 'error' => ['code' => 'SOURCE_FAILED', 'message' => $res['error'] ?? 'failed']], 400); + return; + } + $all = $settings->getAll(); + $sources = $all['sources'] ?? []; + $cfg = is_array($sources['transmission'] ?? null) ? $sources['transmission'] : []; + $display = is_array($cfg['display_fields'] ?? null) ? $cfg['display_fields'] : []; + if (count($display) > 0) { + $res['fields'] = array_values(array_filter($res['fields'] ?? [], function ($f) use ($display) { + $key = (string)($f['key'] ?? ''); + return $key !== '' && in_array($key, $display, true); + })); + } + Response::json(['ok' => true, 'data' => [ + 'core' => $res['core'] ?? [], + 'fields' => $res['fields'] ?? [], + 'files' => $res['files'] ?? [], + 'preview' => $this->buildTransmissionPreview($res), + 'raw' => $res['raw'] ?? null, + ]]); + return; + } + + Response::json(['ok' => false, 'error' => ['code' => 'UNKNOWN_SOURCE', 'message' => 'unknown source']], 400); + } + + private function testSource(): void { + /** @var TransmissionService $transmission */ + $transmission = $this->services()['transmission']; + $logger = $this->logger(); + $body = read_json_body(); + $cfg = is_array($body['transmission'] ?? null) ? $body['transmission'] : []; + try { + $res = $transmission->test($cfg); + if (empty($res['ok'])) { + $logger->log('warn', 'Transmission test failed', ['error' => $res['error'] ?? 'failed']); + Response::json(['ok' => false, 'error' => ['code' => 'TEST_FAILED', 'message' => $res['error'] ?? 'failed']], 400); + return; + } + $logger->log('info', 'Transmission test ok'); + Response::json(['ok' => true]); + } catch (Throwable $e) { + $logger->log('error', 'Transmission test exception', ['error' => $e->getMessage()]); + Response::json(['ok' => false, 'error' => ['code' => 'TEST_EXCEPTION', 'message' => $e->getMessage()]], 500); + } + } + + private function getPreview(): void { + $source = (string)($_GET['source'] ?? ''); + $id = (int)($_GET['id'] ?? 0); + if ($source === '' || $id <= 0) { + Response::json(['ok' => false, 'error' => ['code' => 'PARAMS_REQUIRED', 'message' => 'source and id required']], 400); + return; + } + + if ($source === 'transmission') { + /** @var TransmissionService $transmission */ + $transmission = $this->services()['transmission']; + $detail = $transmission->detail($id); + if (empty($detail['ok'])) { + Response::json(['ok' => false, 'error' => ['code' => 'SOURCE_FAILED', 'message' => $detail['error'] ?? 'failed']], 400); + return; + } + $preview = $this->buildTransmissionPreview($detail); + Response::json(['ok' => true, 'data' => $preview]); + return; + } + + Response::json(['ok' => false, 'error' => ['code' => 'UNKNOWN_SOURCE', 'message' => 'unknown source']], 400); + } + + private function approveSource(): void { + $body = read_json_body(); + $source = (string)($body['source'] ?? ''); + $id = (int)($body['id'] ?? 0); + if ($source === '' || $id <= 0) { + Response::json(['ok' => false, 'error' => ['code' => 'PARAMS_REQUIRED', 'message' => 'source and id required']], 400); + return; + } + /** @var \ScMedia\Services\JobsService $jobs */ + $jobs = $this->services()['jobs']; + $logger = $this->logger(); + $payload = ['source' => $source, 'id' => $id]; + $jobId = $jobs->create('task', "Source approve: {$source} #{$id}", $payload); + $logger->log('info', 'Source approved', ['source' => $source, 'id' => $id, 'job_id' => $jobId]); + Response::json(['ok' => true, 'data' => ['job_id' => $jobId]]); + } + + private function buildTransmissionPreview(array $detail): array { + $core = $detail['core'] ?? []; + $files = is_array($detail['files'] ?? null) ? $detail['files'] : []; + $typeInfo = $this->detectSourceType($files); + $episodes = $this->detectSeriesEpisodes($files); + $current = [ + 'name' => (string)($core['name'] ?? ''), + 'kind' => $typeInfo['kind'], + 'structure' => $typeInfo['structure'], + 'file_count' => count($files), + 'size_bytes' => (int)($core['size_bytes'] ?? 0), + 'episodes' => $episodes, + ]; + $planned = $current; + $planned['note'] = 'Pending rules'; + return ['current' => $current, 'planned' => $planned]; + } + + private function detectSourceType(array $files): array { + $structure = 'file'; + $kind = 'movie'; + $hasVideoTs = false; + $hasBdmv = false; + foreach ($files as $f) { + $path = (string)($f['path'] ?? ''); + if ($path === '') continue; + if (stripos($path, 'VIDEO_TS/') !== false || stripos($path, '/VIDEO_TS/') !== false) $hasVideoTs = true; + if (stripos($path, 'BDMV/') !== false || stripos($path, '/BDMV/') !== false) $hasBdmv = true; + } + if ($hasBdmv) { + $structure = 'bluray'; + } elseif ($hasVideoTs) { + $structure = 'dvd'; + } elseif (count($files) > 1) { + $structure = 'folder'; + } + + $episodes = $this->detectSeriesEpisodes($files); + if (count($episodes) > 0) { + $kind = 'series'; + } + + return ['structure' => $structure, 'kind' => $kind]; + } + + private function detectSeriesEpisodes(array $files): array { + $out = []; + foreach ($files as $f) { + $path = (string)($f['path'] ?? ''); + if ($path === '') continue; + if (preg_match('/S(\\d{1,2})E(\\d{1,2})/i', $path, $m)) { + $season = (int)$m[1]; + $episode = (int)$m[2]; + $key = sprintf('S%02dE%02d', $season, $episode); + $out[$key] = ['season' => $season, 'episode' => $episode]; + } + } + ksort($out); + return array_values($out); + } +} diff --git a/app/controllers/tasks.php b/app/controllers/tasks.php new file mode 100644 index 0000000..59c1e0c --- /dev/null +++ b/app/controllers/tasks.php @@ -0,0 +1,158 @@ +add('POST', '/api/tasks/pending/list', fn() => $self->listPending()); + $router->add('POST', '/api/tasks/pending', fn() => $self->savePending()); + $router->add('POST', '/api/tasks/pending/delete', fn() => $self->deletePending()); + $router->add('POST', '/api/tasks/approve', fn() => $self->approvePending()); + $router->add('POST', '/api/tasks/list', fn() => $self->listTasks()); + $router->add('POST', '/api/tasks/run', fn() => $self->runTask()); + } + + private function listPending(): void { + $settings = $this->settings(); + [$page, $perPage, $sort, $dir, $filters] = table_body_params(50, 200); + $data = $settings->getAll(); + $pending = is_array($data['pending_tasks'] ?? null) ? $data['pending_tasks'] : []; + $items = array_values(array_filter($pending, fn($t) => is_array($t))); + $items = apply_filters_array($items, $filters, [ + 'name' => 'name', + 'type' => 'type', + 'status' => 'status', + ]); + [$slice, $total] = paginate_array($items, $page, $perPage); + json_response(['ok' => true, 'data' => [ + 'items' => $slice, + 'total' => $total, + 'page' => $page, + 'per_page' => $perPage, + ]]); + } + + private function savePending(): void { + $settings = $this->settings(); + $body = read_json_body(); + $task = is_array($body['task'] ?? null) ? $body['task'] : null; + if (!$task) { + json_response(['ok' => false, 'error' => 'task required'], 400); + } + $id = (string)($task['id'] ?? ''); + if ($id === '') { + $id = 'pending_' . time() . '_' . bin2hex(random_bytes(2)); + $task['id'] = $id; + } + $data = $settings->getAll(); + $pending = is_array($data['pending_tasks'] ?? null) ? $data['pending_tasks'] : []; + $pending = array_values(array_filter($pending, fn($t) => is_array($t))); + $pending = array_values(array_filter($pending, fn($t) => (string)($t['id'] ?? '') !== $id)); + $pending[] = $task; + $settings->saveBulk(['pending_tasks' => $pending]); + json_response(['ok' => true, 'data' => ['id' => $id]]); + } + + private function deletePending(): void { + $settings = $this->settings(); + $body = read_json_body(); + $id = (string)($body['id'] ?? ''); + if ($id === '') { + json_response(['ok' => false, 'error' => 'id required'], 400); + } + $data = $settings->getAll(); + $pending = is_array($data['pending_tasks'] ?? null) ? $data['pending_tasks'] : []; + $pending = array_values(array_filter($pending, fn($t) => (string)($t['id'] ?? '') !== $id)); + $settings->saveBulk(['pending_tasks' => $pending]); + json_response(['ok' => true, 'data' => ['id' => $id]]); + } + + private function approvePending(): void { + $settings = $this->settings(); + $body = read_json_body(); + $id = (string)($body['id'] ?? ''); + if ($id === '') { + json_response(['ok' => false, 'error' => 'id required'], 400); + } + $data = $settings->getAll(); + $pending = is_array($data['pending_tasks'] ?? null) ? $data['pending_tasks'] : []; + $tasks = is_array($data['tasks'] ?? null) ? $data['tasks'] : []; + $task = null; + $pending = array_values(array_filter($pending, function($t) use ($id, &$task) { + if ((string)($t['id'] ?? '') === $id) { + $task = $t; + return false; + } + return true; + })); + if (!$task) { + json_response(['ok' => false, 'error' => 'task not found'], 404); + } + $tasks[] = $task; + $settings->saveBulk(['pending_tasks' => $pending, 'tasks' => $tasks]); + json_response(['ok' => true, 'data' => ['id' => $id]]); + } + + private function listTasks(): void { + $settings = $this->settings(); + $data = $settings->getAll(); + [$page, $perPage] = table_body_params(50, 200); + $tasks = is_array($data['tasks'] ?? null) ? $data['tasks'] : []; + $out = []; + foreach ($tasks as $t) { + if (!is_array($t)) continue; + if (empty($t['enabled'])) continue; + $out[] = [ + 'id' => (string)($t['id'] ?? ''), + 'name' => (string)($t['name'] ?? ''), + 'sources' => is_array($t['sources'] ?? null) ? $t['sources'] : [], + 'actions' => is_array($t['actions'] ?? null) ? $t['actions'] : [], + 'enabled' => !empty($t['enabled']), + ]; + } + [$slice, $total] = paginate_array($out, $page, $perPage); + json_response(['ok' => true, 'data' => [ + 'items' => $slice, + 'total' => $total, + 'page' => $page, + 'per_page' => $perPage, + ]]); + } + + private function runTask(): void { + $settings = $this->settings(); + /** @var \ScMedia\Services\JobsService $jobs */ + $jobs = $this->services()['jobs']; + $body = read_json_body(); + $id = (string)($body['id'] ?? ''); + if ($id === '') { + json_response(['ok' => false, 'error' => 'id required'], 400); + } + + $data = $settings->getAll(); + $tasks = is_array($data['tasks'] ?? null) ? $data['tasks'] : []; + $task = null; + foreach ($tasks as $t) { + if (!is_array($t)) continue; + if ((string)($t['id'] ?? '') === $id) { + $task = $t; + break; + } + } + if (!$task) { + json_response(['ok' => false, 'error' => 'task not found'], 404); + } + + $title = 'Task: ' . (string)($task['name'] ?? $id); + $jobId = $jobs->create('task', $title, ['task_id' => $id]); + $jobs->start($jobId); + $jobs->log($jobId, 'info', 'Task execution queued'); + $jobs->log($jobId, 'warn', 'Task execution not wired to pipeline yet'); + $jobs->finish($jobId); + json_response(['ok' => true, 'data' => ['job_id' => $jobId]]); + } +} diff --git a/app/controllers/tools.php b/app/controllers/tools.php new file mode 100644 index 0000000..5107a86 --- /dev/null +++ b/app/controllers/tools.php @@ -0,0 +1,37 @@ +add('POST', '/api/tools/test-path', fn() => $self->testPath()); + $router->add('GET', '/api/tools/detect-binaries', fn() => $self->detectBinaries()); + } + + private function testPath(): void { + $logger = $this->logger(); + $body = read_json_body(); + $path = (string)($body['path'] ?? ''); + $checks = is_array($body['checks'] ?? null) ? $body['checks'] : ['exists','read','write','rename']; + $data = $this->services()['path_tool']->testPath($path, $checks); + $logger->log('info', 'Path test', ['path' => $path, 'checks' => $checks, 'results' => $data['results'] ?? null, 'notes' => $data['notes'] ?? null]); + Response::json(['ok' => true, 'data' => ['path' => $path] + $data]); + } + + private function detectBinaries(): void { + $logger = $this->logger(); + $shell = $this->services()['shell'] ?? null; + $bins = ['mkvmerge', 'mkvpropedit', 'ffmpeg']; + $out = []; + foreach ($bins as $b) { + $out[$b . '_path'] = ($shell instanceof \ScMedia\Services\ShellTool) ? $shell->which($b) : null; + } + $logger->log('info', 'Detect binaries', ['binaries' => $out]); + Response::json(['ok' => true, 'data' => $out]); + } +} diff --git a/app/db/Db.php b/app/db/Db.php new file mode 100644 index 0000000..fa237e8 --- /dev/null +++ b/app/db/Db.php @@ -0,0 +1,74 @@ +pdo = new PDO($dsn, $user, $pass, [ + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4", + ]); + } + + public function pdo(): PDO { + return $this->pdo; + } + + public function prepare(string $sql): \PDOStatement { + return $this->pdo->prepare($sql); + } + + public function query(string $sql): \PDOStatement { + return $this->pdo->query($sql); + } + + public function lastInsertId(): string { + return $this->pdo->lastInsertId(); + } + + public function fetchOne(string $sql, array $params = []): ?array { + $stmt = $this->pdo->prepare($sql); + $stmt->execute($params); + $row = $stmt->fetch(); + return $row === false ? null : $row; + } + + public function fetchAll(string $sql, array $params = []): array { + $stmt = $this->pdo->prepare($sql); + $stmt->execute($params); + return $stmt->fetchAll(); + } + + public function exec(string $sql, array $params = []): int { + $stmt = $this->pdo->prepare($sql); + $stmt->execute($params); + return $stmt->rowCount(); + } + + public function begin(): void { + $this->pdo->beginTransaction(); + } + + public function beginTransaction(): void { + $this->begin(); + } + + public function commit(): void { + $this->pdo->commit(); + } + + public function rollBack(): void { + if ($this->pdo->inTransaction()) { + $this->pdo->rollBack(); + } + } +} diff --git a/app/db/SchemaTool.php b/app/db/SchemaTool.php new file mode 100644 index 0000000..5cb2f19 --- /dev/null +++ b/app/db/SchemaTool.php @@ -0,0 +1,355 @@ +db = $db; + $this->schemaPath = $schemaPath; + } + + public function clearIndex(): void { + $this->db->begin(); + try { + $this->db->exec("DELETE FROM items"); + $this->db->exec("DELETE FROM jobs"); + $this->db->commit(); + } catch (Exception $e) { + $this->db->rollBack(); + throw $e; + } + } + + public function clearContent(): void { + $this->db->begin(); + try { + $this->db->exec("DELETE FROM media_metadata"); + $this->db->exec("DELETE FROM media_file_meta"); + $this->db->exec("DELETE FROM media_files"); + $this->db->exec("DELETE FROM items"); + $this->db->commit(); + } catch (Exception $e) { + $this->db->rollBack(); + throw $e; + } + } + + public function getContentStats(): array { + $files = $this->db->fetchOne("SELECT COUNT(*) AS c FROM media_files"); + $meta = $this->db->fetchOne("SELECT COUNT(*) AS c FROM media_metadata"); + $items = $this->db->fetchOne("SELECT COUNT(*) AS c FROM items"); + return [ + 'files' => (int)($files['c'] ?? 0), + 'meta' => (int)($meta['c'] ?? 0), + 'items' => (int)($items['c'] ?? 0), + ]; + } + + public function getDbStats(): array { + $rows = $this->db->fetchAll("SHOW TABLE STATUS"); + $tables = 0; + $size = 0; + foreach ($rows as $row) { + if (!isset($row['Name'])) continue; + $tables += 1; + $size += (int)($row['Data_length'] ?? 0) + (int)($row['Index_length'] ?? 0); + } + return [ + 'tables' => $tables, + 'size_bytes' => $size, + ]; + } + + public function getDbInfo(): array { + $row = $this->db->fetchOne("SELECT DATABASE() AS db_name, USER() AS user_name, CURRENT_USER() AS current_user_name"); + return [ + 'db_name' => (string)($row['db_name'] ?? ''), + 'user_name' => (string)($row['user_name'] ?? ''), + 'current_user' => (string)($row['current_user_name'] ?? ''), + ]; + } + + public function listTablesWithCounts(): array { + $rows = $this->db->fetchAll("SHOW TABLE STATUS"); + $out = []; + foreach ($rows as $row) { + $name = (string)($row['Name'] ?? ''); + if ($name === '') continue; + $out[] = [ + 'name' => $name, + 'rows' => (int)($row['Rows'] ?? 0), + ]; + } + return $out; + } + + public function fetchTableRows(string $table, int $limit = 50): array { + $table = trim($table); + if ($table === '') { + throw new Exception('Table required'); + } + $tables = $this->listTableNames(); + if (!in_array($table, $tables, true)) { + throw new Exception('Unknown table'); + } + $limit = max(1, min(500, (int)$limit)); + $escaped = $this->escapeIdentifier($table); + $rows = $this->db->fetchAll("SELECT * FROM {$escaped} LIMIT {$limit}"); + return [ + 'name' => $table, + 'rows' => $rows, + ]; + } + + public function dumpDatabase(): string { + $rows = $this->db->fetchAll(" + SELECT table_name + FROM information_schema.tables + WHERE table_schema = DATABASE() + AND table_type = 'BASE TABLE' + ORDER BY table_name + "); + + $tables = array_map(fn($r) => (string)$r['table_name'], $rows); + $out = "-- scMedia database dump\n"; + $out .= "SET FOREIGN_KEY_CHECKS=0;\n\n"; + + foreach ($tables as $table) { + $escaped = "`" . str_replace("`", "``", $table) . "`"; + $create = $this->db->fetchOne("SHOW CREATE TABLE {$escaped}"); + $ddl = $create['Create Table'] ?? ''; + if ($ddl === '') { + continue; + } + $out .= "DROP TABLE IF EXISTS {$escaped};\n"; + $out .= $ddl . ";\n"; + + $data = $this->db->fetchAll("SELECT * FROM {$escaped}"); + if (count($data) > 0) { + $cols = array_keys($data[0]); + $colList = implode(', ', array_map(fn($c) => "`" . str_replace("`", "``", $c) . "`", $cols)); + foreach ($data as $row) { + $values = []; + foreach ($cols as $col) { + $values[] = $this->quoteValue($row[$col] ?? null); + } + $out .= "INSERT INTO {$escaped} ({$colList}) VALUES (" . implode(', ', $values) . ");\n"; + } + } + + $out .= "\n"; + } + + $out .= "SET FOREIGN_KEY_CHECKS=1;\n"; + return $out; + } + + private function listTableNames(): array { + $rows = $this->db->fetchAll("SHOW TABLES"); + $out = []; + foreach ($rows as $row) { + $vals = array_values($row); + $name = (string)($vals[0] ?? ''); + if ($name !== '') $out[] = $name; + } + return $out; + } + + private function escapeIdentifier(string $name): string { + return '`' . str_replace('`', '``', $name) . '`'; + } + + public function restoreDatabaseFromSql(string $sql): array { + $log = []; + $log[] = "Restore DB: dropping all tables in current database..."; + $this->dropAllTables($log); + + $log[] = "Restore DB: importing dump..."; + $this->importSql($sql, $log); + + $log[] = "Restore DB: done."; + return $log; + } + + public function resetDatabase(): array { + $log = []; + + $log[] = "Reset DB: dropping all tables in current database..."; + $this->dropAllTables($log); + + $log[] = "Reset DB: importing schema.sql..."; + $this->importSchema($log); + + $log[] = "Reset DB: done."; + return $log; + } + + public function applySchema(): array { + $log = []; + $log[] = "Apply schema: importing schema.sql..."; + $this->importSchema($log); + $log[] = "Apply schema: done."; + return $log; + } + + private function dropAllTables(array &$log): void { + $this->db->exec("SET FOREIGN_KEY_CHECKS=0"); + + $rows = $this->db->fetchAll(" + SELECT table_name + FROM information_schema.tables + WHERE table_schema = DATABASE() + AND table_type = 'BASE TABLE' + "); + + if (count($rows) === 0) { + $log[] = "No tables found. Nothing to drop."; + $this->db->exec("SET FOREIGN_KEY_CHECKS=1"); + return; + } + + $tables = []; + foreach ($rows as $r) { + $tables[] = "`" . str_replace("`", "``", (string)$r['table_name']) . "`"; + } + + $sql = "DROP TABLE IF EXISTS " . implode(", ", $tables); + $this->db->exec($sql); + + $this->db->exec("SET FOREIGN_KEY_CHECKS=1"); + $log[] = "Dropped " . count($tables) . " tables."; + } + + protected function importSchema(array &$log): void { + if (!is_file($this->schemaPath)) { + throw new Exception("schema.sql not found: " . $this->schemaPath); + } + + $sql = file_get_contents($this->schemaPath); + if ($sql === false) { + throw new Exception("Failed to read schema.sql"); + } + + $this->importSql($sql, $log); + } + + private function splitSqlStatements(string $sql): array { + // Simple splitter: handles -- comments and /* */ comments reasonably well. + // Does not support DELIMITER blocks (we don't use them). + $out = []; + $len = strlen($sql); + $buf = ''; + $inString = false; + $stringChar = ''; + $inLineComment = false; + $inBlockComment = false; + + for ($i = 0; $i < $len; $i++) { + $ch = $sql[$i]; + $next = ($i + 1 < $len) ? $sql[$i + 1] : ''; + + if ($inLineComment) { + if ($ch === "\n") { + $inLineComment = false; + } + continue; + } + + if ($inBlockComment) { + if ($ch === '*' && $next === '/') { + $inBlockComment = false; + $i++; + } + continue; + } + + if (!$inString) { + if ($ch === '-' && $next === '-') { + $inLineComment = true; + $i++; + continue; + } + if ($ch === '/' && $next === '*') { + $inBlockComment = true; + $i++; + continue; + } + } + + if ($inString) { + $buf .= $ch; + if ($ch === $stringChar) { + // Handle escaped quotes: '' or \" not fully, but good enough for schema.sql + $prev = ($i > 0) ? $sql[$i - 1] : ''; + if ($prev !== '\\') { + $inString = false; + $stringChar = ''; + } + } + continue; + } + + if ($ch === '\'' || $ch === '"') { + $inString = true; + $stringChar = $ch; + $buf .= $ch; + continue; + } + + if ($ch === ';') { + $out[] = $buf; + $buf = ''; + continue; + } + + $buf .= $ch; + } + + if (trim($buf) !== '') { + $out[] = $buf; + } + + return $out; + } + + private function importSql(string $sql, array &$log): void { + $statements = $this->splitSqlStatements($sql); + $log[] = "Statements: " . count($statements); + + foreach ($statements as $i => $stmt) { + $trim = trim($stmt); + if ($trim === '') { + continue; + } + + try { + $this->db->pdo()->exec($trim); + } catch (Exception $e) { + $log[] = "ERROR at statement #" . ($i + 1) . ": " . $e->getMessage(); + $log[] = "Statement: " . mb_substr($trim, 0, 5000); + throw $e; + } + } + } + + private function quoteValue($value): string { + if ($value === null) { + return 'NULL'; + } + if (is_bool($value)) { + return $value ? '1' : '0'; + } + if (is_int($value) || is_float($value)) { + return (string)$value; + } + return $this->db->pdo()->quote((string)$value); + } +} diff --git a/app/http/Response.php b/app/http/Response.php new file mode 100644 index 0000000..b473ed9 --- /dev/null +++ b/app/http/Response.php @@ -0,0 +1,58 @@ +routes[] = ['GET', $path, $handler]; + } + + public function post(string $path, callable $handler): void { + $this->routes[] = ['POST', $path, $handler]; + } + + public function put(string $path, callable $handler): void { + $this->routes[] = ['PUT', $path, $handler]; + } + + public function delete(string $path, callable $handler): void { + $this->routes[] = ['DELETE', $path, $handler]; + } + + public function add(string $method, string $path, callable $handler): void { + $method = strtoupper($method); + $allowed = ['GET', 'POST', 'PUT', 'DELETE']; + if (!in_array($method, $allowed, true)) { + throw new \InvalidArgumentException("Unsupported method: {$method}"); + } + $this->routes[] = [$method, $path, $handler]; + } + + public function dispatch(string $method, string $uriPath): void { + foreach ($this->routes as $r) { + [$m, $p, $h] = $r; + if ($m !== $method) { + continue; + } + $params = $this->match($p, $uriPath); + if ($params === null) { + continue; + } + $h($params); + return; + } + + if (str_starts_with($uriPath, '/api/')) { + Response::json([ + 'ok' => false, + 'error' => [ + 'code' => 'NOT_FOUND', + 'message' => 'Route not found', + ], + ], 404); + return; + } + Response::html('

404

', 404); + } + + private function match(string $pattern, string $path): ?array { + // Pattern supports: /api/scan-profiles/{id} + $pParts = explode('/', trim($pattern, '/')); + $uParts = explode('/', trim($path, '/')); + + if (count($pParts) !== count($uParts)) { + return null; + } + + $params = []; + for ($i = 0; $i < count($pParts); $i++) { + $pp = $pParts[$i]; + $up = $uParts[$i]; + + if (preg_match('/^\{([a-zA-Z0-9_]+)\}$/', $pp, $m)) { + $params[$m[1]] = $up; + continue; + } + + if ($pp !== $up) { + return null; + } + } + + return $params; + } +} diff --git a/app/http/helpers.php b/app/http/helpers.php new file mode 100644 index 0000000..2d30027 --- /dev/null +++ b/app/http/helpers.php @@ -0,0 +1,225 @@ + false, 'error' => ['code' => 'FORBIDDEN', 'message' => 'Debug tools disabled']], 403); + } + if ($dangerous) { + $allow = (bool)($config['app']['allow_db_reset'] ?? false); + if (!$allow) { + json_response(['ok' => false, 'error' => ['code' => 'FORBIDDEN', 'message' => 'DB reset disabled']], 403); + } + } +} + +function table_params(int $defaultPerPage = 50, int $maxPerPage = 500): array { + $page = isset($_GET['page']) ? (int)$_GET['page'] : 1; + $perPage = isset($_GET['per_page']) ? (int)$_GET['per_page'] : $defaultPerPage; + if ($page < 1) $page = 1; + if ($perPage < 1) $perPage = $defaultPerPage; + if ($perPage > $maxPerPage) $perPage = $maxPerPage; + $sort = isset($_GET['sort']) ? (string)$_GET['sort'] : ''; + $dir = isset($_GET['dir']) ? strtolower((string)$_GET['dir']) : 'asc'; + if (!in_array($dir, ['asc', 'desc'], true)) $dir = 'asc'; + return [$page, $perPage, $sort, $dir]; +} + +function table_body_params(int $defaultPerPage = 50, int $maxPerPage = 500): array { + $body = read_json_body(); + $page = isset($body['page']) ? (int)$body['page'] : 1; + $perPage = isset($body['per_page']) ? (int)$body['per_page'] : $defaultPerPage; + if ($page < 1) $page = 1; + if ($perPage < 1) $perPage = $defaultPerPage; + if ($perPage > $maxPerPage) $perPage = $maxPerPage; + $sort = isset($body['sort']) ? (string)$body['sort'] : ''; + $dir = isset($body['dir']) ? strtolower((string)$body['dir']) : 'asc'; + if (!in_array($dir, ['asc', 'desc'], true)) $dir = 'asc'; + $filters = is_array($body['filters'] ?? null) ? $body['filters'] : []; + $params = is_array($body['params'] ?? null) ? $body['params'] : []; + return [$page, $perPage, $sort, $dir, $filters, $params]; +} + +function find_filter(array $filters, string $key): ?array { + foreach ($filters as $filter) { + if (!is_array($filter)) continue; + if ((string)($filter['key'] ?? '') === $key) { + return $filter; + } + } + return null; +} + +function filter_value(array $filters, string $key) { + $filter = find_filter($filters, $key); + if (!$filter) return null; + return $filter['value'] ?? null; +} + +function filter_op(array $filters, string $key): string { + $filter = find_filter($filters, $key); + if (!$filter) return ''; + return (string)($filter['op'] ?? ''); +} + +function apply_filters_array(array $items, array $filters, array $fieldMap = []): array { + if (count($filters) === 0) return $items; + $out = []; + foreach ($items as $item) { + if (!is_array($item)) continue; + $ok = true; + foreach ($filters as $filter) { + if (!is_array($filter)) continue; + $key = (string)($filter['key'] ?? ''); + if ($key === '') continue; + $op = (string)($filter['op'] ?? 'eq'); + $value = $filter['value'] ?? null; + $field = $fieldMap[$key] ?? $key; + $current = null; + if (is_callable($field)) { + $current = $field($item); + } elseif (is_string($field)) { + $current = $item[$field] ?? null; + } + if (!filter_match($current, $op, $value)) { + $ok = false; + break; + } + } + if ($ok) $out[] = $item; + } + return $out; +} + +function filter_match($current, string $op, $value): bool { + $op = strtolower($op); + if ($op === 'empty') { + if (is_array($current)) return count($current) === 0; + return $current === null || $current === ''; + } + if ($op === 'in') { + if (!is_array($value)) return false; + return in_array($current, $value, true); + } + $cur = normalize_filter_scalar($current); + if ($op === 'like') { + $needle = strtolower((string)$value); + return $needle === '' ? true : (str_contains(strtolower((string)$cur), $needle)); + } + if ($op === 'between') { + if (!is_array($value) || count($value) < 2) return false; + [$from, $to] = $value; + $left = normalize_filter_scalar($from); + $right = normalize_filter_scalar($to); + if (is_numeric($cur) && is_numeric($left) && is_numeric($right)) { + return (float)$cur >= (float)$left && (float)$cur <= (float)$right; + } + $curTs = normalize_filter_timestamp($cur); + $fromTs = normalize_filter_timestamp($left); + $toTs = normalize_filter_timestamp($right); + if ($curTs !== null && $fromTs !== null && $toTs !== null) { + return $curTs >= $fromTs && $curTs <= $toTs; + } + return (string)$cur >= (string)$left && (string)$cur <= (string)$right; + } + if ($op === 'gt' || $op === 'lt') { + if (is_numeric($cur) && is_numeric($value)) { + return $op === 'gt' ? (float)$cur > (float)$value : (float)$cur < (float)$value; + } + return $op === 'gt' ? (string)$cur > (string)$value : (string)$cur < (string)$value; + } + $needle = normalize_filter_scalar($value); + if (is_string($cur) || is_string($needle)) { + return strtolower((string)$cur) === strtolower((string)$needle); + } + return $cur === $needle; +} + +function normalize_filter_scalar($value) { + if (is_array($value)) return ''; + if (is_bool($value)) return $value ? '1' : '0'; + return $value; +} + +function normalize_filter_timestamp($value): ?int { + if (!is_string($value)) return null; + $ts = strtotime($value); + if ($ts === false) return null; + return $ts; +} + +function paginate_array(array $items, int $page, int $perPage): array { + $total = count($items); + $start = ($page - 1) * $perPage; + $slice = array_slice($items, $start, $perPage); + return [$slice, $total]; +} + +function normalize_dates_in_array($data) { + if (!is_array($data)) return $data; + $out = []; + foreach ($data as $key => $value) { + if (is_array($value)) { + $out[$key] = normalize_dates_in_array($value); + continue; + } + if (is_string($value) && should_normalize_date_key((string)$key)) { + $normalized = normalize_datetime_string($value); + $out[$key] = $normalized ?? $value; + continue; + } + $out[$key] = $value; + } + return $out; +} + +function should_normalize_date_key(string $key): bool { + if ($key === 'ts') return true; + return preg_match('/(_at|_ts)$/', $key) === 1; +} + +function normalize_datetime_string(string $value): ?string { + $raw = trim($value); + if ($raw === '') return null; + + $tz = new DateTimeZone('UTC'); + + if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $raw)) { + $raw .= ' 00:00:00'; + } elseif (preg_match('/^\d{2}\.\d{2}\.\d{4}$/', $raw)) { + $parts = explode('.', $raw); + $raw = sprintf('%s-%s-%s 00:00:00', $parts[2], $parts[1], $parts[0]); + } elseif (preg_match('/^\d{2}\.\d{2}\.\d{4}\s+\d{2}:\d{2}:\d{2}$/', $raw)) { + [$datePart, $timePart] = explode(' ', $raw, 2); + $parts = explode('.', $datePart); + $raw = sprintf('%s-%s-%s %s', $parts[2], $parts[1], $parts[0], $timePart); + } + + try { + $dt = new DateTimeImmutable($raw, $tz); + } catch (Throwable $e) { + return null; + } + return $dt->setTimezone($tz)->format('Y-m-d H:i:s'); +} diff --git a/app/services/AuthService.php b/app/services/AuthService.php new file mode 100644 index 0000000..186c5ca --- /dev/null +++ b/app/services/AuthService.php @@ -0,0 +1,1145 @@ +db = $db; + $this->config = $config; + + $auth = $config['auth'] ?? []; + $this->jwtSecret = (string)($auth['jwt_secret'] ?? 'CHANGE_ME_JWT_SECRET'); + $this->accessTtl = (int)($auth['access_ttl_seconds'] ?? 900); + $this->refreshTtlWebDays = (int)($auth['refresh_ttl_web_days'] ?? 14); + $this->refreshTtlMobileDays = (int)($auth['refresh_ttl_mobile_days'] ?? 30); + $this->challengeTtl = (int)($auth['challenge_ttl_seconds'] ?? 300); + $this->passwordResetTtlMinutes = (int)($auth['password_reset_ttl_minutes'] ?? 30); + $this->maxDevices = (int)($auth['max_devices'] ?? 5); + $this->returnResetToken = (bool)($auth['return_reset_token'] ?? false); + $this->loginMax = (int)($auth['rate_limit_login_max'] ?? 10); + $this->loginWindow = (int)($auth['rate_limit_login_window'] ?? 900); + $this->loginBlock = (int)($auth['rate_limit_login_block'] ?? 900); + $this->mfaMax = (int)($auth['rate_limit_mfa_max'] ?? 6); + $this->mfaWindow = (int)($auth['rate_limit_mfa_window'] ?? 900); + $this->mfaBlock = (int)($auth['rate_limit_mfa_block'] ?? 900); + $this->sseKeyTtl = (int)($auth['sse_key_ttl_seconds'] ?? 90); + $this->sseSessionTtl = (int)($auth['sse_session_ttl_seconds'] ?? 20); + } + + public function setSseSessionTtl(int $seconds): void { + $this->sseSessionTtl = max(1, $seconds); + } + + public function requireAuth(?string $role = null): array { + $token = $this->readBearerToken(); + if ($token === '') { + Response::json(['ok' => false, 'error' => ['code' => 'UNAUTHORIZED', 'message' => 'Missing token']], 401); + exit; + } + + $claims = $this->verifyJwt($token); + if ($claims === null) { + Response::json(['ok' => false, 'error' => ['code' => 'UNAUTHORIZED', 'message' => 'Invalid token']], 401); + exit; + } + + $userId = (int)($claims['sub'] ?? 0); + if ($userId <= 0) { + Response::json(['ok' => false, 'error' => ['code' => 'UNAUTHORIZED', 'message' => 'Invalid token subject']], 401); + exit; + } + + $user = $this->db->fetchOne("SELECT id, email, status, token_version FROM users WHERE id = :id", [':id' => $userId]); + if (!$user || (string)($user['status'] ?? '') !== 'active') { + Response::json(['ok' => false, 'error' => ['code' => 'UNAUTHORIZED', 'message' => 'User disabled']], 401); + exit; + } + + $tokenVersion = (int)($claims['ver'] ?? 0); + if ($tokenVersion !== (int)($user['token_version'] ?? 0)) { + Response::json(['ok' => false, 'error' => ['code' => 'UNAUTHORIZED', 'message' => 'Token expired']], 401); + exit; + } + + $roles = $this->getUserRoles($userId); + if ($role !== null && !in_array($role, $roles, true)) { + Response::json(['ok' => false, 'error' => ['code' => 'FORBIDDEN', 'message' => 'Insufficient role']], 403); + exit; + } + + return [ + 'id' => $userId, + 'email' => (string)($user['email'] ?? ''), + 'roles' => $roles, + ]; + } + + public function requirePageAuth(?string $role = null): array { + $token = $this->readBearerToken(); + if ($token === '') { + $this->redirectToLogin(); + } + + $claims = $this->verifyJwt($token); + if ($claims === null) { + $this->redirectToLogin(); + } + + $userId = (int)($claims['sub'] ?? 0); + if ($userId <= 0) { + $this->redirectToLogin(); + } + + $user = $this->db->fetchOne("SELECT id, email, status, token_version FROM users WHERE id = :id", [':id' => $userId]); + if (!$user || (string)($user['status'] ?? '') !== 'active') { + $this->redirectToLogin(); + } + + $tokenVersion = (int)($claims['ver'] ?? 0); + if ($tokenVersion !== (int)($user['token_version'] ?? 0)) { + $this->redirectToLogin(); + } + + $roles = $this->getUserRoles($userId); + if ($role !== null && !in_array($role, $roles, true)) { + $this->redirectToLogin(); + } + + return [ + 'id' => (int)$user['id'], + 'email' => (string)$user['email'], + 'roles' => $roles, + ]; + } + + public function register(string $email, string $password): array { + $email = strtolower(trim($email)); + if ($email === '' || $password === '') { + return ['ok' => false, 'error' => 'Email and password required']; + } + + $exists = $this->db->fetchOne("SELECT id FROM users WHERE email = :e", [':e' => $email]); + if ($exists) { + return ['ok' => false, 'error' => 'User already exists']; + } + + $hash = password_hash($password, PASSWORD_DEFAULT); + $this->db->begin(); + try { + $this->db->exec(" + INSERT INTO users (email, password_hash, status, token_version, created_at, updated_at) + VALUES (:e, :h, 'active', 1, NOW(), NOW()) + ", [':e' => $email, ':h' => $hash]); + $userId = (int)$this->db->lastInsertId(); + + $role = $this->isFirstUser($userId) ? 'admin' : 'user'; + $this->assignRolesInternal($userId, [$role]); + + $this->audit('register', $userId, 'user', $userId, ['role' => $role]); + $this->db->commit(); + return ['ok' => true, 'user_id' => $userId, 'role' => $role]; + } catch (Throwable $e) { + $this->db->rollBack(); + return ['ok' => false, 'error' => $e->getMessage()]; + } + } + + public function login(string $email, string $password, string $clientType, string $deviceId = ''): array { + $blocked = $this->isRateLimited('login'); + if ($blocked > 0) { + return ['ok' => false, 'error' => 'Too many attempts', 'retry_after' => $blocked]; + } + $email = strtolower(trim($email)); + $user = $this->db->fetchOne("SELECT id, email, password_hash, status FROM users WHERE email = :e", [':e' => $email]); + if (!$user || (string)($user['status'] ?? '') !== 'active') { + $this->registerFailure('login'); + $this->audit('login_failed', null, 'user', null, ['email' => $email]); + return ['ok' => false, 'error' => 'Invalid credentials']; + } + + if (!password_verify($password, (string)($user['password_hash'] ?? ''))) { + $this->registerFailure('login'); + $this->audit('login_failed', (int)$user['id'], 'user', (int)$user['id'], ['reason' => 'bad_password']); + return ['ok' => false, 'error' => 'Invalid credentials']; + } + + $userId = (int)$user['id']; + $this->resetRateLimit('login'); + if ($this->isMfaEnabled($userId)) { + $challenge = $this->createLoginChallenge($userId); + $this->audit('login_mfa_required', $userId, 'user', $userId); + return ['ok' => true, 'mfa_required' => true, 'challenge_token' => $challenge]; + } + + $tokens = $this->issueTokens($userId, $clientType, $deviceId); + $this->db->exec("UPDATE users SET last_login_at = NOW() WHERE id = :id", [':id' => $userId]); + $this->audit('login', $userId, 'user', $userId); + return ['ok' => true, 'tokens' => $tokens]; + } + + public function verifyMfa(string $challengeToken, string $code, string $clientType, string $deviceId = ''): array { + $blocked = $this->isRateLimited('mfa'); + if ($blocked > 0) { + return ['ok' => false, 'error' => 'Too many attempts', 'retry_after' => $blocked]; + } + $challenge = $this->findChallenge($challengeToken); + if (!$challenge) { + $this->registerFailure('mfa'); + return ['ok' => false, 'error' => 'Invalid or expired challenge']; + } + + $userId = (int)$challenge['user_id']; + $valid = $this->verifyMfaCode($userId, $code); + if (!$valid) { + $this->registerFailure('mfa'); + $this->audit('mfa_failed', $userId, 'user', $userId); + return ['ok' => false, 'error' => 'Invalid code']; + } + + $this->resetRateLimit('mfa'); + $this->db->exec("UPDATE auth_challenges SET used_at = NOW() WHERE id = :id", [':id' => (int)$challenge['id']]); + $tokens = $this->issueTokens($userId, $clientType, $deviceId); + $this->db->exec("UPDATE users SET last_login_at = NOW() WHERE id = :id", [':id' => $userId]); + $this->audit('login', $userId, 'user', $userId, ['mfa' => true]); + return ['ok' => true, 'tokens' => $tokens]; + } + + public function refresh(string $refreshToken, string $clientType, string $deviceId = ''): array { + $tokenRow = $this->findRefreshToken($refreshToken); + if (!$tokenRow) { + return ['ok' => false, 'error' => 'Invalid refresh token']; + } + if (!empty($tokenRow['revoked_at'])) { + return ['ok' => false, 'error' => 'Refresh token revoked']; + } + $expiresAt = strtotime((string)($tokenRow['expires_at'] ?? '')); + if ($expiresAt !== false && $expiresAt <= time()) { + return ['ok' => false, 'error' => 'Refresh token expired']; + } + + $userId = (int)$tokenRow['user_id']; + $user = $this->db->fetchOne("SELECT id, status FROM users WHERE id = :id", [':id' => $userId]); + if (!$user || (string)($user['status'] ?? '') !== 'active') { + return ['ok' => false, 'error' => 'User disabled']; + } + + $this->db->exec("UPDATE refresh_tokens SET revoked_at = NOW() WHERE id = :id", [':id' => (int)$tokenRow['id']]); + $tokens = $this->issueTokens($userId, $clientType, $deviceId, (int)$tokenRow['id']); + $this->audit('refresh', $userId, 'user', $userId); + return ['ok' => true, 'tokens' => $tokens]; + } + + public function logout(string $refreshToken): array { + $tokenRow = $this->findRefreshToken($refreshToken); + if (!$tokenRow) { + return ['ok' => true]; + } + + $userId = (int)$tokenRow['user_id']; + $this->revokeUserSessions($userId); + $this->audit('logout', $userId, 'user', $userId); + return ['ok' => true]; + } + + public function logoutByAccessToken(string $accessToken): void { + $claims = $this->verifyJwt($accessToken); + if ($claims === null) { + return; + } + $userId = (int)($claims['sub'] ?? 0); + if ($userId <= 0) { + return; + } + $this->revokeUserSessions($userId); + $this->audit('logout', $userId, 'user', $userId); + } + + public function resolveUserLanguageFromToken(string $accessToken): ?string { + if ($accessToken === '') { + return null; + } + $claims = $this->verifyJwt($accessToken); + if ($claims === null) { + return null; + } + $userId = (int)($claims['sub'] ?? 0); + if ($userId <= 0) { + return null; + } + $user = $this->db->fetchOne("SELECT id, status, token_version FROM users WHERE id = :id", [':id' => $userId]); + if (!$user || (string)($user['status'] ?? '') !== 'active') { + return null; + } + $tokenVersion = (int)($claims['ver'] ?? 0); + if ($tokenVersion !== (int)($user['token_version'] ?? 0)) { + return null; + } + $row = $this->db->fetchOne("SELECT ui_prefs_json FROM user_profiles WHERE user_id = :id", [':id' => $userId]) ?? []; + $ui = json_decode((string)($row['ui_prefs_json'] ?? '{}'), true); + if (!is_array($ui)) { + return null; + } + $lang = (string)($ui['language'] ?? ''); + return preg_match('/^[a-z]{2}$/', $lang) ? $lang : null; + } + + public function setupMfa(int $userId): array { + $secret = $this->generateTotpSecret(); + $this->db->exec("DELETE FROM mfa_methods WHERE user_id = :id AND enabled_at IS NULL", [':id' => $userId]); + $this->db->exec(" + INSERT INTO mfa_methods (user_id, type, secret_enc, enabled_at, created_at) + VALUES (:uid, 'totp', :s, NULL, NOW()) + ", [':uid' => $userId, ':s' => $secret]); + + $issuer = (string)($this->config['app']['app_id'] ?? 'scmedia'); + $label = rawurlencode($issuer . ':' . $this->getUserEmail($userId)); + $otpauth = "otpauth://totp/{$label}?secret={$secret}&issuer=" . rawurlencode($issuer); + + $this->audit('mfa_setup', $userId, 'user', $userId); + return ['ok' => true, 'secret' => $secret, 'otpauth_url' => $otpauth]; + } + + public function confirmMfa(int $userId, string $code): array { + $method = $this->db->fetchOne(" + SELECT id, secret_enc + FROM mfa_methods + WHERE user_id = :uid AND enabled_at IS NULL AND type = 'totp' + ORDER BY id DESC + LIMIT 1 + ", [':uid' => $userId]); + if (!$method) { + return ['ok' => false, 'error' => 'No pending MFA setup']; + } + + $secret = (string)($method['secret_enc'] ?? ''); + if (!$this->verifyTotp($secret, $code)) { + return ['ok' => false, 'error' => 'Invalid code']; + } + + $this->db->exec("UPDATE mfa_methods SET enabled_at = NOW() WHERE id = :id", [':id' => (int)$method['id']]); + $codes = $this->generateBackupCodes($userId); + $this->audit('mfa_enabled', $userId, 'user', $userId); + return ['ok' => true, 'backup_codes' => $codes]; + } + + public function disableMfa(int $userId): array { + $this->db->begin(); + try { + $this->db->exec("DELETE FROM mfa_methods WHERE user_id = :uid", [':uid' => $userId]); + $this->db->exec("DELETE FROM mfa_backup_codes WHERE user_id = :uid", [':uid' => $userId]); + $this->db->commit(); + } catch (Throwable $e) { + $this->db->rollBack(); + return ['ok' => false, 'error' => $e->getMessage()]; + } + $this->invalidateUserSessions($userId, 'mfa_disabled'); + $this->audit('mfa_disabled', $userId, 'user', $userId); + return ['ok' => true]; + } + + public function passwordForgot(string $email): array { + $email = strtolower(trim($email)); + $user = $this->db->fetchOne("SELECT id FROM users WHERE email = :e", [':e' => $email]); + if (!$user) { + return ['ok' => true]; + } + + $token = $this->randomToken(32); + $hash = $this->hashToken($token); + $this->db->exec(" + INSERT INTO password_resets (user_id, token_hash, expires_at, created_at) + VALUES (:uid, :h, DATE_ADD(NOW(), INTERVAL :mins MINUTE), NOW()) + ", [':uid' => (int)$user['id'], ':h' => $hash, ':mins' => $this->passwordResetTtlMinutes]); + + $payload = ['ok' => true]; + if ($this->returnResetToken) { + $payload['reset_token'] = $token; + } + $this->audit('password_reset_requested', (int)$user['id'], 'user', (int)$user['id']); + return $payload; + } + + public function passwordReset(string $token, string $newPassword): array { + if ($token === '' || $newPassword === '') { + return ['ok' => false, 'error' => 'Token and password required']; + } + + $row = $this->findPasswordReset($token); + if (!$row) { + return ['ok' => false, 'error' => 'Invalid token']; + } + + $hash = password_hash($newPassword, PASSWORD_DEFAULT); + $userId = (int)$row['user_id']; + $this->db->begin(); + try { + $this->db->exec("UPDATE users SET password_hash = :h, password_changed_at = NOW(), token_version = token_version + 1 WHERE id = :id", [ + ':h' => $hash, + ':id' => $userId, + ]); + $this->db->exec("UPDATE password_resets SET used_at = NOW() WHERE id = :id", [':id' => (int)$row['id']]); + $this->db->exec("UPDATE refresh_tokens SET revoked_at = NOW() WHERE user_id = :uid AND revoked_at IS NULL", [':uid' => $userId]); + $this->db->commit(); + } catch (Throwable $e) { + $this->db->rollBack(); + return ['ok' => false, 'error' => $e->getMessage()]; + } + + $this->audit('password_reset', $userId, 'user', $userId); + return ['ok' => true]; + } + + public function changePassword(int $userId, string $currentPassword, string $newPassword): array { + if ($currentPassword === '' || $newPassword === '') { + return ['ok' => false, 'error' => 'Password required']; + } + $row = $this->db->fetchOne("SELECT password_hash FROM users WHERE id = :id", [':id' => $userId]); + if (!$row) { + return ['ok' => false, 'error' => 'User not found']; + } + if (!password_verify($currentPassword, (string)($row['password_hash'] ?? ''))) { + $this->audit('password_change_failed', $userId, 'user', $userId); + return ['ok' => false, 'error' => 'Invalid password']; + } + $hash = password_hash($newPassword, PASSWORD_DEFAULT); + $this->db->exec("UPDATE users SET password_hash = :h, password_changed_at = NOW(), token_version = token_version + 1 WHERE id = :id", [ + ':h' => $hash, + ':id' => $userId, + ]); + $this->audit('password_change', $userId, 'user', $userId); + return ['ok' => true]; + } + + public function changeEmail(int $userId, string $email): array { + $email = strtolower(trim($email)); + if ($email === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) { + return ['ok' => false, 'error' => 'Invalid email']; + } + $exists = $this->db->fetchOne("SELECT id FROM users WHERE email = :e AND id <> :id", [ + ':e' => $email, + ':id' => $userId, + ]); + if ($exists) { + return ['ok' => false, 'error' => 'Email already in use']; + } + $this->db->exec("UPDATE users SET email = :e, updated_at = NOW() WHERE id = :id", [ + ':e' => $email, + ':id' => $userId, + ]); + $this->audit('email_change', $userId, 'user', $userId, ['email' => $email]); + return ['ok' => true]; + } + + public function listUsers(): array { + return $this->db->fetchAll(" + SELECT u.id, u.email, u.status, u.last_login_at, u.created_at, + GROUP_CONCAT(r.name ORDER BY r.name SEPARATOR ',') AS roles + FROM users u + LEFT JOIN user_roles ur ON ur.user_id = u.id + LEFT JOIN roles r ON r.id = ur.role_id + GROUP BY u.id + ORDER BY u.id ASC + "); + } + + public function listRoles(): array { + return $this->db->fetchAll("SELECT id, name, description FROM roles ORDER BY id ASC"); + } + + public function listAudit(int $page, int $perPage): array { + if ($page < 1) $page = 1; + if ($perPage < 1) $perPage = 50; + if ($perPage > 500) $perPage = 500; + $offset = ($page - 1) * $perPage; + $items = $this->db->fetchAll(" + SELECT a.id, a.actor_user_id, u.email AS actor_email, a.action, a.target_type, + a.target_id, a.ip_addr, a.user_agent, a.meta_json, a.created_at + FROM audit_log a + LEFT JOIN users u ON u.id = a.actor_user_id + ORDER BY a.id DESC + LIMIT {$perPage} OFFSET {$offset} + "); + $totalRow = $this->db->fetchOne("SELECT COUNT(*) AS c FROM audit_log"); + return [ + 'items' => $items, + 'total' => (int)($totalRow['c'] ?? 0), + ]; + } + + public function listAuditFiltered(int $page, int $perPage, string $from = '', string $to = '', string $action = ''): array { + if ($page < 1) $page = 1; + if ($perPage < 1) $perPage = 50; + if ($perPage > 500) $perPage = 500; + $offset = ($page - 1) * $perPage; + + $where = []; + $params = []; + if ($from !== '' && $to !== '' && preg_match('/^\d{4}-\d{2}-\d{2}$/', $from) && preg_match('/^\d{4}-\d{2}-\d{2}$/', $to)) { + $where[] = "a.created_at >= :from AND a.created_at < DATE_ADD(:to, INTERVAL 1 DAY)"; + $params[':from'] = $from . ' 00:00:00'; + $params[':to'] = $to . ' 00:00:00'; + } + if ($action !== '') { + $where[] = "a.action = :action"; + $params[':action'] = $action; + } + $whereSql = count($where) > 0 ? ('WHERE ' . implode(' AND ', $where)) : ''; + + $items = $this->db->fetchAll(" + SELECT a.id, a.actor_user_id, u.email AS actor_email, a.action, a.target_type, + a.target_id, a.ip_addr, a.user_agent, a.meta_json, a.created_at + FROM audit_log a + LEFT JOIN users u ON u.id = a.actor_user_id + {$whereSql} + ORDER BY a.id DESC + LIMIT {$perPage} OFFSET {$offset} + ", $params); + $totalRow = $this->db->fetchOne("SELECT COUNT(*) AS c FROM audit_log {$whereSql}", $params); + return [ + 'items' => $items, + 'total' => (int)($totalRow['c'] ?? 0), + ]; + } + + public function setUserRoles(int $actorId, int $userId, array $roles): array { + $roles = array_values(array_filter(array_map('trim', $roles))); + if (count($roles) === 0) { + return ['ok' => false, 'error' => 'Roles required']; + } + + $this->db->begin(); + try { + $this->db->exec("DELETE FROM user_roles WHERE user_id = :uid", [':uid' => $userId]); + $this->assignRolesInternal($userId, $roles); + $this->db->exec("UPDATE users SET token_version = token_version + 1 WHERE id = :id", [':id' => $userId]); + $this->db->exec("UPDATE refresh_tokens SET revoked_at = NOW() WHERE user_id = :uid AND revoked_at IS NULL", [':uid' => $userId]); + $this->db->commit(); + } catch (Throwable $e) { + $this->db->rollBack(); + return ['ok' => false, 'error' => $e->getMessage()]; + } + + $this->audit('roles_changed', $actorId, 'user', $userId, ['roles' => $roles]); + return ['ok' => true]; + } + + public function disableUser(int $actorId, int $userId, bool $disabled): array { + if ($disabled) { + $isAdmin = $this->db->fetchOne(" + SELECT 1 + FROM user_roles ur + JOIN roles r ON r.id = ur.role_id + WHERE ur.user_id = :uid AND r.name = 'admin' + LIMIT 1 + ", [':uid' => $userId]); + if ($isAdmin) { + $row = $this->db->fetchOne(" + SELECT COUNT(*) AS c + FROM users u + JOIN user_roles ur ON ur.user_id = u.id + JOIN roles r ON r.id = ur.role_id + WHERE r.name = 'admin' AND u.status = 'active' + "); + $admins = (int)($row['c'] ?? 0); + if ($admins <= 1) { + return ['ok' => false, 'error' => 'Cannot disable last admin']; + } + } + } + $status = $disabled ? 'disabled' : 'active'; + $this->db->exec("UPDATE users SET status = :s WHERE id = :id", [':s' => $status, ':id' => $userId]); + $this->invalidateUserSessions($userId, 'user_disabled'); + $this->audit($disabled ? 'user_disabled' : 'user_enabled', $actorId, 'user', $userId); + return ['ok' => true]; + } + + public function resetUserMfa(int $actorId, int $userId): array { + $this->db->begin(); + try { + $this->db->exec("DELETE FROM mfa_methods WHERE user_id = :uid", [':uid' => $userId]); + $this->db->exec("DELETE FROM mfa_backup_codes WHERE user_id = :uid", [':uid' => $userId]); + $this->db->commit(); + } catch (Throwable $e) { + $this->db->rollBack(); + return ['ok' => false, 'error' => $e->getMessage()]; + } + $this->invalidateUserSessions($userId, 'mfa_reset'); + $this->audit('mfa_reset', $actorId, 'user', $userId); + return ['ok' => true]; + } + + public function issueSseKey(int $userId): array { + $key = $this->randomToken(24); + $hash = $this->hashToken($key); + $this->db->exec(" + INSERT INTO auth_sse_keys (user_id, key_hash, expires_at, created_at) + VALUES (:uid, :h, DATE_ADD(NOW(), INTERVAL :ttl SECOND), NOW()) + ", [ + ':uid' => $userId, + ':h' => $hash, + ':ttl' => $this->sseKeyTtl, + ]); + return ['key' => $key, 'expires_in' => $this->sseKeyTtl]; + } + + public function validateSseKey(string $key): ?int { + if ($key === '') { + return null; + } + $hash = $this->hashToken($key); + $row = $this->db->fetchOne(" + SELECT user_id + FROM auth_sse_keys + WHERE key_hash = :h AND expires_at > NOW() + LIMIT 1 + ", [':h' => $hash]); + if (!$row) { + return null; + } + return (int)($row['user_id'] ?? 0); + } + + public function startSseSession(int $userId): string { + $existing = $this->db->fetchOne(" + SELECT session_token, updated_at + FROM auth_sse_sessions + WHERE user_id = :uid + LIMIT 1 + ", [':uid' => $userId]); + if ($existing && $this->isRecentSseUpdate($existing['updated_at'] ?? null)) { + return (string)($existing['session_token'] ?? ''); + } + $token = $this->hashToken($this->randomToken(24)); + $this->db->exec(" + INSERT INTO auth_sse_sessions (user_id, session_token, updated_at) + VALUES (:uid, :token, NOW()) + ON DUPLICATE KEY UPDATE session_token = VALUES(session_token), updated_at = NOW() + ", [ + ':uid' => $userId, + ':token' => $token, + ]); + return $token; + } + + public function isSseSessionActive(int $userId, string $token): bool { + $row = $this->db->fetchOne(" + SELECT session_token, updated_at + FROM auth_sse_sessions + WHERE user_id = :uid + LIMIT 1 + ", [':uid' => $userId]); + if (!$row) return false; + if (!hash_equals((string)$row['session_token'], $token)) { + return false; + } + return $this->isRecentSseUpdate($row['updated_at'] ?? null); + } + + public function touchSseSession(int $userId, string $token): void { + $this->db->exec(" + UPDATE auth_sse_sessions + SET updated_at = NOW() + WHERE user_id = :uid AND session_token = :token + ", [ + ':uid' => $userId, + ':token' => $token, + ]); + } + + private function isRecentSseUpdate(?string $updatedAt): bool { + if (!$updatedAt) return false; + $ts = strtotime($updatedAt); + if ($ts === false) return false; + return (time() - $ts) <= $this->sseSessionTtl; + } + + private function issueTokens(int $userId, string $clientType, string $deviceId = '', int $rotatedFromId = 0): array { + $roles = $this->getUserRoles($userId); + $user = $this->db->fetchOne("SELECT token_version FROM users WHERE id = :id", [':id' => $userId]); + $tokenVersion = (int)($user['token_version'] ?? 1); + $now = time(); + $payload = [ + 'sub' => $userId, + 'roles' => $roles, + 'ver' => $tokenVersion, + 'iat' => $now, + 'exp' => $now + $this->accessTtl, + 'jti' => $this->randomToken(16), + ]; + + $access = $this->signJwt($payload); + $refresh = $this->randomToken(32); + $refreshHash = $this->hashToken($refresh); + $deviceId = $deviceId !== '' ? $deviceId : $this->randomToken(12); + $ttlDays = ($clientType === 'mobile') ? $this->refreshTtlMobileDays : $this->refreshTtlWebDays; + + $this->db->exec(" + INSERT INTO refresh_tokens (user_id, device_id, token_hash, user_agent, ip_addr, expires_at, rotated_from_id, created_at) + VALUES (:uid, :did, :h, :ua, :ip, DATE_ADD(NOW(), INTERVAL :days DAY), :rf, NOW()) + ", [ + ':uid' => $userId, + ':did' => $deviceId, + ':h' => $refreshHash, + ':ua' => $this->getUserAgent(), + ':ip' => $this->getIpAddress(), + ':days' => $ttlDays, + ':rf' => $rotatedFromId > 0 ? $rotatedFromId : null, + ]); + + $this->enforceDeviceLimit($userId); + + return [ + 'access_token' => $access, + 'refresh_token' => $refresh, + 'expires_in' => $this->accessTtl, + 'token_type' => 'Bearer', + ]; + } + + private function enforceDeviceLimit(int $userId): void { + $rows = $this->db->fetchAll(" + SELECT id + FROM refresh_tokens + WHERE user_id = :uid AND revoked_at IS NULL AND expires_at > NOW() + ORDER BY created_at ASC + ", [':uid' => $userId]); + + $extra = count($rows) - $this->maxDevices; + if ($extra <= 0) { + return; + } + + $ids = array_slice(array_map(fn($r) => (int)$r['id'], $rows), 0, $extra); + if (count($ids) > 0) { + $placeholders = implode(',', array_fill(0, count($ids), '?')); + $this->db->exec("UPDATE refresh_tokens SET revoked_at = NOW() WHERE id IN ({$placeholders})", $ids); + } + } + + private function createLoginChallenge(int $userId): string { + $token = $this->randomToken(24); + $hash = $this->hashToken($token); + $this->db->exec(" + INSERT INTO auth_challenges (user_id, token_hash, expires_at, created_at) + VALUES (:uid, :h, DATE_ADD(NOW(), INTERVAL :ttl SECOND), NOW()) + ", [':uid' => $userId, ':h' => $hash, ':ttl' => $this->challengeTtl]); + return $token; + } + + private function findChallenge(string $token): ?array { + if ($token === '') { + return null; + } + $hash = $this->hashToken($token); + return $this->db->fetchOne(" + SELECT id, user_id + FROM auth_challenges + WHERE token_hash = :h AND used_at IS NULL AND expires_at > NOW() + ORDER BY id DESC + LIMIT 1 + ", [':h' => $hash]); + } + + private function findRefreshToken(string $token): ?array { + if ($token === '') { + return null; + } + $hash = $this->hashToken($token); + return $this->db->fetchOne(" + SELECT id, user_id, expires_at, revoked_at + FROM refresh_tokens + WHERE token_hash = :h + LIMIT 1 + ", [':h' => $hash]); + } + + private function findPasswordReset(string $token): ?array { + $hash = $this->hashToken($token); + return $this->db->fetchOne(" + SELECT id, user_id + FROM password_resets + WHERE token_hash = :h AND used_at IS NULL AND expires_at > NOW() + LIMIT 1 + ", [':h' => $hash]); + } + + private function getUserRoles(int $userId): array { + $rows = $this->db->fetchAll(" + SELECT r.name + FROM roles r + INNER JOIN user_roles ur ON ur.role_id = r.id + WHERE ur.user_id = :uid + ", [':uid' => $userId]); + return array_values(array_filter(array_map(fn($r) => (string)$r['name'], $rows))); + } + + private function assignRolesInternal(int $userId, array $roles): void { + foreach ($roles as $role) { + $row = $this->db->fetchOne("SELECT id FROM roles WHERE name = :n", [':n' => $role]); + if (!$row) { + continue; + } + $this->db->exec("INSERT IGNORE INTO user_roles (user_id, role_id) VALUES (:u, :r)", [ + ':u' => $userId, + ':r' => (int)$row['id'], + ]); + } + } + + private function isMfaEnabled(int $userId): bool { + $row = $this->db->fetchOne("SELECT id FROM mfa_methods WHERE user_id = :uid AND enabled_at IS NOT NULL LIMIT 1", [':uid' => $userId]); + return (bool)$row; + } + + private function verifyMfaCode(int $userId, string $code): bool { + $code = trim($code); + if ($code === '') { + return false; + } + + $method = $this->db->fetchOne(" + SELECT secret_enc + FROM mfa_methods + WHERE user_id = :uid AND enabled_at IS NOT NULL AND type = 'totp' + ORDER BY id DESC LIMIT 1 + ", [':uid' => $userId]); + if ($method) { + $secret = (string)($method['secret_enc'] ?? ''); + if ($this->verifyTotp($secret, $code)) { + return true; + } + } + + $hash = $this->hashToken($code); + $row = $this->db->fetchOne(" + SELECT id + FROM mfa_backup_codes + WHERE user_id = :uid AND code_hash = :h AND used_at IS NULL + LIMIT 1 + ", [':uid' => $userId, ':h' => $hash]); + if ($row) { + $this->db->exec("UPDATE mfa_backup_codes SET used_at = NOW() WHERE id = :id", [':id' => (int)$row['id']]); + return true; + } + + return false; + } + + private function generateBackupCodes(int $userId, int $count = 10): array { + $this->db->exec("DELETE FROM mfa_backup_codes WHERE user_id = :uid", [':uid' => $userId]); + $codes = []; + for ($i = 0; $i < $count; $i++) { + $code = strtoupper(bin2hex(random_bytes(4))); + $codes[] = $code; + $this->db->exec(" + INSERT INTO mfa_backup_codes (user_id, code_hash, created_at) + VALUES (:uid, :h, NOW()) + ", [':uid' => $userId, ':h' => $this->hashToken($code)]); + } + return $codes; + } + + private function verifyTotp(string $secret, string $code, int $window = 1): bool { + $secret = trim($secret); + if ($secret === '' || !ctype_digit($code)) { + return false; + } + $timestamp = time(); + $timeStep = 30; + $t = (int)floor($timestamp / $timeStep); + + for ($i = -$window; $i <= $window; $i++) { + $hash = $this->hotp($secret, $t + $i); + if (hash_equals($hash, $code)) { + return true; + } + } + return false; + } + + private function hotp(string $secret, int $counter, int $digits = 6): string { + $key = $this->base32Decode($secret); + $binCounter = pack('N*', 0) . pack('N*', $counter); + $hash = hash_hmac('sha1', $binCounter, $key, true); + $offset = ord(substr($hash, -1)) & 0x0F; + $part = substr($hash, $offset, 4); + $value = unpack('N', $part)[1] & 0x7fffffff; + $mod = $value % (10 ** $digits); + return str_pad((string)$mod, $digits, '0', STR_PAD_LEFT); + } + + private function base32Decode(string $str): string { + $alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'; + $str = strtoupper($str); + $str = preg_replace('/[^A-Z2-7]/', '', $str); + if ($str === null) { + $str = ''; + } + $bits = ''; + for ($i = 0; $i < strlen($str); $i++) { + $val = strpos($alphabet, $str[$i]); + if ($val === false) { + continue; + } + $bits .= str_pad(decbin($val), 5, '0', STR_PAD_LEFT); + } + $bytes = ''; + for ($i = 0; $i + 8 <= strlen($bits); $i += 8) { + $bytes .= chr(bindec(substr($bits, $i, 8))); + } + return $bytes; + } + + private function generateTotpSecret(int $length = 16): string { + $alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'; + $secret = ''; + for ($i = 0; $i < $length; $i++) { + $secret .= $alphabet[random_int(0, 31)]; + } + return $secret; + } + + private function signJwt(array $payload): string { + $header = ['alg' => 'HS256', 'typ' => 'JWT']; + $segments = [ + $this->base64UrlEncode(json_encode($header, JSON_UNESCAPED_SLASHES)), + $this->base64UrlEncode(json_encode($payload, JSON_UNESCAPED_SLASHES)), + ]; + $data = implode('.', $segments); + $sig = hash_hmac('sha256', $data, $this->jwtSecret, true); + $segments[] = $this->base64UrlEncode($sig); + return implode('.', $segments); + } + + private function verifyJwt(string $token): ?array { + $parts = explode('.', $token); + if (count($parts) !== 3) { + return null; + } + [$h, $p, $s] = $parts; + $data = $h . '.' . $p; + $expected = $this->base64UrlEncode(hash_hmac('sha256', $data, $this->jwtSecret, true)); + if (!hash_equals($expected, $s)) { + return null; + } + $payload = json_decode($this->base64UrlDecode($p), true); + if (!is_array($payload)) { + return null; + } + $exp = (int)($payload['exp'] ?? 0); + if ($exp > 0 && time() > $exp) { + return null; + } + return $payload; + } + + private function base64UrlEncode(string $data): string { + return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); + } + + private function base64UrlDecode(string $data): string { + $pad = strlen($data) % 4; + if ($pad > 0) { + $data .= str_repeat('=', 4 - $pad); + } + return base64_decode(strtr($data, '-_', '+/')) ?: ''; + } + + private function randomToken(int $bytes): string { + return rtrim(strtr(base64_encode(random_bytes($bytes)), '+/', '-_'), '='); + } + + private function hashToken(string $token): string { + return hash('sha256', $token); + } + + private function readBearerToken(): string { + $header = $_SERVER['HTTP_AUTHORIZATION'] ?? $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] ?? ''; + if ($header === '' && function_exists('apache_request_headers')) { + $headers = apache_request_headers(); + $header = $headers['Authorization'] ?? ''; + } + if (preg_match('/^Bearer\s+(.+)$/i', $header, $m)) { + return trim($m[1]); + } + $cookie = $_COOKIE['access_token'] ?? ''; + if (is_string($cookie) && $cookie !== '') { + return $cookie; + } + return ''; + } + + private function redirectToLogin(): void { + header('Location: /login', true, 302); + exit; + } + + private function getUserAgent(): string { + return substr((string)($_SERVER['HTTP_USER_AGENT'] ?? ''), 0, 255); + } + + private function getIpAddress(): string { + return substr((string)($_SERVER['REMOTE_ADDR'] ?? ''), 0, 64); + } + + private function getUserEmail(int $userId): string { + $row = $this->db->fetchOne("SELECT email FROM users WHERE id = :id", [':id' => $userId]); + return (string)($row['email'] ?? ''); + } + + private function invalidateUserSessions(int $userId, string $reason): void { + $this->revokeUserSessions($userId); + $this->audit('forced_logout', $userId, 'user', $userId, ['reason' => $reason]); + } + + private function revokeUserSessions(int $userId): void { + $this->db->exec("UPDATE users SET token_version = token_version + 1 WHERE id = :id", [':id' => $userId]); + $this->db->exec("UPDATE refresh_tokens SET revoked_at = NOW() WHERE user_id = :uid AND revoked_at IS NULL", [':uid' => $userId]); + } + + private function isFirstUser(int $userId): bool { + $row = $this->db->fetchOne("SELECT COUNT(*) AS c FROM users"); + return (int)($row['c'] ?? 0) === 1; + } + + private function isRateLimited(string $action): int { + $ip = $this->getIpAddress(); + $row = $this->db->fetchOne(" + SELECT id, failed_count, window_started_at, blocked_until + FROM auth_rate_limits + WHERE ip_addr = :ip AND action = :action + LIMIT 1 + ", [':ip' => $ip, ':action' => $action]); + + if (!$row) { + return 0; + } + + $blockedUntil = $row['blocked_until'] ? strtotime((string)$row['blocked_until']) : null; + if ($blockedUntil !== null && $blockedUntil > time()) { + return $blockedUntil - time(); + } + + $windowStart = strtotime((string)$row['window_started_at']); + $window = $this->getRateWindow($action); + if ($windowStart !== false && (time() - $windowStart) > $window) { + $this->db->exec(" + UPDATE auth_rate_limits + SET failed_count = 0, window_started_at = NOW(), blocked_until = NULL + WHERE id = :id + ", [':id' => (int)$row['id']]); + } + + return 0; + } + + private function registerFailure(string $action): void { + $ip = $this->getIpAddress(); + $row = $this->db->fetchOne(" + SELECT id, failed_count, window_started_at + FROM auth_rate_limits + WHERE ip_addr = :ip AND action = :action + LIMIT 1 + ", [':ip' => $ip, ':action' => $action]); + + $window = $this->getRateWindow($action); + $max = $this->getRateMax($action); + $block = $this->getRateBlock($action); + $now = time(); + + if (!$row) { + $blockedUntil = $max <= 1 ? date('Y-m-d H:i:s', $now + $block) : null; + $this->db->exec(" + INSERT INTO auth_rate_limits (ip_addr, action, failed_count, window_started_at, blocked_until) + VALUES (:ip, :action, :cnt, NOW(), :blocked) + ", [ + ':ip' => $ip, + ':action' => $action, + ':cnt' => 1, + ':blocked' => $blockedUntil, + ]); + return; + } + + $windowStart = strtotime((string)$row['window_started_at']); + $count = (int)$row['failed_count']; + if ($windowStart === false || ($now - $windowStart) > $window) { + $count = 0; + $windowStart = $now; + } + $count++; + $blockedUntil = $count >= $max ? date('Y-m-d H:i:s', $now + $block) : null; + + $this->db->exec(" + UPDATE auth_rate_limits + SET failed_count = :cnt, window_started_at = :ws, blocked_until = :blocked + WHERE id = :id + ", [ + ':cnt' => $count, + ':ws' => date('Y-m-d H:i:s', $windowStart), + ':blocked' => $blockedUntil, + ':id' => (int)$row['id'], + ]); + } + + private function resetRateLimit(string $action): void { + $ip = $this->getIpAddress(); + $this->db->exec("DELETE FROM auth_rate_limits WHERE ip_addr = :ip AND action = :action", [ + ':ip' => $ip, + ':action' => $action, + ]); + } + + private function getRateMax(string $action): int { + return $action === 'mfa' ? $this->mfaMax : $this->loginMax; + } + + private function getRateWindow(string $action): int { + return $action === 'mfa' ? $this->mfaWindow : $this->loginWindow; + } + + private function getRateBlock(string $action): int { + return $action === 'mfa' ? $this->mfaBlock : $this->loginBlock; + } + + private function audit(string $action, ?int $actorId, ?string $targetType, ?int $targetId, array $meta = []): void { + $this->db->exec(" + INSERT INTO audit_log (actor_user_id, action, target_type, target_id, ip_addr, user_agent, meta_json, created_at) + VALUES (:actor, :action, :tt, :tid, :ip, :ua, :meta, NOW()) + ", [ + ':actor' => $actorId, + ':action' => $action, + ':tt' => $targetType, + ':tid' => $targetId, + ':ip' => $this->getIpAddress(), + ':ua' => $this->getUserAgent(), + ':meta' => json_encode($meta, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), + ]); + } +} diff --git a/app/services/ExportService.php b/app/services/ExportService.php new file mode 100644 index 0000000..fbd8ec8 --- /dev/null +++ b/app/services/ExportService.php @@ -0,0 +1,55 @@ +settings = $settings; + $this->exporters = $exporters; + } + + public function getEnabledExporters(): array { + $all = $this->settings->getAll(); + $cfg = $all['exports'] ?? []; + $enabled = []; + foreach ($this->exporters as $exp) { + $id = $exp->id(); + if (!empty($cfg[$id]['enabled'])) { + $enabled[$id] = $exp; + } + } + return $enabled; + } + + public function exportMovie(string $filePath, array $meta): array { + $enabled = $this->getEnabledExporters(); + $out = []; + foreach ($enabled as $id => $exp) { + if (!$exp->supportsKind('movie')) continue; + $out[$id] = $exp->exportMovie($filePath, $meta); + } + return $out; + } + + public function exportSeries(string $seriesPath, array $meta): array { + $enabled = $this->getEnabledExporters(); + $out = []; + foreach ($enabled as $id => $exp) { + if (!$exp->supportsKind('series')) continue; + $out[$id] = $exp->exportSeries($seriesPath, $meta); + } + return $out; + } +} diff --git a/app/services/HttpClient.php b/app/services/HttpClient.php new file mode 100644 index 0000000..88857f7 --- /dev/null +++ b/app/services/HttpClient.php @@ -0,0 +1,69 @@ +request('GET', $url, null, $headers); + return $this->decodeJson($res); + } + + public function postJson(string $url, array $payload, array $headers = []): array { + $body = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + if ($body === false) { + $body = '{}'; + } + $headers[] = 'Content-Type: application/json'; + $res = $this->request('POST', $url, $body, $headers); + return $this->decodeJson($res); + } + + private function request(string $method, string $url, ?string $body, array $headers): array { + if (!function_exists('curl_init')) { + return ['ok' => false, 'status' => 0, 'error' => 'cURL not available', 'raw' => '', 'headers' => []]; + } + $ch = \curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 8); + curl_setopt($ch, CURLOPT_TIMEOUT, 20); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); + $respHeaders = []; + \curl_setopt($ch, CURLOPT_HEADERFUNCTION, function($ch, $header) use (&$respHeaders) { + $len = strlen($header); + $header = trim($header); + if ($header === '' || strpos($header, ':') === false) return $len; + [$name, $value] = explode(':', $header, 2); + $respHeaders[strtolower(trim($name))] = trim($value); + return $len; + }); + if ($body !== null) { + curl_setopt($ch, CURLOPT_POSTFIELDS, $body); + } + if (count($headers) > 0) { + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + } + $raw = \curl_exec($ch); + $err = \curl_error($ch); + $code = (int)\curl_getinfo($ch, CURLINFO_RESPONSE_CODE); + \curl_close($ch); + + if ($raw === false) { + return ['ok' => false, 'status' => $code, 'error' => $err !== '' ? $err : 'request failed', 'raw' => '', 'headers' => $respHeaders]; + } + + return ['ok' => ($code >= 200 && $code < 300), 'status' => $code, 'raw' => (string)$raw, 'headers' => $respHeaders]; + } + + private function decodeJson(array $res): array { + if (empty($res['raw'])) { + return $res + ['data' => null]; + } + $data = json_decode((string)$res['raw'], true); + return $res + ['data' => is_array($data) ? $data : null]; + } +} diff --git a/app/services/JobsService.php b/app/services/JobsService.php new file mode 100644 index 0000000..e853162 --- /dev/null +++ b/app/services/JobsService.php @@ -0,0 +1,166 @@ +db = $db; + $this->logger = $logger; + } + + public function create(string $type, string $title, ?array $payload = null): int { + $payloadJson = $payload === null ? null : json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + + $this->db->exec(" + INSERT INTO jobs (type, status, title, payload_json) + VALUES (:type, 'queued', :title, :payload) + ", [ + ':type' => $type, + ':title' => $title, + ':payload' => $payloadJson, + ]); + + $row = $this->db->fetchOne("SELECT LAST_INSERT_ID() AS id"); + return (int)($row['id'] ?? 0); + } + + public function get(int $id): ?array { + return $this->db->fetchOne("SELECT * FROM jobs WHERE id=:id", [':id' => $id]); + } + + public function getStatus(int $id): ?string { + $row = $this->db->fetchOne("SELECT status FROM jobs WHERE id=:id", [':id' => $id]); + return $row ? (string)$row['status'] : null; + } + + public function fetchNextQueued(): ?array { + return $this->db->fetchOne(" + SELECT * FROM jobs + WHERE status='queued' + ORDER BY id ASC + LIMIT 1 + "); + } + + public function start(int $id): void { + $this->db->exec(" + UPDATE jobs + SET status='running', started_at=NOW(), error_message=NULL, cancel_requested=0, last_heartbeat=NOW() + WHERE id=:id AND status='queued' + ", [':id' => $id]); + } + + public function setProgress(int $id, int $current, int $total): void { + $pct = 0; + if ($total > 0) { + $pct = (int)floor(($current / $total) * 100); + if ($pct < 0) $pct = 0; + if ($pct > 100) $pct = 100; + } + + $this->db->exec(" + UPDATE jobs + SET progress_current=:c, progress_total=:t, progress_pct=:p, last_heartbeat=NOW() + WHERE id=:id + ", [ + ':id' => $id, + ':c' => $current, + ':t' => $total, + ':p' => $pct, + ]); + } + + public function log(int $jobId, string $level, string $message): void { + $level = in_array($level, ['info','warn','error','debug'], true) ? $level : 'info'; + $this->db->exec(" + INSERT INTO job_logs (job_id, level, message) + VALUES (:job, :level, :msg) + ", [ + ':job' => $jobId, + ':level' => $level, + ':msg' => $message, + ]); + + $this->db->exec(" + UPDATE jobs + SET last_heartbeat=NOW() + WHERE id=:id + ", [':id' => $jobId]); + + if ($this->logger) { + $this->logger->log($level, $message, ['job_id' => $jobId]); + } + } + + public function finish(int $id): void { + $this->db->exec(" + UPDATE jobs + SET status='done', finished_at=NOW() + WHERE id=:id + ", [':id' => $id]); + } + + public function fail(int $id, string $errorMessage): void { + $this->db->exec(" + UPDATE jobs + SET status='error', error_message=:e, finished_at=NOW() + WHERE id=:id + ", [ + ':id' => $id, + ':e' => $errorMessage, + ]); + } + + public function requestCancel(int $id): void { + $this->db->exec(" + UPDATE jobs + SET cancel_requested=1 + WHERE id=:id AND status IN ('queued','running') + ", [':id' => $id]); + } + + public function cancelNow(int $id, string $reason = 'canceled'): void { + $this->db->exec(" + UPDATE jobs + SET status='canceled', error_message=:e, finished_at=NOW() + WHERE id=:id AND status IN ('queued','running') + ", [ + ':id' => $id, + ':e' => $reason, + ]); + } + + public function isCancelRequested(int $id): bool { + $row = $this->db->fetchOne("SELECT cancel_requested, status FROM jobs WHERE id=:id", [':id' => $id]); + if (!$row) return false; + if ((string)($row['status'] ?? '') === 'canceled') return true; + return !empty($row['cancel_requested']); + } + + public function cancelIfRequested(int $id): bool { + if ($this->isCancelRequested($id)) { + $this->cancelNow($id, 'cancel requested'); + return true; + } + return false; + } + + public function markStalled(int $minutes): int { + $minutes = max(1, $minutes); + return $this->db->exec(" + UPDATE jobs + SET status='error', error_message='stalled watchdog', finished_at=NOW() + WHERE status='running' AND last_heartbeat IS NOT NULL + AND last_heartbeat < (NOW() - INTERVAL {$minutes} MINUTE) + "); + } +} diff --git a/app/services/LayoutService.php b/app/services/LayoutService.php new file mode 100644 index 0000000..8e339f9 --- /dev/null +++ b/app/services/LayoutService.php @@ -0,0 +1,227 @@ +db = $db; + $this->config = $config; + } + + public function preview(array $settingsAll, string $kind, string $mode, int $limit = 10, ?array $sampleItems = null): array { + $kind = ($kind === 'series') ? 'series' : 'movies'; + $limit = max(1, min($limit, 50)); + + $paths = $settingsAll['paths'] ?? []; + $layout = $settingsAll['layout'] ?? []; + $root = ($kind === 'series') ? (string)($paths['series_root'] ?? '') : (string)($paths['movies_root'] ?? ''); + + $cfg = ($kind === 'series') ? ($layout['series'] ?? []) : ($layout['movies'] ?? []); + $norm = $layout['normalization'] ?? []; + $collision = (string)($layout['collision_policy'] ?? 'stop'); + + $items = []; + if ($mode === 'samples') { + $items = $this->defaultSamples($kind); + } else if (is_array($sampleItems)) { + $items = $sampleItems; + } else { + // Pull some items from DB (best effort) + $rows = $this->db->fetchAll(" + SELECT display_name, year + FROM items + WHERE status = 'active' + ORDER BY id DESC + LIMIT :lim + ", [':lim' => $limit]); + foreach ($rows as $r) { + $items[] = [ + 'title' => (string)$r['display_name'], + 'year' => isset($r['year']) ? (int)$r['year'] : null, + ]; + } + if (count($items) === 0) { + $items = $this->defaultSamples($kind); + } + } + + $examples = []; + foreach (array_slice($items, 0, $limit) as $it) { + $title = (string)($it['title'] ?? ''); + $year = $it['year'] ?? null; + + $folderName = $this->buildDisplayFolder($title, $year); + $rel = $this->computeShardPath($cfg, $norm, $folderName, $year); + $abs = rtrim($root, '/') . '/' . ltrim($rel, '/'); + + $examples[] = [ + 'input' => ['title' => $title, 'year' => $year], + 'output_rel' => $rel, + 'output_abs' => $abs, + 'notes' => [ + 'collision_policy=' . $collision, + ], + ]; + } + + return [ + 'kind' => $kind, + 'examples' => $examples, + ]; + } + + private function buildDisplayFolder(string $title, $year): string { + $t = trim($title); + if ($year !== null && is_int($year) && $year > 1800 && $year < 2100) { + return $t . " (" . $year . ")"; + } + return $t; + } + + private function computeShardPath(array $cfg, array $norm, string $folderName, $year): string { + $strategy = (string)($cfg['strategy'] ?? 'prefix'); + $params = is_array($cfg['params'] ?? null) ? $cfg['params'] : []; + $template = $cfg['template'] ?? null; + + $name = $this->normalizeName($folderName, $norm); + $base = $name; + + if ($strategy === 'flat') { + return $base; + } + + if ($strategy === 'first_letter') { + $sh = $this->firstLetters($name, 1, (bool)($norm['uppercase_shards'] ?? true)); + return $sh . '/' . $base; + } + + if ($strategy === 'prefix') { + $n = (int)($params['n'] ?? 2); + $n = max(1, min($n, 4)); + $sh = $this->firstLetters($name, $n, (bool)($norm['uppercase_shards'] ?? true)); + return $sh . '/' . $base; + } + + if ($strategy === 'hash_buckets') { + $b = (int)($params['buckets'] ?? 100); + if (!in_array($b, [10, 50, 100, 200], true)) { + $b = 100; + } + $idx = crc32(mb_strtolower($name, 'UTF-8')) % $b; + $sh = str_pad((string)$idx, 2, '0', STR_PAD_LEFT); + return $sh . '/' . $base; + } + + if ($strategy === 'by_year') { + $y = (is_int($year) && $year > 1800 && $year < 2100) ? (string)$year : '_unknown'; + return $y . '/' . $base; + } + + if ($strategy === 'letter_year') { + $sh = $this->firstLetters($name, 1, (bool)($norm['uppercase_shards'] ?? true)); + $y = (is_int($year) && $year > 1800 && $year < 2100) ? (string)$year : '_unknown'; + return $sh . '/' . $y . '/' . $base; + } + + if ($strategy === 'decade_year') { + $y = (is_int($year) && $year > 1800 && $year < 2100) ? $year : null; + $dec = ($y !== null) ? ((int)floor($y / 10) * 10) . "s" : '_unknown'; + $yy = ($y !== null) ? (string)$y : '_unknown'; + return $dec . '/' . $yy . '/' . $base; + } + + if ($strategy === 'custom' && is_string($template) && trim($template) !== '') { + return $this->applyTemplate($template, $name, $year); + } + + // Default fallback + $sh = $this->firstLetters($name, 2, (bool)($norm['uppercase_shards'] ?? true)); + return $sh . '/' . $base; + } + + private function normalizeName(string $name, array $norm): string { + $s = $name; + + if (!empty($norm['trim_dots_spaces'])) { + $s = trim($s, " \t\n\r\0\x0B."); + } else { + $s = trim($s); + } + + if (!empty($norm['ignore_articles'])) { + $lower = mb_strtolower($s, 'UTF-8'); + foreach (['the ', 'a ', 'an '] as $a) { + if (str_starts_with($lower, $a)) { + $s = trim(mb_substr($s, mb_strlen($a, 'UTF-8'), null, 'UTF-8')); + break; + } + } + } + + if (!empty($norm['replace_unsafe_chars'])) { + $s = preg_replace('/[\/\\\\:\*\?"<>\|]+/u', ' ', $s); + $s = preg_replace('/\s+/u', ' ', $s); + $s = trim((string)$s); + } + + return $s; + } + + private function firstLetters(string $name, int $n, bool $upper): string { + $t = mb_strtolower(trim($name), 'UTF-8'); + if ($t === '') { + return '_'; + } + $letters = mb_substr($t, 0, $n, 'UTF-8'); + if ($upper) { + $letters = mb_strtoupper($letters, 'UTF-8'); + } + // sanitize shard + $letters = preg_replace('/[^0-9A-Za-zА-Яа-я]+/u', '_', (string)$letters); + return $letters !== '' ? $letters : '_'; + } + + private function applyTemplate(string $tpl, string $name, $year): string { + $y = (is_int($year) && $year > 1800 && $year < 2100) ? (string)$year : '_unknown'; + $dec = (is_int($year) && $year > 1800 && $year < 2100) ? ((int)floor($year / 10) * 10) . "s" : '_unknown'; + + $rep = [ + '{title}' => $name, + '{year}' => $y, + '{decade}' => $dec, + '{first}' => $this->firstLetters($name, 1, true), + '{first:2}' => $this->firstLetters($name, 2, true), + '{first:3}' => $this->firstLetters($name, 3, true), + '{hash:2}' => str_pad((string)(crc32(mb_strtolower($name, 'UTF-8')) % 100), 2, '0', STR_PAD_LEFT), + ]; + + $out = strtr($tpl, $rep); + $out = trim($out, "/ \t\n\r\0\x0B"); + + return $out; + } + + private function defaultSamples(string $kind): array { + if ($kind === 'series') { + return [ + ['title' => 'Breaking Bad', 'year' => 2008], + ['title' => 'The Office', 'year' => 2005], + ['title' => 'Чернобыль', 'year' => 2019], + ]; + } + + return [ + ['title' => 'Avatar', 'year' => 2009], + ['title' => 'The Matrix', 'year' => 1999], + ['title' => 'Сталкер', 'year' => 1979], + ]; + } +} diff --git a/app/services/LogService.php b/app/services/LogService.php new file mode 100644 index 0000000..acd303e --- /dev/null +++ b/app/services/LogService.php @@ -0,0 +1,184 @@ +db = $db; + $this->settings = $settings; + } + + public function log(string $level, string $message, ?array $context = null): void { + $level = in_array($level, ['info','warn','error','debug'], true) ? $level : 'info'; + if (!$this->shouldLog($level)) return; + $ctxJson = $context ? json_encode($context, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) : null; + $this->db->exec(" + INSERT INTO app_logs (level, message, context_json) + VALUES (:level, :msg, :ctx) + ", [ + ':level' => $level, + ':msg' => $message, + ':ctx' => $ctxJson, + ]); + } + + public function listByDate(string $date, int $limit = 5000): array { + $date = trim($date); + if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) { + return []; + } + $limit = max(1, min((int)$limit, 5000)); + + $sql = " + SELECT id, ts, level, message, context_json + FROM app_logs + WHERE ts >= :d AND ts < DATE_ADD(:d, INTERVAL 1 DAY) + ORDER BY id ASC + LIMIT {$limit} + "; + return $this->db->fetchAll($sql, [ + ':d' => $date . ' 00:00:00', + ]); + } + + public function listByRange(string $from, string $to, int $limit = 5000): array { + $from = trim($from); + $to = trim($to); + if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $from) || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $to)) { + return []; + } + $limit = max(1, min((int)$limit, 5000)); + + $sql = " + SELECT id, ts, level, message, context_json + FROM app_logs + WHERE ts >= :from AND ts < DATE_ADD(:to, INTERVAL 1 DAY) + ORDER BY id ASC + LIMIT {$limit} + "; + return $this->db->fetchAll($sql, [ + ':from' => $from . ' 00:00:00', + ':to' => $to . ' 00:00:00', + ]); + } + + public function listByDatePaged(string $date, int $page = 1, int $perPage = 100, ?string $level = null, ?string $sort = null, ?string $dir = null): array { + $date = trim($date); + if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) { + return ['items' => [], 'total' => 0, 'page' => 1, 'per_page' => 0]; + } + $per = max(1, min((int)$perPage, 500)); + $p = max(1, (int)$page); + $offset = ($p - 1) * $per; + + [$whereSql, $params] = $this->buildLogsFilter($date, $date, $level); + + $countRow = $this->db->fetchOne("SELECT COUNT(*) AS cnt FROM app_logs {$whereSql}", $params) ?? []; + $total = (int)($countRow['cnt'] ?? 0); + + $orderBy = $this->buildLogsOrder($sort, $dir); + $sql = " + SELECT id, ts, level, message, context_json + FROM app_logs + {$whereSql} + ORDER BY {$orderBy} + LIMIT {$per} OFFSET {$offset} + "; + $items = $this->db->fetchAll($sql, $params); + + return ['items' => $items, 'total' => $total, 'page' => $p, 'per_page' => $per]; + } + + public function listByRangePaged(string $from, string $to, int $page = 1, int $perPage = 100, ?string $level = null, ?string $sort = null, ?string $dir = null): array { + $from = trim($from); + $to = trim($to); + if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $from) || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $to)) { + return ['items' => [], 'total' => 0, 'page' => 1, 'per_page' => 0]; + } + $per = max(1, min((int)$perPage, 500)); + $p = max(1, (int)$page); + $offset = ($p - 1) * $per; + + [$whereSql, $params] = $this->buildLogsFilter($from, $to, $level); + + $countRow = $this->db->fetchOne("SELECT COUNT(*) AS cnt FROM app_logs {$whereSql}", $params) ?? []; + $total = (int)($countRow['cnt'] ?? 0); + + $orderBy = $this->buildLogsOrder($sort, $dir); + $sql = " + SELECT id, ts, level, message, context_json + FROM app_logs + {$whereSql} + ORDER BY {$orderBy} + LIMIT {$per} OFFSET {$offset} + "; + $items = $this->db->fetchAll($sql, $params); + + return ['items' => $items, 'total' => $total, 'page' => $p, 'per_page' => $per]; + } + + public function cleanup(int $keepDays): int { + if ($keepDays <= 0) { + return $this->db->exec("DELETE FROM app_logs"); + } + $days = (int)$keepDays; + return $this->db->exec(" + DELETE FROM app_logs + WHERE ts < DATE_SUB(NOW(), INTERVAL {$days} DAY) + "); + } + + private function shouldLog(string $level): bool { + $order = ['debug' => 10, 'info' => 20, 'warn' => 30, 'error' => 40]; + $lvl = $order[$level] ?? 20; + + if ($level === 'debug') { + $cfg = $this->settings->getConfig(); + $enabled = (bool)($cfg['app']['debug_logs_enabled'] ?? false); + if (!$enabled) { + return false; + } + } + + $all = $this->settings->getAll(); + $logs = $all['logs'] ?? []; + $min = (string)($logs['level'] ?? 'info'); + $minVal = $order[$min] ?? 20; + + return $lvl >= $minVal; + } + + private function buildLogsFilter(string $from, string $to, ?string $level): array { + $params = [ + ':from' => $from . ' 00:00:00', + ':to' => $to . ' 00:00:00', + ]; + $sql = "WHERE ts >= :from AND ts < DATE_ADD(:to, INTERVAL 1 DAY)"; + $allowed = ['debug', 'info', 'warn', 'error']; + if ($level && in_array($level, $allowed, true)) { + $sql .= " AND level = :level"; + $params[':level'] = $level; + } + return [$sql, $params]; + } + + private function buildLogsOrder(?string $sort, ?string $dir): string { + $map = [ + 'ts' => 'ts', + 'level' => 'level', + 'message' => 'message', + 'context_json' => 'context_json', + ]; + $col = $map[$sort ?? ''] ?? 'id'; + $direction = strtolower((string)$dir) === 'desc' ? 'DESC' : 'ASC'; + return $col . ' ' . $direction; + } +} diff --git a/app/services/MediaApplyService.php b/app/services/MediaApplyService.php new file mode 100644 index 0000000..c42a3ef --- /dev/null +++ b/app/services/MediaApplyService.php @@ -0,0 +1,194 @@ +media = $media; + $this->mkvtoolnix = $mkvtoolnix; + $this->jobs = $jobs; + $this->metadata = $metadata; + $this->export = $export; + } + + public function applyTab(string $tab, int $jobId): array { + $items = $this->media->listTab($tab); + $files = $this->expandFiles($tab, $items); + + $total = count($files); + $this->jobs->setProgress($jobId, 0, max(1, $total)); + + $done = 0; + $rename = 0; + $delete = 0; + $convert = 0; + $errors = 0; + $seriesExported = []; + + foreach ($files as $f) { + if ($this->jobs->cancelIfRequested($jobId)) { + $this->jobs->log($jobId, 'warn', 'Apply canceled by user'); + return [ + 'files' => $total, + 'renamed' => $rename, + 'deleted' => $delete, + 'converted' => $convert, + 'errors' => $errors, + 'canceled' => true, + ]; + } + $done++; + $this->jobs->setProgress($jobId, $done, $total); + + $path = (string)($f['abs_path'] ?? ''); + if ($path === '') continue; + + $plan = $this->media->buildEdits($path); + + if (!empty($plan['convert'])) { + $res = $this->convertFile($path); + if (!$res['ok']) { + $errors++; + $this->jobs->log($jobId, 'error', "Convert failed: {$path} | {$res['error']}"); + } else { + $convert++; + $this->jobs->log($jobId, 'info', "Converted: {$path} -> {$res['dest']}"); + $path = $res['dest']; + } + } + + if (count($plan['delete']) > 0 || count($plan['rename']) > 0) { + $res = $this->mkvtoolnix->applyTrackEdits($path, $plan['rename'], $plan['delete']); + if (!$res['ok']) { + $errors++; + $this->jobs->log($jobId, 'error', "Apply failed: {$path} | {$res['error']}"); + } else if (!empty($res['changed'])) { + $rename += count($plan['rename']); + $delete += count($plan['delete']); + $this->jobs->log($jobId, 'info', "Applied: {$path} (rename " . count($plan['rename']) . ", delete " . count($plan['delete']) . ")"); + } + } + + $exported = $this->maybeExportMeta($f, $seriesExported); + foreach ($exported as $expId => $res) { + if (!empty($res['ok'])) { + $this->jobs->log($jobId, 'info', "Exported {$expId}: " . ($res['path'] ?? $path)); + } else if (!empty($res['error'])) { + $this->jobs->log($jobId, 'warn', "Export {$expId} failed: " . ($res['error'] ?? 'error')); + } + } + } + + return [ + 'files' => $total, + 'renamed' => $rename, + 'deleted' => $delete, + 'converted' => $convert, + 'errors' => $errors, + ]; + } + + private function expandFiles(string $tab, array $items): array { + if ($tab !== 'series') return $items; + $out = []; + foreach ($items as $s) { + $key = (string)($s['series_key'] ?? ''); + if ($key === '') continue; + $files = $this->media->getSeriesFiles($key); + foreach ($files as $f) $out[] = $f; + } + return $out; + } + + private function convertFile(string $src): array { + $dir = dirname($src); + $base = pathinfo($src, PATHINFO_FILENAME); + $dest = $dir . '/' . $base . '.mkv'; + if (is_file($dest)) { + $dest = $dir . '/' . $base . '_conv.mkv'; + } + + $res = $this->mkvtoolnix->convertToMkv($src, $dest); + if (!$res['ok']) return $res; + + $meta = $this->mkvtoolnix->readFileData($dest); + $info = (is_array($meta) && isset($meta['mkvmerge']['data'])) ? $meta['mkvmerge']['data'] : null; + $this->media->updateFilePath($src, $dest, $info); + + return ['ok' => true, 'dest' => $dest]; + } + + private function maybeExportMeta(array $file, array &$seriesExported): array { + $enabled = $this->export->getEnabledExporters(); + if (count($enabled) === 0) return []; + + $kind = (string)($file['kind'] ?? 'movie'); + if ($kind === 'series') { + $seriesKey = (string)($file['series_key'] ?? ''); + if ($seriesKey === '' || isset($seriesExported[$seriesKey])) { + return []; + } + $metaRow = $this->metadata->getSubjectMeta('series', $seriesKey); + if (!is_array($metaRow)) return []; + $display = $this->metadata->formatDisplay($metaRow); + $payload = $this->buildExportPayload($display); + if ($payload['title'] === '' && $payload['original_title'] === '') return []; + $seriesPath = $this->resolveSeriesPath($file); + $seriesExported[$seriesKey] = true; + return $this->export->exportSeries($seriesPath, $payload); + } + + $path = (string)($file['abs_path'] ?? ''); + if ($path === '') return []; + $metaRow = $this->metadata->getSubjectMeta('movie', $path); + if (!is_array($metaRow)) return []; + $display = $this->metadata->formatDisplay($metaRow); + $payload = $this->buildExportPayload($display); + if ($payload['title'] === '' && $payload['original_title'] === '') return []; + return $this->export->exportMovie($path, $payload); + } + + private function buildExportPayload(array $display): array { + $meta = is_array($display['meta'] ?? null) ? $display['meta'] : []; + $provider = (string)($meta['provider'] ?? ''); + $providerId = (string)($meta['provider_id'] ?? ''); + $providerUrl = ''; + if ($provider !== '' && $providerId !== '') { + $providerUrl = $this->metadata->buildProviderUrl($provider, $providerId); + } + return [ + 'title' => (string)($display['title_display'] ?? ''), + 'original_title' => (string)($display['title_original'] ?? ''), + 'year' => $display['year'] ?? null, + 'provider' => $provider, + 'provider_id' => $providerId, + 'provider_url' => $providerUrl, + ]; + } + + private function resolveSeriesPath(array $file): string { + $abs = (string)($file['abs_path'] ?? ''); + $rel = (string)($file['rel_path'] ?? ''); + $seriesKey = (string)($file['series_key'] ?? ''); + if ($abs !== '' && $rel !== '' && str_ends_with($abs, $rel) && $seriesKey !== '') { + $root = substr($abs, 0, strlen($abs) - strlen($rel)); + return rtrim($root, '/') . '/' . $seriesKey; + } + return $abs !== '' ? dirname($abs) : ''; + } +} diff --git a/app/services/MediaLibraryService.php b/app/services/MediaLibraryService.php new file mode 100644 index 0000000..d48ad09 --- /dev/null +++ b/app/services/MediaLibraryService.php @@ -0,0 +1,751 @@ +db = $db; + $this->settings = $settings; + $this->metadata = $metadata; + } + + public function upsertMediaFile( + int $profileId, + string $root, + string $abs, + array $stat, + bool $isMkv, + ?array $mkvInfo + ): void { + $root = rtrim($root, "/"); + $rel = ltrim(str_replace($root, '', $abs), '/'); + if ($rel === '') { + $rel = basename($abs); + } + + $name = basename($abs); + $ext = strtolower(pathinfo($abs, PATHINFO_EXTENSION)); + $size = (int)($stat['size'] ?? 0); + $mtime = (int)($stat['mtime'] ?? 0); + + $seriesKey = null; + $kind = 'unknown'; + if (str_contains($rel, '/')) { + $parts = explode('/', $rel); + $seriesKey = $parts[0] !== '' ? $parts[0] : null; + $kind = $seriesKey ? 'series' : 'unknown'; + } else { + $kind = 'movie'; + } + + [$container, $durationMs] = $this->extractContainerData($mkvInfo); + + $this->db->exec(" + INSERT INTO media_files + (scan_profile_id, abs_path, rel_path, name, ext, size_bytes, mtime, is_mkv, kind, series_key, container, duration_ms, last_analyzed_at) + VALUES + (:pid, :abs, :rel, :name, :ext, :size, :mtime, :is_mkv, :kind, :series, :container, :duration, NOW()) + ON DUPLICATE KEY UPDATE + scan_profile_id = VALUES(scan_profile_id), + rel_path = VALUES(rel_path), + name = VALUES(name), + ext = VALUES(ext), + size_bytes = VALUES(size_bytes), + mtime = VALUES(mtime), + is_mkv = VALUES(is_mkv), + kind = VALUES(kind), + series_key = VALUES(series_key), + container = VALUES(container), + duration_ms = VALUES(duration_ms), + last_analyzed_at = NOW() + ", [ + ':pid' => $profileId, + ':abs' => $abs, + ':rel' => $rel, + ':name' => $name, + ':ext' => $ext, + ':size' => $size, + ':mtime' => $mtime, + ':is_mkv' => $isMkv ? 1 : 0, + ':kind' => $kind, + ':series' => $seriesKey, + ':container' => $container !== '' ? $container : null, + ':duration' => $durationMs, + ]); + } + + public function listTab(string $tab): array { + if ($tab === 'series') { + $rows = $this->db->fetchAll(" + SELECT series_key, COUNT(*) AS total_files + FROM media_files + WHERE is_mkv=1 AND kind='series' AND series_key IS NOT NULL + GROUP BY series_key + ORDER BY series_key ASC + LIMIT 2000 + "); + + $out = []; + $seriesKeys = array_map(fn($r) => (string)$r['series_key'], $rows); + $metaMap = $this->metadata->getSubjectMetaMap('series', $seriesKeys); + foreach ($rows as $r) { + $key = (string)$r['series_key']; + $files = $this->getSeriesFiles($key); + $stats = $this->summarizeFiles($files); + $meta = $metaMap[$key] ?? null; + $display = $this->metadata->formatDisplay($meta); + $out[] = [ + 'series_key' => $key, + 'title_display' => $display['title_display'], + 'title_original' => $display['title_original'], + 'year' => $display['year'], + 'meta' => $display['meta'], + 'total_files' => (int)$r['total_files'], + 'needs_attention' => $stats['needs_attention'], + 'issues' => $stats['issues'], + ]; + } + return $out; + } + + if ($tab === 'needs_mkv') { + $rows = $this->db->fetchAll(" + SELECT * + FROM media_files + WHERE is_mkv=0 + ORDER BY updated_at DESC + LIMIT 2000 + "); + return $this->decorateFiles($rows, 'movie'); + } + + // movies (default) + $rows = $this->db->fetchAll(" + SELECT * + FROM media_files + WHERE is_mkv=1 AND kind='movie' + ORDER BY updated_at DESC + LIMIT 2000 + "); + return $this->decorateFiles($rows, 'movie'); + } + + public function listTabPaged(string $tab, int $page, int $perPage, string $sort, string $dir): array { + $page = max(1, $page); + $perPage = max(1, $perPage); + $offset = ($page - 1) * $perPage; + $dir = strtolower($dir) === 'asc' ? 'ASC' : 'DESC'; + + if ($tab === 'series') { + $orderBy = 'series_key ASC'; + if ($sort === 'name') { + $orderBy = 'series_key ' . $dir; + } + $totalRow = $this->db->fetchOne(" + SELECT COUNT(DISTINCT series_key) AS total + FROM media_files + WHERE is_mkv=1 AND kind='series' AND series_key IS NOT NULL + "); + $total = (int)($totalRow['total'] ?? 0); + $rows = $this->db->fetchAll(" + SELECT series_key, COUNT(*) AS total_files + FROM media_files + WHERE is_mkv=1 AND kind='series' AND series_key IS NOT NULL + GROUP BY series_key + ORDER BY {$orderBy} + LIMIT {$perPage} OFFSET {$offset} + "); + + $out = []; + $seriesKeys = array_map(fn($r) => (string)$r['series_key'], $rows); + $metaMap = $this->metadata->getSubjectMetaMap('series', $seriesKeys); + foreach ($rows as $r) { + $key = (string)$r['series_key']; + $files = $this->getSeriesFiles($key); + $stats = $this->summarizeFiles($files); + $meta = $metaMap[$key] ?? null; + $display = $this->metadata->formatDisplay($meta); + $out[] = [ + 'series_key' => $key, + 'title_display' => $display['title_display'], + 'title_original' => $display['title_original'], + 'year' => $display['year'], + 'meta' => $display['meta'], + 'total_files' => (int)$r['total_files'], + 'needs_attention' => $stats['needs_attention'], + 'issues' => $stats['issues'], + ]; + } + return ['items' => $out, 'total' => $total]; + } + + if ($tab === 'needs_mkv') { + $orderBy = $this->mediaOrderBy($sort, $dir, 'updated_at DESC'); + $totalRow = $this->db->fetchOne(" + SELECT COUNT(*) AS total + FROM media_files + WHERE is_mkv=0 + "); + $total = (int)($totalRow['total'] ?? 0); + $rows = $this->db->fetchAll(" + SELECT * + FROM media_files + WHERE is_mkv=0 + ORDER BY {$orderBy} + LIMIT {$perPage} OFFSET {$offset} + "); + $items = $this->decorateFiles($rows, 'movie'); + return ['items' => $items, 'total' => $total]; + } + + // movies (default) + $orderBy = $this->mediaOrderBy($sort, $dir, 'updated_at DESC'); + $totalRow = $this->db->fetchOne(" + SELECT COUNT(*) AS total + FROM media_files + WHERE is_mkv=1 AND kind='movie' + "); + $total = (int)($totalRow['total'] ?? 0); + $rows = $this->db->fetchAll(" + SELECT * + FROM media_files + WHERE is_mkv=1 AND kind='movie' + ORDER BY {$orderBy} + LIMIT {$perPage} OFFSET {$offset} + "); + $items = $this->decorateFiles($rows, 'movie'); + return ['items' => $items, 'total' => $total]; + } + + private function mediaOrderBy(string $sort, string $dir, string $fallback): string { + $dir = strtoupper($dir) === 'DESC' ? 'DESC' : 'ASC'; + $map = [ + 'name' => 'name', + 'mtime' => 'mtime', + 'updated' => 'updated_at', + 'size' => 'size_bytes', + ]; + if (isset($map[$sort])) { + return $map[$sort] . ' ' . $dir; + } + return $fallback; + } + + public function getSeriesFiles(string $seriesKey): array { + $rows = $this->db->fetchAll(" + SELECT * + FROM media_files + WHERE is_mkv=1 AND kind='series' AND series_key=:k + ORDER BY rel_path ASC + LIMIT 5000 + ", [':k' => $seriesKey]); + return $this->decorateFiles($rows, 'series'); + } + + public function dryRun(string $tab): array { + $rows = $this->listTab($tab); + $totalFiles = 0; + $rename = 0; + $delete = 0; + $unknown = 0; + $convert = 0; + $details = []; + + if ($tab === 'series') { + foreach ($rows as $series) { + $files = $this->getSeriesFiles((string)$series['series_key']); + foreach ($files as $f) { + $res = $this->planFile($f['abs_path'] ?? ''); + $totalFiles++; + $rename += $res['rename']; + $delete += $res['delete']; + $unknown += $res['unknown_type']; + $convert += $res['convert']; + $details[] = $res['detail']; + } + } + } else { + foreach ($rows as $f) { + $res = $this->planFile($f['abs_path'] ?? ''); + $totalFiles++; + $rename += $res['rename']; + $delete += $res['delete']; + $unknown += $res['unknown_type']; + $convert += $res['convert']; + $details[] = $res['detail']; + } + } + + return [ + 'files' => $totalFiles, + 'rename' => $rename, + 'delete' => $delete, + 'unknown_type' => $unknown, + 'convert' => $convert, + 'rows' => $details, + ]; + } + + public function getFileDetail(string $absPath): array { + $row = $this->db->fetchOne(" + SELECT * + FROM media_files + WHERE abs_path=:p + LIMIT 1 + ", [':p' => $absPath]); + + if (!$row) { + return ['ok' => false, 'error' => 'File not found']; + } + + $meta = $this->db->fetchOne(" + SELECT info_json + FROM media_file_meta + WHERE abs_path=:p + LIMIT 1 + ", [':p' => $absPath]); + + $info = null; + if ($meta && isset($meta['info_json'])) { + $decoded = json_decode((string)$meta['info_json'], true); + $info = is_array($decoded) ? $decoded : null; + } + + $rules = $this->getRules(); + $tracks = $this->parseTracks($info, $rules); + $issues = $this->evaluateIssues($tracks, $rules); + if (is_array($row) && is_array($info)) { + $this->refreshContainerData((int)$row['id'], $info, $row); + $row = $this->db->fetchOne(" + SELECT * + FROM media_files + WHERE abs_path=:p + LIMIT 1 + ", [':p' => $absPath]) ?: $row; + } + + $subject = $this->subjectForRow($row); + $meta = $subject ? $this->metadata->getSubjectMeta($subject['kind'], $subject['key']) : null; + $display = $this->metadata->formatDisplay($meta); + $metaPayload = is_array($display['meta'] ?? null) ? $display['meta'] : []; + if ($subject) { + $metaPayload['subject_kind'] = $subject['kind']; + $metaPayload['subject_key'] = $subject['key']; + } + $metaPayload['title_display'] = $display['title_display']; + $metaPayload['title_original'] = $display['title_original']; + $metaPayload['year'] = $display['year']; + + return [ + 'ok' => true, + 'file' => $this->decorateFileRow($row, $issues), + 'tracks' => $tracks, + 'meta' => $metaPayload, + ]; + } + + public function getRules(): array { + $all = $this->settings->getAll(); + $rules = $all['media_rules'] ?? []; + return [ + 'name_map' => is_array($rules['name_map'] ?? null) ? $rules['name_map'] : [], + 'delete_rules' => is_array($rules['delete_rules'] ?? null) ? $rules['delete_rules'] : [], + 'language_priority' => is_array($rules['language_priority'] ?? null) ? $rules['language_priority'] : ['ru','en'], + 'audio_type_priority' => is_array($rules['audio_type_priority'] ?? null) ? $rules['audio_type_priority'] : ['dub','voiceover','original','commentary','unknown'], + 'require_audio_type' => !empty($rules['require_audio_type']), + 'series_order_threshold' => (float)($rules['series_order_threshold'] ?? 0.7), + ]; + } + + private function planFile(string $absPath): array { + $row = $this->db->fetchOne("SELECT * FROM media_files WHERE abs_path=:p LIMIT 1", [':p' => $absPath]); + $name = $row ? (string)($row['name'] ?? $absPath) : $absPath; + $plan = $this->buildEdits($absPath); + + $actions = []; + if (count($plan['rename']) > 0) $actions[] = 'rename'; + if (count($plan['delete']) > 0) $actions[] = 'delete'; + if ($plan['unknown_type'] > 0) $actions[] = 'unknown_type'; + if ($plan['convert'] > 0) $actions[] = 'convert'; + + return [ + 'rename' => count($plan['rename']), + 'delete' => count($plan['delete']), + 'unknown_type' => $plan['unknown_type'], + 'convert' => $plan['convert'], + 'detail' => [ + 'name' => $name, + 'actions' => $actions, + ], + ]; + } + + public function updateFilePath(string $absPath, string $newAbsPath, ?array $mkvInfo = null): void { + $row = $this->db->fetchOne("SELECT * FROM media_files WHERE abs_path=:p LIMIT 1", [':p' => $absPath]); + if (!$row) return; + + $rel = (string)($row['rel_path'] ?? ''); + $dir = $rel !== '' ? trim(dirname($rel), '.') : ''; + $newName = basename($newAbsPath); + $newRel = $dir !== '' ? $dir . '/' . $newName : $newName; + $stat = @stat($newAbsPath); + $size = is_array($stat) ? (int)($stat['size'] ?? 0) : (int)($row['size_bytes'] ?? 0); + $mtime = is_array($stat) ? (int)($stat['mtime'] ?? 0) : (int)($row['mtime'] ?? 0); + + [$container, $durationMs] = $this->extractContainerData($mkvInfo); + + $this->db->exec(" + UPDATE media_files + SET abs_path=:abs, rel_path=:rel, name=:name, ext=:ext, is_mkv=1, + size_bytes=:size, mtime=:mtime, container=:container, duration_ms=:duration, + updated_at=NOW() + WHERE abs_path=:old + ", [ + ':abs' => $newAbsPath, + ':rel' => $newRel, + ':name' => $newName, + ':ext' => strtolower(pathinfo($newAbsPath, PATHINFO_EXTENSION)), + ':size' => $size, + ':mtime' => $mtime, + ':container' => $container !== '' ? $container : null, + ':duration' => $durationMs, + ':old' => $absPath, + ]); + } + + public function buildEdits(string $absPath): array { + $row = $this->db->fetchOne("SELECT * FROM media_files WHERE abs_path=:p LIMIT 1", [':p' => $absPath]); + $convert = ($row && empty($row['is_mkv'])) ? 1 : 0; + + $meta = $this->db->fetchOne("SELECT info_json FROM media_file_meta WHERE abs_path=:p LIMIT 1", [':p' => $absPath]); + $info = null; + if ($meta && isset($meta['info_json'])) { + $decoded = json_decode((string)$meta['info_json'], true); + $info = is_array($decoded) ? $decoded : null; + } + + $rules = $this->getRules(); + $tracks = $this->parseTracks($info, $rules); + $rename = []; + $delete = []; + $unknownCount = 0; + $deleteIds = []; + + foreach ($tracks as $t) { + $id = (int)($t['id'] ?? 0); + if ($this->matchesDeleteRule($t, $rules['delete_rules'])) { + if ($id > 0) { + $deleteIds[$id] = true; + $delete[] = $id; + } + } + if ($t['name_norm'] !== '' && $t['name_norm'] !== $t['name']) { + if ($id > 0) { + $rename[] = ['id' => $id, 'name' => $t['name_norm']]; + } + } + if (!empty($rules['require_audio_type']) && $t['type'] === 'audio' && $t['audio_type'] === 'unknown') { + $unknownCount++; + } + } + + // Do not rename deleted tracks + $rename = array_values(array_filter($rename, fn($r) => !isset($deleteIds[(int)$r['id']]))); + + return [ + 'rename' => $rename, + 'delete' => $delete, + 'unknown_type' => $unknownCount, + 'convert' => $convert, + ]; + } + + private function decorateFiles(array $rows, string $kind): array { + $rules = $this->getRules(); + $keys = []; + foreach ($rows as $r) { + if ($kind === 'series') { + $keys[] = (string)($r['series_key'] ?? ''); + } else { + $keys[] = (string)($r['abs_path'] ?? ''); + } + } + $metaMap = $this->metadata->getSubjectMetaMap($kind === 'series' ? 'series' : 'movie', $keys); + $out = []; + foreach ($rows as $r) { + $meta = null; + if ((int)($r['is_mkv'] ?? 0) === 1) { + $metaRow = $this->db->fetchOne(" + SELECT info_json + FROM media_file_meta + WHERE abs_path=:p + LIMIT 1 + ", [':p' => (string)$r['abs_path']]); + if ($metaRow && isset($metaRow['info_json'])) { + $decoded = json_decode((string)$metaRow['info_json'], true); + $meta = is_array($decoded) ? $decoded : null; + } + } + + $tracks = $this->parseTracks($meta, $rules); + $issues = $this->evaluateIssues($tracks, $rules); + if (is_array($meta)) { + $this->refreshContainerData((int)$r['id'], $meta, $r); + } + $subjectKey = ($kind === 'series') + ? (string)($r['series_key'] ?? '') + : (string)($r['abs_path'] ?? ''); + $metaRow = $metaMap[$subjectKey] ?? null; + $display = $this->metadata->formatDisplay($metaRow); + $out[] = $this->decorateFileRow($r, $issues, $display); + } + return $out; + } + + private function decorateFileRow(array $r, array $issues, ?array $display = null): array { + $display = $display ?? $this->metadata->formatDisplay(null); + return [ + 'id' => (int)($r['id'] ?? 0), + 'abs_path' => (string)($r['abs_path'] ?? ''), + 'rel_path' => (string)($r['rel_path'] ?? ''), + 'name' => (string)($r['name'] ?? ''), + 'ext' => (string)($r['ext'] ?? ''), + 'is_mkv' => !empty($r['is_mkv']), + 'kind' => (string)($r['kind'] ?? 'unknown'), + 'series_key' => $r['series_key'] ?? null, + 'container' => $r['container'] ?? null, + 'duration_ms' => $r['duration_ms'] !== null ? (int)$r['duration_ms'] : null, + 'size_bytes' => (int)($r['size_bytes'] ?? 0), + 'needs_attention' => $issues['needs_attention'], + 'issues' => $issues['issues'], + 'title_display' => $display['title_display'], + 'title_original' => $display['title_original'], + 'year' => $display['year'], + 'meta' => $display['meta'], + ]; + } + + private function subjectForRow(array $row): ?array { + $kind = (string)($row['kind'] ?? 'unknown'); + if ($kind === 'series') { + $seriesKey = (string)($row['series_key'] ?? ''); + if ($seriesKey !== '') { + return ['kind' => 'series', 'key' => $seriesKey]; + } + } + $abs = (string)($row['abs_path'] ?? ''); + if ($abs !== '') { + return ['kind' => 'movie', 'key' => $abs]; + } + return null; + } + + + private function summarizeFiles(array $files): array { + $needs = 0; + $issues = []; + foreach ($files as $f) { + if (!empty($f['needs_attention'])) { + $needs++; + foreach (($f['issues'] ?? []) as $i) { + $issues[$i] = true; + } + } + } + return [ + 'needs_attention' => $needs, + 'issues' => array_values(array_keys($issues)), + ]; + } + + private function parseTracks(?array $info, array $rules): array { + if (!is_array($info)) return []; + $tracks = is_array($info['tracks'] ?? null) ? $info['tracks'] : []; + $out = []; + foreach ($tracks as $t) { + $props = is_array($t['properties'] ?? null) ? $t['properties'] : []; + $type = (string)($t['type'] ?? ''); + $name = (string)($props['track_name'] ?? ''); + $lang = (string)($props['language'] ?? 'und'); + $codec = (string)($props['codec_id'] ?? ''); + $channels = isset($props['audio_channels']) ? (string)$props['audio_channels'] : ''; + $isDefault = !empty($props['default_track']); + $isForced = !empty($props['forced_track']); + + $audioType = 'unknown'; + if ($type === 'audio') { + $audioType = $this->detectAudioType($name); + } + + $nameNorm = $this->applyNameMap($name, $rules['name_map']); + + $out[] = [ + 'id' => (int)($t['id'] ?? 0), + 'type' => $type, + 'lang' => $lang, + 'name' => $name, + 'name_norm' => $nameNorm, + 'codec' => $codec, + 'channels' => $channels, + 'default' => $isDefault, + 'forced' => $isForced, + 'audio_type' => $audioType, + ]; + } + return $out; + } + + private function evaluateIssues(array $tracks, array $rules): array { + $issues = []; + foreach ($tracks as $t) { + if ($t['name_norm'] !== '' && $t['name_norm'] !== $t['name']) { + $issues['rename'] = true; + } + if ($this->matchesDeleteRule($t, $rules['delete_rules'])) { + $issues['delete'] = true; + } + if (!empty($rules['require_audio_type']) && $t['type'] === 'audio' && $t['audio_type'] === 'unknown') { + $issues['unknown_type'] = true; + } + } + return [ + 'needs_attention' => count($issues) > 0, + 'issues' => array_values(array_keys($issues)), + ]; + } + + private function applyNameMap(string $name, array $map): string { + $trim = trim($name); + if ($trim === '') return $name; + + foreach ($map as $row) { + if (!is_array($row)) continue; + $mode = (string)($row['mode'] ?? 'exact'); + $pattern = (string)($row['pattern'] ?? ''); + $canonical = (string)($row['canonical'] ?? ''); + if ($pattern === '' || $canonical === '') continue; + + if ($mode === 'exact') { + if (mb_strtolower($trim) === mb_strtolower($pattern)) { + return $canonical; + } + } else if ($mode === 'regex') { + $ok = @preg_match($pattern, $trim); + if ($ok === 1) { + return $canonical; + } + } + } + + return $name; + } + + private function matchesDeleteRule(array $t, array $rules): bool { + foreach ($rules as $r) { + if (!is_array($r)) continue; + $type = (string)($r['type'] ?? ''); + $lang = (string)($r['lang'] ?? ''); + $audioType = (string)($r['audio_type'] ?? ''); + $nameContains = (string)($r['name_contains'] ?? ''); + $exceptDefault = !empty($r['except_default']); + $exceptForced = !empty($r['except_forced']); + + if ($type !== '' && $t['type'] !== $type) continue; + if ($lang !== '' && $t['lang'] !== $lang) continue; + if ($audioType !== '' && $t['audio_type'] !== $audioType) continue; + if ($nameContains !== '' && !str_contains(mb_strtolower($t['name']), mb_strtolower($nameContains))) continue; + if ($exceptDefault && !empty($t['default'])) continue; + if ($exceptForced && !empty($t['forced'])) continue; + + return true; + } + return false; + } + + private function detectAudioType(string $name): string { + $n = mb_strtolower($name); + if ($n === '') return 'unknown'; + + $commentary = ['commentary','коммент','комментар','director','режисс']; + $dub = ['dub','dubbing','дуб','дубляж','полный']; + $voiceover = ['vo','voiceover','озвуч','многогол','двухгол','одногол']; + $original = ['original','orig','оригин']; + + foreach ($commentary as $k) { + if (str_contains($n, $k)) return 'commentary'; + } + foreach ($dub as $k) { + if (str_contains($n, $k)) return 'dub'; + } + foreach ($voiceover as $k) { + if (str_contains($n, $k)) return 'voiceover'; + } + foreach ($original as $k) { + if (str_contains($n, $k)) return 'original'; + } + + return 'unknown'; + } + + private function refreshContainerData(int $id, array $info, array $row): void { + [$container, $durationMs] = $this->extractContainerData($info); + + $needsUpdate = false; + if ($container !== '' && ($row['container'] ?? null) !== $container) { + $needsUpdate = true; + } + if ($durationMs !== null && (int)($row['duration_ms'] ?? 0) !== $durationMs) { + $needsUpdate = true; + } + if (!$needsUpdate) return; + + $this->db->exec(" + UPDATE media_files + SET container=:c, duration_ms=:d, updated_at=NOW() + WHERE id=:id + ", [ + ':c' => $container !== '' ? $container : null, + ':d' => $durationMs, + ':id' => $id, + ]); + } + + private function extractContainerData(?array $info): array { + if (!is_array($info)) { + return [null, null]; + } + $container = ''; + if (isset($info['container']['properties']['container_type'])) { + $container = (string)$info['container']['properties']['container_type']; + } + if ($container === '' && isset($info['container']['type'])) { + $container = (string)$info['container']['type']; + } + if ($container !== '' && preg_match('/^\d+$/', $container) && isset($info['container']['type'])) { + $container = (string)$info['container']['type']; + } + + $dur = $info['container']['properties']['duration'] ?? $info['container']['duration'] ?? null; + $durationMs = null; + if (is_numeric($dur)) { + $durVal = (float)$dur; + // mkvmerge reports duration in ns; guard for seconds in older formats + if ($durVal > 1e9) { + $durationMs = (int)round($durVal / 1e6); + } else { + $durationMs = (int)round($durVal * 1000); + } + } + + return [$container !== '' ? $container : null, $durationMs]; + } +} diff --git a/app/services/MetadataService.php b/app/services/MetadataService.php new file mode 100644 index 0000000..b6665c3 --- /dev/null +++ b/app/services/MetadataService.php @@ -0,0 +1,372 @@ +db = $db; + $this->settings = $settings; + $this->providers = $providers; + $this->logger = $logger; + } + + public function search(string $query, string $type, ?int $year): array { + $query = trim($query); + if ($query === '') return []; + + $cfg = $this->getMetadataSettings(); + $langs = $this->getLanguages($cfg); + $order = $this->getProviderPriority($cfg); + $enabled = $this->getEnabledProviders($cfg, $order); + + $results = []; + foreach ($enabled as $pid => $provider) { + $pCfg = $cfg['providers'][$pid] ?? []; + foreach ($langs as $lang) { + $this->logger?->log('debug', 'Metadata search request', [ + 'provider' => $pid, + 'lang' => $lang, + 'query' => $query, + 'type' => $type, + 'year' => $year, + ]); + $found = $provider->search($query, $type, $year, $lang, $pCfg); + $this->logger?->log('info', 'Metadata provider results', [ + 'provider' => $pid, + 'lang' => $lang, + 'count' => count($found), + ]); + foreach ($found as $row) { + $key = $pid . ':' . (string)($row['provider_id'] ?? ''); + if ($key === $pid . ':') continue; + if (!isset($results[$key])) { + $results[$key] = $row; + $results[$key]['title_map'] = is_array($row['title_map'] ?? null) ? $row['title_map'] : []; + $results[$key]['_priority'] = array_search($pid, $order, true); + } else { + $existing = $results[$key]['title_map'] ?? []; + $add = is_array($row['title_map'] ?? null) ? $row['title_map'] : []; + $results[$key]['title_map'] = array_merge($existing, $add); + if (($results[$key]['original_title'] ?? '') === '' && !empty($row['original_title'])) { + $results[$key]['original_title'] = $row['original_title']; + } + if (($results[$key]['year'] ?? null) === null && isset($row['year'])) { + $results[$key]['year'] = $row['year']; + } + if (($results[$key]['poster'] ?? '') === '' && !empty($row['poster'])) { + $results[$key]['poster'] = $row['poster']; + } + } + } + } + } + + $out = array_values($results); + usort($out, function($a, $b) { + $pa = $a['_priority'] ?? 999; + $pb = $b['_priority'] ?? 999; + if ($pa === $pb) return 0; + return $pa < $pb ? -1 : 1; + }); + foreach ($out as &$r) { + unset($r['_priority']); + } + return $out; + } + + public function getSubjectMeta(string $kind, string $key): ?array { + if ($key === '') return null; + $row = $this->db->fetchOne(" + SELECT * + FROM media_metadata + WHERE subject_kind=:k AND subject_key=:s + LIMIT 1 + ", [':k' => $kind, ':s' => $key]); + return $row ? $this->decodeMetaRow($row) : null; + } + + public function getSubjectMetaMap(string $kind, array $keys): array { + $keys = array_values(array_filter($keys, fn($k) => $k !== '')); + if (count($keys) === 0) return []; + $placeholders = []; + $params = [':k' => $kind]; + foreach ($keys as $i => $k) { + $ph = ':p' . $i; + $placeholders[] = $ph; + $params[$ph] = $k; + } + $rows = $this->db->fetchAll(" + SELECT * + FROM media_metadata + WHERE subject_kind=:k + AND subject_key IN (" . implode(',', $placeholders) . ") + ", $params); + $out = []; + foreach ($rows as $r) { + $row = $this->decodeMetaRow($r); + $out[(string)$row['subject_key']] = $row; + } + return $out; + } + + public function saveSelection(string $kind, string $key, array $payload): void { + $provider = (string)($payload['provider'] ?? ''); + $providerId = (string)($payload['provider_id'] ?? ''); + $titleMap = is_array($payload['title_map'] ?? null) ? $payload['title_map'] : []; + $originalTitle = (string)($payload['original_title'] ?? ''); + $year = isset($payload['year']) ? (int)$payload['year'] : null; + + $this->upsertMeta($kind, $key, [ + 'provider' => $provider !== '' ? $provider : null, + 'provider_id' => $providerId !== '' ? $providerId : null, + 'title_map' => $titleMap, + 'original_title' => $originalTitle !== '' ? $originalTitle : null, + 'year' => $year, + 'manual_title' => null, + 'manual_year' => null, + 'source' => 'auto', + ]); + } + + public function saveManual(string $kind, string $key, string $title, ?int $year): void { + $row = $this->getSubjectMeta($kind, $key); + $payload = [ + 'provider' => $row['provider'] ?? null, + 'provider_id' => $row['provider_id'] ?? null, + 'title_map' => $row['title_map'] ?? [], + 'original_title' => $row['original_title'] ?? null, + 'year' => $row['year'] ?? null, + 'manual_title' => $title !== '' ? $title : null, + 'manual_year' => $year, + 'source' => 'manual', + ]; + $this->upsertMeta($kind, $key, $payload); + } + + public function clearManual(string $kind, string $key): void { + $row = $this->getSubjectMeta($kind, $key); + if (!$row) return; + $payload = [ + 'provider' => $row['provider'] ?? null, + 'provider_id' => $row['provider_id'] ?? null, + 'title_map' => $row['title_map'] ?? [], + 'original_title' => $row['original_title'] ?? null, + 'year' => $row['year'] ?? null, + 'manual_title' => null, + 'manual_year' => null, + 'source' => 'auto', + ]; + $this->upsertMeta($kind, $key, $payload); + } + + public function getProviderLabel(string $providerId): string { + foreach ($this->providers as $p) { + if ($p->id() === $providerId) return $p->label(); + } + return $providerId; + } + + public function getUiLanguage(): string { + $all = $this->settings->getAll(); + return (string)($all['general']['language'] ?? 'en'); + } + + public function formatDisplay(?array $meta, ?string $uiLang = null): array { + $uiLang = $uiLang ?? $this->getUiLanguage(); + $titleMap = is_array($meta['title_map'] ?? null) ? $meta['title_map'] : []; + $manualTitle = (string)($meta['manual_title'] ?? ''); + $manualYear = $meta['manual_year'] ?? null; + + $titleDisplay = ''; + $titleOriginal = (string)($meta['original_title'] ?? ''); + $year = $meta['year'] ?? null; + + if (!empty($meta) && ($meta['source'] ?? '') === 'manual' && $manualTitle !== '') { + $titleDisplay = $manualTitle; + $year = $manualYear !== null ? (int)$manualYear : $year; + } else { + if (isset($titleMap[$uiLang]) && $titleMap[$uiLang] !== '') { + $titleDisplay = (string)$titleMap[$uiLang]; + } else if (count($titleMap) > 0) { + $first = array_values($titleMap)[0]; + $titleDisplay = is_string($first) ? $first : ''; + } + } + + if ($titleOriginal === '' && $titleDisplay !== '') { + $titleOriginal = $titleDisplay; + } + + $metaOut = null; + if (is_array($meta)) { + $metaOut = [ + 'provider' => $meta['provider'] ?? null, + 'provider_id' => $meta['provider_id'] ?? null, + 'source' => $meta['source'] ?? 'auto', + 'title_map' => $titleMap, + 'original_title' => $meta['original_title'] ?? null, + 'manual_title' => $meta['manual_title'] ?? null, + 'manual_year' => $meta['manual_year'] ?? null, + 'year' => $meta['year'] ?? null, + ]; + } + + return [ + 'title_display' => $titleDisplay, + 'title_original' => $titleOriginal, + 'year' => $year !== null ? (int)$year : null, + 'meta' => $metaOut, + ]; + } + + public function buildProviderUrl(string $providerId, string $externalId): string { + foreach ($this->providers as $p) { + if ($p->id() === $providerId) return $p->buildUrl($externalId); + } + return ''; + } + + private function decodeMetaRow(array $row): array { + $map = []; + if (isset($row['title_map_json'])) { + $decoded = json_decode((string)$row['title_map_json'], true); + if (is_array($decoded)) $map = $decoded; + } + $row['title_map'] = $map; + return $row; + } + + private function upsertMeta(string $kind, string $key, array $payload): void { + $json = json_encode($payload['title_map'] ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + if ($json === false) $json = '{}'; + + $this->db->exec(" + INSERT INTO media_metadata + (subject_kind, subject_key, provider, provider_id, title_map_json, original_title, year, manual_title, manual_year, source) + VALUES + (:kind, :key, :provider, :provider_id, :title_map, :original_title, :year, :manual_title, :manual_year, :source) + ON DUPLICATE KEY UPDATE + provider = VALUES(provider), + provider_id = VALUES(provider_id), + title_map_json = VALUES(title_map_json), + original_title = VALUES(original_title), + year = VALUES(year), + manual_title = VALUES(manual_title), + manual_year = VALUES(manual_year), + source = VALUES(source), + updated_at = NOW() + ", [ + ':kind' => $kind, + ':key' => $key, + ':provider' => $payload['provider'], + ':provider_id' => $payload['provider_id'], + ':title_map' => $json, + ':original_title' => $payload['original_title'], + ':year' => $payload['year'], + ':manual_title' => $payload['manual_title'], + ':manual_year' => $payload['manual_year'], + ':source' => $payload['source'], + ]); + } + + private function getMetadataSettings(): array { + $all = $this->settings->getAll(); + $meta = $all['metadata'] ?? []; + if (!is_array($meta)) $meta = []; + if (!isset($meta['enabled'])) $meta['enabled'] = false; + if (!isset($meta['languages'])) $meta['languages'] = ['de','ru','en']; + if (!isset($meta['providers'])) $meta['providers'] = []; + if (!isset($meta['provider_priority'])) $meta['provider_priority'] = ['tvdb','omdb']; + $meta = $this->applyEnvOverrides($meta); + return $meta; + } + + private function getLanguages(array $cfg): array { + $langs = is_array($cfg['languages'] ?? null) ? $cfg['languages'] : []; + $clean = []; + foreach ($langs as $l) { + $l = trim((string)$l); + if ($l !== '') $clean[] = $l; + } + if (count($clean) === 0) { + $clean = ['de','ru','en']; + } + return array_values(array_unique($clean)); + } + + private function getProviderPriority(array $cfg): array { + $list = is_array($cfg['provider_priority'] ?? null) ? $cfg['provider_priority'] : []; + $clean = []; + foreach ($list as $p) { + $p = trim((string)$p); + if ($p !== '') $clean[] = $p; + } + if (count($clean) === 0) { + $clean = ['tvdb','omdb']; + } + return $clean; + } + + /** + * @return array + */ + private function getEnabledProviders(array $cfg, array $order): array { + if (empty($cfg['enabled'])) { + return []; + } + $out = []; + foreach ($order as $pid) { + foreach ($this->providers as $p) { + if ($p->id() !== $pid) continue; + $pCfg = $cfg['providers'][$pid] ?? []; + if (!empty($pCfg['enabled'])) { + $out[$pid] = $p; + } + } + } + return $out; + } + + private function applyEnvOverrides(array $meta): array { + $envOmdb = getenv('OMDB_API_KEY') ?: ''; + $envTvdb = getenv('TVDB_API_KEY') ?: ''; + $envOmdbEnabled = getenv('OMDB_ENABLED'); + $envTvdbEnabled = getenv('TVDB_ENABLED'); + + if ($envOmdb !== '') { + $meta['providers']['omdb']['api_key'] = $envOmdb; + $meta['providers']['omdb']['enabled'] = true; + } else if ($envOmdbEnabled !== false) { + $meta['providers']['omdb']['enabled'] = filter_var($envOmdbEnabled, FILTER_VALIDATE_BOOLEAN); + } + + if ($envTvdb !== '') { + $meta['providers']['tvdb']['api_key'] = $envTvdb; + $meta['providers']['tvdb']['enabled'] = true; + } else if ($envTvdbEnabled !== false) { + $meta['providers']['tvdb']['enabled'] = filter_var($envTvdbEnabled, FILTER_VALIDATE_BOOLEAN); + } + + $envPin = getenv('TVDB_PIN') ?: ''; + if ($envPin !== '') { + $meta['providers']['tvdb']['pin'] = $envPin; + } + + return $meta; + } +} diff --git a/app/services/MkvToolnixService.php b/app/services/MkvToolnixService.php new file mode 100644 index 0000000..36c386c --- /dev/null +++ b/app/services/MkvToolnixService.php @@ -0,0 +1,274 @@ +db = $db; + $this->settings = $settings; + $this->logger = $logger; + $this->shell = $shell ?? new ShellTool(); + } + + public function isAvailable(): bool { + return $this->getMkvmergePath() !== null; + } + + public function isMkvmergeAvailable(): bool { + return $this->getMkvmergePath() !== null; + } + + public function isMkvpropeditAvailable(): bool { + return $this->getMkvpropeditPath() !== null; + } + + public function readFileData(string $path): array { + $path = rtrim($path, "/"); + if ($path === '') { + return ['ok' => false, 'error' => 'Empty path']; + } + if (!is_file($path)) { + return ['ok' => false, 'error' => 'File not found']; + } + if (!is_readable($path)) { + return ['ok' => false, 'error' => 'File not readable']; + } + + $stat = @stat($path); + if (!is_array($stat)) { + return ['ok' => false, 'error' => 'Cannot stat file']; + } + + $size = (int)$stat['size']; + $mtime = (int)$stat['mtime']; + $inode = isset($stat['ino']) ? (int)$stat['ino'] : 0; + + $prev = $this->db->fetchOne(" + SELECT size_bytes, mtime, inode, info_json + FROM media_file_meta + WHERE abs_path = :p + LIMIT 1 + ", [':p' => $path]); + + $changed = true; + if ($prev) { + $prevSize = (int)($prev['size_bytes'] ?? 0); + $prevMtime = (int)($prev['mtime'] ?? 0); + $prevInode = (int)($prev['inode'] ?? 0); + if ($prevSize === $size && $prevMtime === $mtime && $prevInode === $inode) { + $changed = false; + } + } + + if ($prev && !$changed) { + $prevInfo = (string)($prev['info_json'] ?? ''); + if ($prevInfo === '' || $prevInfo === 'null') { + $changed = true; + } + } + + $info = null; + $fromCache = false; + if ($changed) { + $info = $this->probeMkvmerge($path); + $this->upsertMeta($path, $size, $mtime, $inode, $info); + } else if (is_array($prev)) { + $cached = json_decode((string)($prev['info_json'] ?? ''), true); + if (is_array($cached)) { + $info = $cached; + $fromCache = true; + } + } + + return [ + 'ok' => true, + 'changed' => $changed, + 'from_cache' => $fromCache, + 'signature' => [ + 'size_bytes' => $size, + 'mtime' => $mtime, + 'inode' => $inode, + ], + 'file' => [ + 'path' => $path, + 'name' => basename($path), + 'ext' => strtolower(pathinfo($path, PATHINFO_EXTENSION)), + ], + 'mkvmerge' => [ + 'available' => $this->isAvailable(), + 'data' => $info, + ], + ]; + } + + private function probeMkvmerge(string $path): ?array { + if (!$this->isAvailable()) { + return null; + } + + $bin = $this->getMkvmergePath(); + if ($bin === null) return null; + $cmd = escapeshellarg($bin) . ' -J ' . escapeshellarg($path) . ' 2>/dev/null'; + $this->logCmd('debug', $cmd); + $json = $this->shell->exec($cmd); + if (!is_string($json)) { + return null; + } + + $data = json_decode($json, true); + if (is_array($data)) { + $errors = $data['errors'] ?? []; + if (is_array($errors) && count($errors) > 0) { + $this->logger?->log('warn', 'mkvmerge reported errors', ['errors' => $errors]); + return null; + } + + $container = (string)($data['container']['type'] ?? ''); + $dur = $data['container']['properties']['duration'] ?? $data['container']['duration'] ?? null; + $this->logger?->log('debug', 'mkvmerge parsed', [ + 'container' => $container, + 'duration' => $dur, + ]); + return $data; + } + $this->logger?->log('warn', 'mkvmerge JSON parse failed'); + return null; + } + + public function applyTrackEdits(string $path, array $rename, array $delete): array { + if (!$this->isMkvpropeditAvailable()) { + return ['ok' => false, 'error' => 'mkvpropedit not available']; + } + + $args = []; + foreach ($delete as $id) { + $id = (int)$id; + $args[] = '--delete'; + $args[] = 'track:' . $id; + } + + foreach ($rename as $r) { + $id = (int)($r['id'] ?? 0); + $name = (string)($r['name'] ?? ''); + if ($id <= 0 || $name === '') continue; + $args[] = '--edit'; + $args[] = 'track:' . $id; + $args[] = '--set'; + $args[] = 'name=' . $name; + } + + if (count($args) === 0) { + return ['ok' => true, 'changed' => false]; + } + + $bin = $this->getMkvpropeditPath(); + if ($bin === null) { + return ['ok' => false, 'error' => 'mkvpropedit not available']; + } + $cmd = escapeshellarg($bin) . ' ' . escapeshellarg($path); + foreach ($args as $a) { + $cmd .= ' ' . escapeshellarg($a); + } + $out = []; + $code = 0; + $this->logCmd('info', $this->shell->wrap($cmd)); + @exec($this->shell->wrap($cmd) . ' 2>&1', $out, $code); + if ($code !== 0) { + return ['ok' => false, 'error' => implode("\n", $out)]; + } + + return ['ok' => true, 'changed' => true]; + } + + public function convertToMkv(string $srcPath, string $destPath): array { + if (!$this->isMkvmergeAvailable()) { + return ['ok' => false, 'error' => 'mkvmerge not available']; + } + $bin = $this->getMkvmergePath(); + if ($bin === null) { + return ['ok' => false, 'error' => 'mkvmerge not available']; + } + $cmd = escapeshellarg($bin) . ' -o ' . escapeshellarg($destPath) . ' ' . escapeshellarg($srcPath); + $out = []; + $code = 0; + $this->logCmd('info', $this->shell->wrap($cmd)); + @exec($this->shell->wrap($cmd) . ' 2>&1', $out, $code); + if ($code !== 0) { + return ['ok' => false, 'error' => implode("\n", $out)]; + } + return ['ok' => true]; + } + + private function upsertMeta(string $path, int $size, int $mtime, int $inode, ?array $info): void { + $infoJson = $info === null ? null : json_encode($info, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + $this->db->exec(" + INSERT INTO media_file_meta (abs_path, size_bytes, mtime, inode, info_json, last_scanned_at) + VALUES (:p, :s, :m, :i, :j, NOW()) + ON DUPLICATE KEY UPDATE + size_bytes = VALUES(size_bytes), + mtime = VALUES(mtime), + inode = VALUES(inode), + info_json = VALUES(info_json), + last_scanned_at = NOW() + ", [ + ':p' => $path, + ':s' => $size, + ':m' => $mtime, + ':i' => $inode, + ':j' => $infoJson, + ]); + } + + private function getMkvmergePath(): ?string { + if ($this->mkvmergePath !== null) { + return $this->mkvmergePath; + } + $all = $this->settings->getAll(); + $tools = $all['tools'] ?? []; + $cfg = trim((string)($tools['mkvmerge_path'] ?? '')); + if ($cfg !== '' && is_file($cfg)) { + $this->mkvmergePath = $cfg; + return $cfg; + } + $path = $this->shell->which('mkvmerge'); + $this->mkvmergePath = $path !== null ? $path : null; + return $this->mkvmergePath; + } + + private function getMkvpropeditPath(): ?string { + if ($this->mkvpropeditPath !== null) { + return $this->mkvpropeditPath; + } + $all = $this->settings->getAll(); + $tools = $all['tools'] ?? []; + $cfg = trim((string)($tools['mkvpropedit_path'] ?? '')); + if ($cfg !== '' && is_file($cfg)) { + $this->mkvpropeditPath = $cfg; + return $cfg; + } + $path = $this->shell->which('mkvpropedit'); + $this->mkvpropeditPath = $path !== null ? $path : null; + return $this->mkvpropeditPath; + } + + private function logCmd(string $level, string $cmd): void { + if ($this->logger) { + $this->logger->log($level, 'Exec: ' . $cmd, ['op' => 'mkvtoolnix']); + } + } + +} diff --git a/app/services/PathTool.php b/app/services/PathTool.php new file mode 100644 index 0000000..053d3ba --- /dev/null +++ b/app/services/PathTool.php @@ -0,0 +1,85 @@ + null, + 'read' => null, + 'write' => null, + 'rename' => null, + ]; + + $notes = []; + + $path = rtrim($path, "/"); + if ($path === '') { + return [ + 'results' => $res, + 'notes' => ['Empty path'], + ]; + } + + if (in_array('exists', $checks, true)) { + $res['exists'] = file_exists($path); + if (!$res['exists']) { + $notes[] = "Path does not exist"; + } + } + + if (in_array('read', $checks, true)) { + $res['read'] = is_readable($path); + if (!$res['read']) { + $notes[] = "Not readable"; + } + } + + if (in_array('write', $checks, true)) { + $res['write'] = is_writable($path); + if (!$res['write']) { + $notes[] = "Not writable"; + } + } + + if (in_array('rename', $checks, true)) { + // Rename test: create temp file and rename it in same directory + $dir = $path; + if (!is_dir($dir)) { + $dir = dirname($path); + } + $tmp1 = $dir . "/.scmedia_test_" . bin2hex(random_bytes(6)); + $tmp2 = $tmp1 . "_renamed"; + + $ok = false; + try { + $created = @file_put_contents($tmp1, "test"); + if ($created === false) { + $notes[] = "Rename test: cannot create temp file"; + } else { + $ren = @rename($tmp1, $tmp2); + if ($ren) { + $ok = true; + @unlink($tmp2); + } else { + $notes[] = "Rename test: rename() failed"; + @unlink($tmp1); + } + } + } catch (\Throwable $e) { + $notes[] = "Rename test exception: " . $e->getMessage(); + @unlink($tmp1); + @unlink($tmp2); + } + $res['rename'] = $ok; + } + + return [ + 'results' => $res, + 'notes' => $notes, + ]; + } +} diff --git a/app/services/ScanProfilesService.php b/app/services/ScanProfilesService.php new file mode 100644 index 0000000..2c0cbe9 --- /dev/null +++ b/app/services/ScanProfilesService.php @@ -0,0 +1,158 @@ +db = $db; + $this->settings = $settings; + $this->config = $config; + } + + public function list(): array { + return $this->db->fetchAll(" + SELECT + id, sort_order, profile_type, enabled, name, root_path, max_depth, + exclude_patterns_json, include_ext_mode, include_ext_json, + last_scan_at, last_result + FROM scan_profiles + ORDER BY sort_order ASC, id ASC + "); + } + + public function create(array $p): int { + $this->validate($p); + + $exclude = json_encode($p['exclude_patterns'] ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + $include = null; + if (($p['include_ext_mode'] ?? 'default') === 'custom') { + $include = json_encode($p['include_ext'] ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + } + + $sortOrder = isset($p['sort_order']) ? (int)$p['sort_order'] : $this->nextSortOrder(); + + $this->db->exec(" + INSERT INTO scan_profiles + (sort_order, profile_type, enabled, name, root_path, max_depth, exclude_patterns_json, include_ext_mode, include_ext_json) + VALUES + (:sort_order, :ptype, :enabled, :name, :root, :depth, :exclude, :mode, :include) + ", [ + ':sort_order' => $sortOrder, + ':ptype' => (string)($p['profile_type'] ?? 'scan'), + ':enabled' => !empty($p['enabled']) ? 1 : 0, + ':name' => (string)$p['name'], + ':root' => (string)$p['root_path'], + ':depth' => (int)$p['max_depth'], + ':exclude' => $exclude ?: '[]', + ':mode' => (string)($p['include_ext_mode'] ?? 'default'), + ':include' => $include, + ]); + + $row = $this->db->fetchOne("SELECT LAST_INSERT_ID() AS id"); + return (int)($row['id'] ?? 0); + } + + public function update(int $id, array $p): void { + $this->validate($p); + + $exclude = json_encode($p['exclude_patterns'] ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + $include = null; + if (($p['include_ext_mode'] ?? 'default') === 'custom') { + $include = json_encode($p['include_ext'] ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + } + + $this->db->exec(" + UPDATE scan_profiles + SET + profile_type = :ptype, + enabled = :enabled, + name = :name, + root_path = :root, + max_depth = :depth, + exclude_patterns_json = :exclude, + include_ext_mode = :mode, + include_ext_json = :include + WHERE id = :id + ", [ + ':ptype' => (string)($p['profile_type'] ?? 'scan'), + ':enabled' => !empty($p['enabled']) ? 1 : 0, + ':name' => (string)$p['name'], + ':root' => (string)$p['root_path'], + ':depth' => (int)$p['max_depth'], + ':exclude' => $exclude ?: '[]', + ':mode' => (string)($p['include_ext_mode'] ?? 'default'), + ':include' => $include, + ':id' => $id, + ]); + } + + public function delete(int $id): void { + $this->db->exec("DELETE FROM scan_profiles WHERE id = :id", [':id' => $id]); + } + + public function reorder(array $ids): void { + $ids = array_values(array_filter(array_map('intval', $ids), fn($v) => $v > 0)); + if (count($ids) === 0) return; + + $this->db->begin(); + try { + $order = 10; + foreach ($ids as $id) { + $this->db->exec(" + UPDATE scan_profiles + SET sort_order = :o + WHERE id = :id + ", [':o' => $order, ':id' => $id]); + $order += 10; + } + $this->db->commit(); + } catch (\Throwable $e) { + $this->db->rollBack(); + throw $e; + } + } + + private function validate(array $p): void { + $name = trim((string)($p['name'] ?? '')); + $root = trim((string)($p['root_path'] ?? '')); + $depth = (int)($p['max_depth'] ?? 0); + $ptype = (string)($p['profile_type'] ?? 'scan'); + + if ($name === '') { + throw new Exception("Profile name is required"); + } + if ($root === '' || $root[0] !== '/') { + throw new Exception("Root path must be an absolute path"); + } + if (!in_array($ptype, ['scan', 'analyze'], true)) { + throw new Exception("Invalid profile type"); + } + + $fromSettings = $this->settings->getAll()['safety'] ?? []; + $hardMaxDepth = (int)($fromSettings['max_depth'] ?? ($this->config['safety']['hard_limits']['max_depth'] ?? 10)); + if ($depth < 1 || $depth > $hardMaxDepth) { + throw new Exception("Max depth out of range"); + } + + $mode = (string)($p['include_ext_mode'] ?? 'default'); + if (!in_array($mode, ['default', 'custom'], true)) { + throw new Exception("Invalid include_ext_mode"); + } + } + + private function nextSortOrder(): int { + $row = $this->db->fetchOne("SELECT MAX(sort_order) AS max_sort FROM scan_profiles"); + $max = isset($row['max_sort']) ? (int)$row['max_sort'] : 0; + return $max + 10; + } +} diff --git a/app/services/ScannerService.php b/app/services/ScannerService.php new file mode 100644 index 0000000..34c9337 --- /dev/null +++ b/app/services/ScannerService.php @@ -0,0 +1,524 @@ +db = $db; + $this->settings = $settings; + $this->profiles = $profiles; + $this->jobs = $jobs; + $this->mkvtoolnix = $mkvtoolnix; + $this->mediaLibrary = $mediaLibrary; + } + + public function runScanJob(int $jobId): array { + $all = $this->settings->getAll(); + + $scannerDefaults = $all['scanner_defaults'] ?? []; + $globalExt = is_array($scannerDefaults['video_ext'] ?? null) ? $scannerDefaults['video_ext'] : ['mkv','mp4','avi','mov','m4v','ts','m2ts','wmv']; + + $hardLimits = $this->getHardLimits(); + $defaultMaxDepth = (int)($scannerDefaults['max_depth_default'] ?? 3); + $defaultMaxFilesPerItem = (int)($scannerDefaults['max_files_per_item'] ?? 3000); + $defaultMaxItemsPerScan = (int)($scannerDefaults['max_items_per_scan'] ?? 0); + + $defaultMaxDepth = $this->cap($defaultMaxDepth, 1, (int)$hardLimits['max_depth']); + $defaultMaxFilesPerItem = $this->cap($defaultMaxFilesPerItem, 100, (int)$hardLimits['max_files_per_item']); + $defaultMaxItemsPerScan = $this->cap($defaultMaxItemsPerScan, 0, (int)$hardLimits['max_items_per_scan']); + + $profiles = $this->profiles->list(); + $profiles = array_values(array_filter($profiles, fn($p) => !empty($p['enabled']))); + + $this->jobs->log($jobId, 'info', 'Scan started'); + $this->jobs->setProgress($jobId, 0, max(1, count($profiles))); + + $totalItemsSeen = 0; + $profileIndex = 0; + + foreach ($profiles as $p) { + if ($this->jobs->cancelIfRequested($jobId)) { + $this->jobs->log($jobId, 'warn', 'Scan canceled by user'); + break; + } + $profileIndex++; + + $profileId = (int)$p['id']; + $root = (string)$p['root_path']; + $profileType = (string)($p['profile_type'] ?? 'scan'); + + $maxDepth = (int)($p['max_depth'] ?? $defaultMaxDepth); + $maxDepth = $this->cap($maxDepth, 1, (int)$hardLimits['max_depth']); + + $exclude = $this->toStringList($p['exclude_patterns'] ?? []); + $extMode = (string)($p['include_ext_mode'] ?? 'default'); + $ext = $globalExt; + if ($extMode === 'custom') { + $custom = $this->toStringList($p['include_ext'] ?? []); + if (count($custom) > 0) $ext = $custom; + } + + $this->jobs->log($jobId, 'info', "Profile #{$profileId} ({$profileType}): {$root}"); + + if ($profileType === 'analyze') { + $result = $this->analyzeProfileRoot( + $jobId, + $profileId, + $root, + $exclude, + $ext, + $maxDepth, + $defaultMaxItemsPerScan + ); + $this->jobs->log($jobId, 'info', "Analyze done. Files: {$result['files']} Changed: {$result['changed']} Cached: {$result['cached']}"); + } else { + $seenAbs = $this->scanProfileRoot( + $jobId, + $profileId, + $root, + $exclude, + $ext, + $maxDepth, + $defaultMaxFilesPerItem, + $defaultMaxItemsPerScan, + $totalItemsSeen + ); + + // Mark gone + $this->markGone($profileId, $seenAbs); + } + + $this->db->exec(" + UPDATE scan_profiles + SET last_scan_at=NOW(), last_result='ok' + WHERE id=:id + ", [':id' => $profileId]); + + $this->jobs->setProgress($jobId, $profileIndex, count($profiles)); + } + + if ($this->jobs->isCancelRequested($jobId)) { + return [ + 'profiles' => count($profiles), + 'items_seen' => $totalItemsSeen, + 'canceled' => true, + ]; + } + + $this->jobs->log($jobId, 'info', "Scan finished. Items seen: {$totalItemsSeen}"); + $this->jobs->setProgress($jobId, count($profiles), count($profiles)); + + return [ + 'profiles' => count($profiles), + 'items_seen' => $totalItemsSeen, + ]; + } + + private function analyzeProfileRoot( + int $jobId, + int $profileId, + string $root, + array $excludePatterns, + array $videoExt, + int $maxDepth, + int $maxFiles + ): array { + $root = rtrim($root, "/"); + + if ($root === '' || !is_dir($root)) { + $this->jobs->log($jobId, 'warn', "Analyze root not accessible: {$root}"); + return ['files' => 0, 'changed' => 0, 'cached' => 0]; + } + + if (!$this->mkvtoolnix->isAvailable()) { + $this->jobs->log($jobId, 'warn', "mkvmerge not available, analyze limited to inventory"); + } + + $extList = $this->normExt($videoExt); + $files = 0; + $changed = 0; + $cached = 0; + + $stack = [[ 'path' => $root, 'depth' => 0 ]]; + $stop = false; + + while (count($stack) > 0 && !$stop) { + if ($this->jobs->cancelIfRequested($jobId)) { + $this->jobs->log($jobId, 'warn', 'Analyze canceled by user'); + break; + } + $node = array_pop($stack); + $path = $node['path']; + $depth = (int)$node['depth']; + + $entries = @scandir($path); + if (!is_array($entries)) continue; + + foreach ($entries as $name) { + if ($this->jobs->cancelIfRequested($jobId)) { + $this->jobs->log($jobId, 'warn', 'Analyze canceled by user'); + $stop = true; + break; + } + if ($name === '.' || $name === '..') continue; + if ($this->isExcluded($name, $excludePatterns)) continue; + + $abs = $path . '/' . $name; + + if (is_dir($abs) && $depth < $maxDepth) { + $stack[] = ['path' => $abs, 'depth' => $depth + 1]; + continue; + } + + if (!is_file($abs)) continue; + + $ext = strtolower(pathinfo($abs, PATHINFO_EXTENSION)); + if ($ext === '' || !in_array($ext, $extList, true)) continue; + + $files++; + if ($maxFiles > 0 && $files >= $maxFiles) { + $this->jobs->log($jobId, 'warn', "Analyze max files reached: {$maxFiles}"); + $stop = true; + break; + } + + $stat = @stat($abs); + $res = null; + if ($ext === 'mkv') { + $res = $this->mkvtoolnix->readFileData($abs); + } + if (is_array($stat)) { + $this->mediaLibrary->upsertMediaFile( + $profileId, + $root, + $abs, + $stat, + ($ext === 'mkv'), + ($res && isset($res['mkvmerge']['data'])) ? $res['mkvmerge']['data'] : null + ); + } + if (is_array($res) && !empty($res['ok'])) { + if (!empty($res['changed'])) { + $changed++; + } else if (!empty($res['from_cache'])) { + $cached++; + } + } + } + } + + return ['files' => $files, 'changed' => $changed, 'cached' => $cached]; + } + + private function scanProfileRoot( + int $jobId, + int $profileId, + string $root, + array $excludePatterns, + array $videoExt, + int $maxDepth, + int $maxFilesPerItem, + int $maxItemsPerScan, + int &$totalItemsSeen + ): array { + $root = rtrim($root, "/"); + + if ($root === '' || !is_dir($root)) { + $this->jobs->log($jobId, 'warn', "Root not accessible: {$root}"); + $this->db->exec(" + UPDATE scan_profiles + SET last_scan_at=NOW(), last_result='error' + WHERE id=:id + ", [':id' => $profileId]); + return []; + } + + $entries = @scandir($root); + if (!is_array($entries)) { + $this->jobs->log($jobId, 'error', "Cannot read dir: {$root}"); + $this->db->exec(" + UPDATE scan_profiles + SET last_scan_at=NOW(), last_result='error' + WHERE id=:id + ", [':id' => $profileId]); + return []; + } + + $seen = []; + + foreach ($entries as $name) { + if ($this->jobs->cancelIfRequested($jobId)) { + $this->jobs->log($jobId, 'warn', 'Scan canceled by user'); + break; + } + if ($name === '.' || $name === '..') continue; + if ($this->isExcluded($name, $excludePatterns)) continue; + + $abs = $root . '/' . $name; + + // Respect max items per scan (if >0) + if ($maxItemsPerScan > 0 && $totalItemsSeen >= $maxItemsPerScan) { + $this->jobs->log($jobId, 'warn', "Max items per scan reached: {$maxItemsPerScan}"); + break; + } + + $info = $this->inspectItem($abs, $videoExt, $maxDepth, $maxFilesPerItem); + + $display = $name; + $structure = $info['structure']; + $videoCount = $info['video_count']; + $fileCount = $info['file_count']; + $confidence = $info['confidence']; + + $this->upsertItem($profileId, $abs, $name, $display, $structure, $confidence, $videoCount, $fileCount); + + $seen[] = $abs; + $totalItemsSeen++; + $seenAbsKey = $abs; + $seen[$seenAbsKey] = true; + } + + return array_keys($seen); + } + + private function inspectItem(string $abs, array $videoExt, int $maxDepth, int $maxFilesPerItem): array { + if (is_file($abs)) { + $ext = strtolower(pathinfo($abs, PATHINFO_EXTENSION)); + $isVideo = in_array($ext, $this->normExt($videoExt), true); + + return [ + 'structure' => 'file', + 'confidence' => $isVideo ? 70 : 10, + 'video_count' => $isVideo ? 1 : 0, + 'file_count' => 1, + ]; + } + + if (!is_dir($abs)) { + return [ + 'structure' => 'folder', + 'confidence' => 0, + 'video_count' => 0, + 'file_count' => 0, + ]; + } + + // detect dvd/bluray by marker folders + if (is_dir($abs . '/BDMV')) { + $counts = $this->countFiles($abs, $videoExt, $maxDepth, $maxFilesPerItem); + return [ + 'structure' => 'bluray', + 'confidence' => 90, + 'video_count' => $counts['video'], + 'file_count' => $counts['files'], + ]; + } + + if (is_dir($abs . '/VIDEO_TS')) { + $counts = $this->countFiles($abs, $videoExt, $maxDepth, $maxFilesPerItem); + return [ + 'structure' => 'dvd', + 'confidence' => 90, + 'video_count' => $counts['video'], + 'file_count' => $counts['files'], + ]; + } + + $counts = $this->countFiles($abs, $videoExt, $maxDepth, $maxFilesPerItem); + + return [ + 'structure' => 'folder', + 'confidence' => $counts['video'] > 0 ? 60 : 20, + 'video_count' => $counts['video'], + 'file_count' => $counts['files'], + ]; + } + + private function countFiles(string $dir, array $videoExt, int $maxDepth, int $maxFilesPerItem): array { + $videoExt = $this->normExt($videoExt); + + $files = 0; + $video = 0; + + $stack = [[ 'path' => $dir, 'depth' => 0 ]]; + + while (count($stack) > 0) { + $node = array_pop($stack); + $path = $node['path']; + $depth = (int)$node['depth']; + + $entries = @scandir($path); + if (!is_array($entries)) continue; + + foreach ($entries as $name) { + if ($name === '.' || $name === '..') continue; + + $abs = $path . '/' . $name; + + if (is_file($abs)) { + $files++; + $ext = strtolower(pathinfo($abs, PATHINFO_EXTENSION)); + if ($ext !== '' && in_array($ext, $videoExt, true)) $video++; + + if ($files >= $maxFilesPerItem) { + return ['files' => $files, 'video' => $video]; + } + continue; + } + + if (is_dir($abs) && $depth < $maxDepth) { + $stack[] = ['path' => $abs, 'depth' => $depth + 1]; + } + } + } + + return ['files' => $files, 'video' => $video]; + } + + private function upsertItem( + int $profileId, + string $absPath, + string $relPath, + string $displayName, + string $structure, + int $confidence, + int $videoCount, + int $fileCount + ): void { + $this->db->exec(" + INSERT INTO items + (scan_profile_id, abs_path, rel_path, display_name, structure, confidence, video_count, file_count, status, last_seen_at) + VALUES + (:pid, :abs, :rel, :name, :structure, :conf, :vcount, :fcount, 'active', NOW()) + ON DUPLICATE KEY UPDATE + rel_path = VALUES(rel_path), + display_name = VALUES(display_name), + structure = VALUES(structure), + confidence = VALUES(confidence), + video_count = VALUES(video_count), + file_count = VALUES(file_count), + status = 'active', + last_seen_at = NOW(), + updated_at = NOW() + ", [ + ':pid' => $profileId, + ':abs' => $absPath, + ':rel' => $relPath, + ':name' => $displayName, + ':structure' => $structure, + ':conf' => $confidence, + ':vcount' => $videoCount, + ':fcount' => $fileCount, + ]); + } + + private function markGone(int $profileId, array $seenAbs): void { + // If nothing seen, do not mark everything gone (safety) + if (count($seenAbs) === 0) return; + + // Mark items not seen in this scan as gone + // We do it by updating those with last_seen_at older than current scan moment. + // A simple approach: mark all as gone, then set active for seen list (but that’s heavy). + // Here: set gone for items where abs_path NOT IN (...) within this profile. + // For large lists, chunk it. + + $chunkSize = 200; + $seenSet = array_values($seenAbs); + + // First mark all as gone for this profile, then re-activate seen ones (fast and safe). + $this->db->exec(" + UPDATE items + SET status='gone', updated_at=NOW() + WHERE scan_profile_id=:pid + ", [':pid' => $profileId]); + + for ($i = 0; $i < count($seenSet); $i += $chunkSize) { + $chunk = array_slice($seenSet, $i, $chunkSize); + + $placeholders = []; + $params = [':pid' => $profileId]; + foreach ($chunk as $idx => $abs) { + $k = ':p' . $idx; + $placeholders[] = $k; + $params[$k] = $abs; + } + + $sql = " + UPDATE items + SET status='active', updated_at=NOW() + WHERE scan_profile_id=:pid + AND abs_path IN (" . implode(',', $placeholders) . ") + "; + + $this->db->exec($sql, $params); + } + } + + private function isExcluded(string $name, array $patterns): bool { + $n = strtolower($name); + foreach ($patterns as $p) { + $p = trim((string)$p); + if ($p === '') continue; + if (str_contains($n, strtolower($p))) return true; + } + return false; + } + + private function normExt(array $ext): array { + $out = []; + foreach ($ext as $e) { + $e = strtolower(trim((string)$e)); + if ($e === '') continue; + $out[] = $e; + } + return array_values(array_unique($out)); + } + + private function toStringList($v): array { + if (!is_array($v)) return []; + $out = []; + foreach ($v as $x) { + $x = trim((string)$x); + if ($x !== '') $out[] = $x; + } + return $out; + } + + private function getHardLimits(): array { + // config safety rails (GUI cannot exceed) + $fromSettings = $this->settings->getAll()['safety'] ?? []; + $cfg = $this->settings->getConfig(); + $limits = $fromSettings ?: ($cfg['safety']['hard_limits'] ?? []); + return [ + 'max_depth' => (int)($limits['max_depth'] ?? 10), + 'max_files_per_item' => (int)($limits['max_files_per_item'] ?? 200000), + 'max_items_per_scan' => (int)($limits['max_items_per_scan'] ?? 1000000), + ]; + } + + private function cap(int $v, int $min, int $max): int { + if ($v < $min) return $min; + if ($v > $max) return $max; + return $v; + } +} diff --git a/app/services/SettingsService.php b/app/services/SettingsService.php new file mode 100644 index 0000000..27d5bd8 --- /dev/null +++ b/app/services/SettingsService.php @@ -0,0 +1,177 @@ +db = $db; + $this->config = $config; + } + + public function getAll(): array { + $rows = $this->db->fetchAll("SELECT `key`, value_json FROM settings"); + $map = []; + foreach ($rows as $r) { + $k = (string)$r['key']; + $v = json_decode((string)$r['value_json'], true); + $map[$k] = is_array($v) ? $v : []; + } + + $system = $map['_system'] ?? ['settings_revision' => 1, 'first_run_completed' => false]; + + return [ + 'meta' => [ + 'app_id' => (string)($this->config['app']['app_id'] ?? ''), + 'env' => (string)($this->config['app']['env'] ?? 'production'), + 'debug_tools_enabled' => (bool)($this->config['app']['debug_tools_enabled'] ?? false), + 'allow_db_reset' => (bool)($this->config['app']['allow_db_reset'] ?? false), + 'settings_revision' => (int)($system['settings_revision'] ?? 1), + 'backend_version' => (string)($this->config['app']['backend_version'] ?? ''), + 'db_version' => (string)($this->config['app']['db_version'] ?? ''), + 'plugins_version' => (string)($this->config['app']['plugins_version'] ?? ''), + ], + 'general' => $map['general'] ?? [], + 'scanner_defaults' => $map['scanner_defaults'] ?? [], + 'paths' => $map['paths'] ?? [], + 'tools' => $map['tools'] ?? [], + 'logs' => $map['logs'] ?? [], + 'layout' => $map['layout'] ?? [], + 'media_rules' => $map['media_rules'] ?? [], + 'rules' => $map['rules'] ?? [], + 'sources' => $map['sources'] ?? [], + 'metadata' => $map['metadata'] ?? [], + 'exports' => $map['exports'] ?? [], + 'ui' => $map['ui'] ?? [], + 'background' => $map['background'] ?? [], + 'safety' => $map['safety'] ?? [], + 'tasks' => $map['tasks'] ?? [], + '_system' => $system, + ]; + } + + public function saveBulk(array $payload): int { + $all = $this->getAll(); + $rev = (int)($all['meta']['settings_revision'] ?? 1); + + $if = isset($payload['if_revision']) ? (int)$payload['if_revision'] : null; + if ($if !== null && $if !== $rev) { + throw new Exception("Settings revision mismatch"); + } + + $allowed = ['general', 'scanner_defaults', 'paths', 'tools', 'logs', 'layout', 'media_rules', 'rules', 'sources', 'metadata', 'exports', 'ui', 'background', 'safety', 'tasks', 'pending_tasks']; + $toSave = []; + foreach ($allowed as $k) { + if (array_key_exists($k, $payload)) { + $toSave[$k] = $payload[$k]; + } + } + + $newRev = $rev + 1; + $system = $all['_system'] ?? []; + $system['settings_revision'] = $newRev; + + $this->db->begin(); + try { + foreach ($toSave as $k => $v) { + $this->upsertJson($k, $v); + } + $this->upsertJson('_system', $system); + $this->db->commit(); + } catch (Exception $e) { + $this->db->rollBack(); + throw $e; + } + + return $newRev; + } + + public function getConfig(): array { + return $this->config; + } + + public function listSnapshots(int $limit = 50): array { + $limit = max(1, min(200, $limit)); + return $this->db->fetchAll(" + SELECT id, label, created_at, created_by + FROM settings_snapshots + ORDER BY id DESC + LIMIT {$limit} + "); + } + + public function createSnapshot(?string $label = null, ?int $createdBy = null): int { + $all = $this->getAll(); + unset($all['meta']); + $json = json_encode($all, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + if ($json === false) { + $json = '{}'; + } + $this->db->exec(" + INSERT INTO settings_snapshots (label, data_json, created_by) + VALUES (:label, :data_json, :created_by) + ", [ + ':label' => ($label !== '' ? $label : null), + ':data_json' => $json, + ':created_by' => $createdBy, + ]); + $row = $this->db->fetchOne("SELECT LAST_INSERT_ID() AS id"); + return (int)($row['id'] ?? 0); + } + + public function restoreSnapshot(int $id): void { + $row = $this->db->fetchOne("SELECT data_json FROM settings_snapshots WHERE id = :id", [':id' => $id]); + if (!$row || !isset($row['data_json'])) { + throw new Exception('Snapshot not found'); + } + $data = json_decode((string)$row['data_json'], true); + if (!is_array($data)) { + throw new Exception('Snapshot data invalid'); + } + + $system = $this->getAll()['_system'] ?? []; + $system['settings_revision'] = (int)($system['settings_revision'] ?? 1) + 1; + $data['_system'] = $system; + + $this->db->begin(); + try { + $this->db->exec("DELETE FROM settings"); + foreach ($data as $key => $value) { + $this->upsertJson((string)$key, $value); + } + $this->db->commit(); + } catch (Exception $e) { + $this->db->rollBack(); + throw $e; + } + } + + public function deleteSnapshot(int $id): void { + $this->db->exec("DELETE FROM settings_snapshots WHERE id = :id", [':id' => $id]); + } + + + private function upsertJson(string $key, $value): void { + $json = json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + if ($json === false) { + $json = '{}'; + } + + $this->db->exec(" + INSERT INTO settings (`key`, value_json) + VALUES (:k, :v) + ON DUPLICATE KEY UPDATE value_json = VALUES(value_json) + ", [ + ':k' => $key, + ':v' => $json, + ]); + } +} diff --git a/app/services/ShellTool.php b/app/services/ShellTool.php new file mode 100644 index 0000000..cd17844 --- /dev/null +++ b/app/services/ShellTool.php @@ -0,0 +1,28 @@ +envPrefix . $cmd; + } + + public function exec(string $cmd): ?string { + return @shell_exec($this->wrap($cmd)); + } + + public function execTrim(string $cmd): ?string { + $out = $this->exec($cmd); + return $out === null ? null : trim($out); + } + + public function which(string $bin): ?string { + $out = $this->execTrim('command -v ' . escapeshellarg($bin) . ' 2>/dev/null'); + return $out !== '' ? $out : null; + } +} diff --git a/app/services/SourcesService.php b/app/services/SourcesService.php new file mode 100644 index 0000000..688b213 --- /dev/null +++ b/app/services/SourcesService.php @@ -0,0 +1,163 @@ +transmission = $transmission; + $this->settings = $settings; + } + + public function list(): array { + $items = $this->transmission->list(); + return $this->applyFilters($items); + } + + private function applyFilters(array $items): array { + $rules = $this->getSourceRules(); + if (count($rules) === 0) return []; + + $out = []; + foreach ($items as $it) { + foreach ($rules as $r) { + if ($this->matchesRule($it, $r)) { + $out[] = $it; + break; + } + } + } + return $out; + } + + private function getSourceRules(): array { + $all = $this->settings->getAll(); + $rules = is_array($all['rules'] ?? null) ? $all['rules'] : []; + $out = []; + foreach ($rules as $r) { + if (!is_array($r)) continue; + if (!empty($r['enabled']) && ($r['type'] ?? '') === 'source_filter') { + $out[] = $r; + } + } + return $out; + } + + private function matchesRule(array $item, array $rule): bool { + $cfg = is_array($rule['config'] ?? null) ? $rule['config'] : []; + $source = (string)($cfg['source'] ?? ''); + if ($source !== '' && (string)($item['source'] ?? '') !== $source) return false; + + $conditions = is_array($cfg['conditions'] ?? null) ? $cfg['conditions'] : []; + if (count($conditions) === 0) { + $conditions = $this->buildLegacyConditions($cfg); + } + + if (count($conditions) === 0) { + return true; + } + + foreach ($conditions as $cond) { + if (!is_array($cond)) continue; + if (array_key_exists('enabled', $cond) && !$cond['enabled']) continue; + if (!$this->matchesCondition($item, $cond)) return false; + } + return true; + } + + private function buildLegacyConditions(array $cfg): array { + $conditions = []; + $statuses = []; + if (isset($cfg['statuses']) && is_array($cfg['statuses'])) { + $statuses = $cfg['statuses']; + } elseif (!empty($cfg['status'])) { + $statuses = [(string)$cfg['status']]; + } + if (count($statuses) > 0) { + $conditions[] = ['field' => 'status', 'op' => 'in', 'value' => $statuses]; + } + if (!empty($cfg['label'])) { + $conditions[] = ['field' => 'label', 'op' => 'contains', 'value' => (string)$cfg['label']]; + } + if (!empty($cfg['name_regex'])) { + $conditions[] = ['field' => 'name_regex', 'op' => 'regex', 'value' => (string)$cfg['name_regex']]; + } + if (!empty($cfg['path_regex'])) { + $conditions[] = ['field' => 'path_regex', 'op' => 'regex', 'value' => (string)$cfg['path_regex']]; + } + if (!empty($cfg['min_size'])) { + $conditions[] = ['field' => 'min_size', 'op' => '>=', 'value' => (int)$cfg['min_size']]; + } + return $conditions; + } + + private function matchesCondition(array $item, array $cond): bool { + $field = (string)($cond['field'] ?? ''); + $op = (string)($cond['op'] ?? ''); + $value = $cond['value'] ?? null; + + if ($field === 'status') { + $status = (string)($item['status'] ?? ''); + $vals = is_array($value) ? $value : (is_string($value) ? [$value] : []); + if ($op === 'not_in') { + return !in_array($status, $vals, true); + } + if (count($vals) === 0) return true; + return in_array($status, $vals, true); + } + + if ($field === 'label') { + $labels = is_array($item['labels'] ?? null) ? $item['labels'] : []; + $needle = (string)$value; + if ($needle === '') return true; + if ($op === 'not_contains') { + foreach ($labels as $l) { + if (stripos((string)$l, $needle) !== false) return false; + } + return true; + } + if ($op === '=' || $op === '!=') { + $has = in_array($needle, $labels, true); + return $op === '!=' ? !$has : $has; + } + foreach ($labels as $l) { + if (stripos((string)$l, $needle) !== false) return true; + } + return false; + } + + if ($field === 'name_regex') { + $name = (string)($item['name'] ?? ''); + if ($value === null || $value === '') return true; + $ok = @preg_match((string)$value, $name) === 1; + return ($op === 'not_regex') ? !$ok : $ok; + } + + if ($field === 'path_regex') { + $path = (string)($item['path'] ?? ''); + if ($value === null || $value === '') return true; + $ok = @preg_match((string)$value, $path) === 1; + return ($op === 'not_regex') ? !$ok : $ok; + } + + if ($field === 'min_size') { + $size = (int)($item['size_bytes'] ?? 0); + $val = (int)($value ?? 0); + return match ($op) { + '>' => $size > $val, + '<' => $size < $val, + '<=' => $size <= $val, + '=' => $size === $val, + '!=' => $size !== $val, + default => $size >= $val, + }; + } + + return true; + } +} diff --git a/app/services/TransmissionService.php b/app/services/TransmissionService.php new file mode 100644 index 0000000..e0faa9a --- /dev/null +++ b/app/services/TransmissionService.php @@ -0,0 +1,228 @@ +http = $http; + $this->settings = $settings; + $this->logger = $logger; + } + + public function list(): array { + $cfg = $this->getConfig(); + if (empty($cfg['enabled'])) return []; + $res = $this->rpcRequest($cfg, 'torrent-get', [ + 'fields' => ['id','name','totalSize','status','percentDone','downloadDir','labels','files'], + ]); + if (!$res['ok'] || !is_array($res['data'])) { + return []; + } + $rows = is_array($res['data']['arguments']['torrents'] ?? null) ? $res['data']['arguments']['torrents'] : []; + $out = []; + foreach ($rows as $t) { + if (!is_array($t)) continue; + $files = is_array($t['files'] ?? null) ? $t['files'] : []; + $fileCount = count($files); + $contentType = ($fileCount > 1) ? 'folder' : 'file'; + $out[] = [ + 'id' => (int)($t['id'] ?? 0), + 'name' => (string)($t['name'] ?? ''), + 'size_bytes' => (int)($t['totalSize'] ?? 0), + 'status' => $this->statusLabel((int)($t['status'] ?? 0), (float)($t['percentDone'] ?? 0)), + 'percent_done' => (float)($t['percentDone'] ?? 0), + 'path' => (string)($t['downloadDir'] ?? ''), + 'labels' => $t['labels'] ?? [], + 'source' => 'transmission', + 'file_count' => $fileCount, + 'content_type' => $contentType, + ]; + } + return $out; + } + + public function test(array $cfg): array { + $cfg = $this->normalizeConfig($cfg); + $res = $this->rpcRequest($cfg, 'session-get', []); + if (!$res['ok']) { + $status = $res['status'] ?? null; + if ($status === 401) { + return ['ok' => false, 'error' => 'unauthorized']; + } + if ($status === 403) { + return ['ok' => false, 'error' => 'forbidden']; + } + return ['ok' => false, 'error' => $res['error'] ?? 'request failed']; + } + return ['ok' => true]; + } + + public function detail(int $id): array { + $cfg = $this->getConfig(); + if (empty($cfg['enabled'])) { + return ['ok' => false, 'error' => 'disabled']; + } + $res = $this->rpcRequest($cfg, 'torrent-get', [ + 'ids' => [$id], + 'fields' => [ + 'id','name','totalSize','status','percentDone','downloadDir','labels', + 'rateDownload','rateUpload','addedDate','doneDate','eta','uploadedEver','downloadedEver', + 'files','fileStats' + ], + ]); + if (!$res['ok'] || !is_array($res['data'])) { + return ['ok' => false, 'error' => $res['error'] ?? 'rpc failed']; + } + $rows = is_array($res['data']['arguments']['torrents'] ?? null) ? $res['data']['arguments']['torrents'] : []; + if (count($rows) === 0) { + return ['ok' => false, 'error' => 'not found']; + } + $t = $rows[0]; + $files = is_array($t['files'] ?? null) ? $t['files'] : []; + $stats = is_array($t['fileStats'] ?? null) ? $t['fileStats'] : []; + $fileList = []; + foreach ($files as $idx => $f) { + if (!is_array($f)) continue; + $stat = $stats[$idx] ?? []; + $length = (int)($f['length'] ?? 0); + $done = (int)($stat['bytesCompleted'] ?? 0); + $pct = $length > 0 ? round(($done / $length) * 100, 1) : 0.0; + $fileList[] = [ + 'path' => (string)($f['name'] ?? ''), + 'size_bytes' => $length, + 'bytes_done' => $done, + 'percent_done' => $pct, + 'wanted' => !empty($stat['wanted']), + 'priority' => (int)($stat['priority'] ?? 0), + ]; + } + + $core = [ + 'id' => (int)($t['id'] ?? 0), + 'name' => (string)($t['name'] ?? ''), + 'status' => $this->statusLabel((int)($t['status'] ?? 0), (float)($t['percentDone'] ?? 0)), + 'percent_done' => (float)($t['percentDone'] ?? 0), + 'size_bytes' => (int)($t['totalSize'] ?? 0), + 'source' => 'transmission', + ]; + + $fields = [ + ['key' => 'download_dir', 'label' => 'Download dir', 'type' => 'text', 'value' => (string)($t['downloadDir'] ?? '')], + ['key' => 'labels', 'label' => 'Labels', 'type' => 'list', 'value' => $t['labels'] ?? []], + ['key' => 'rate_download', 'label' => 'Download speed', 'type' => 'speed', 'value' => (int)($t['rateDownload'] ?? 0)], + ['key' => 'rate_upload', 'label' => 'Upload speed', 'type' => 'speed', 'value' => (int)($t['rateUpload'] ?? 0)], + ['key' => 'added_date', 'label' => 'Added', 'type' => 'date', 'value' => (int)($t['addedDate'] ?? 0)], + ['key' => 'done_date', 'label' => 'Completed', 'type' => 'date', 'value' => (int)($t['doneDate'] ?? 0)], + ['key' => 'eta', 'label' => 'ETA', 'type' => 'seconds', 'value' => (int)($t['eta'] ?? 0)], + ['key' => 'uploaded', 'label' => 'Uploaded', 'type' => 'bytes', 'value' => (int)($t['uploadedEver'] ?? 0)], + ['key' => 'downloaded', 'label' => 'Downloaded', 'type' => 'bytes', 'value' => (int)($t['downloadedEver'] ?? 0)], + ]; + + return ['ok' => true, 'core' => $core, 'fields' => $fields, 'files' => $fileList, 'raw' => $t]; + } + + private function getConfig(): array { + $all = $this->settings->getAll(); + $sources = $all['sources'] ?? []; + $cfg = is_array($sources['transmission'] ?? null) ? $sources['transmission'] : []; + return $this->normalizeConfig($cfg); + } + + private function normalizeConfig(array $cfg): array { + return [ + 'enabled' => !empty($cfg['enabled']), + 'protocol' => (string)($cfg['protocol'] ?? 'http'), + 'host' => (string)($cfg['host'] ?? ''), + 'port' => (int)($cfg['port'] ?? 9091), + 'path' => (string)($cfg['path'] ?? '/transmission/rpc'), + 'username' => (string)($cfg['username'] ?? ''), + 'password' => (string)($cfg['password'] ?? ''), + ]; + } + + private function rpcRequest(array $cfg, string $method, array $args): array { + $url = $this->buildUrl($cfg); + $this->logger?->log('debug', 'Transmission config', [ + 'protocol' => $cfg['protocol'] ?? null, + 'host' => $cfg['host'] ?? null, + 'port' => $cfg['port'] ?? null, + 'path' => $cfg['path'] ?? null, + 'has_auth' => (($cfg['username'] ?? '') !== '' || ($cfg['password'] ?? '') !== ''), + ]); + $headers = $this->buildHeaders($cfg, null); + $payload = ['method' => $method, 'arguments' => $args]; + + $this->logger?->log('debug', 'Transmission RPC request', [ + 'method' => $method, + 'url' => $this->sanitizeUrl($url), + ]); + + $res = $this->http->postJson($url, $payload, $headers); + if (($res['status'] ?? 0) === 409) { + $sid = (string)($res['headers']['x-transmission-session-id'] ?? ''); + $this->logger?->log('debug', 'Transmission session id required', ['has_sid' => $sid !== '']); + if ($sid !== '') { + $headers = $this->buildHeaders($cfg, $sid); + $res = $this->http->postJson($url, $payload, $headers); + } + } + + if (empty($res['ok']) || !is_array($res['data'])) { + $this->logger?->log('warn', 'Transmission RPC failed', [ + 'method' => $method, + 'status' => $res['status'] ?? null, + 'error' => $res['error'] ?? null, + ]); + return [ + 'ok' => false, + 'error' => $res['error'] ?? 'rpc failed', + 'status' => $res['status'] ?? null, + ]; + } + + if (isset($res['data']['result']) && $res['data']['result'] !== 'success') { + $this->logger?->log('warn', 'Transmission RPC result not success', ['result' => $res['data']['result'] ?? null]); + } + return ['ok' => true, 'data' => $res['data']]; + } + + private function buildUrl(array $cfg): string { + $host = $cfg['host'] !== '' ? $cfg['host'] : 'localhost'; + $path = $cfg['path'] !== '' ? $cfg['path'] : '/transmission/rpc'; + if ($path[0] !== '/') $path = '/' . $path; + return $cfg['protocol'] . '://' . $host . ':' . $cfg['port'] . $path; + } + + private function buildHeaders(array $cfg, ?string $sessionId): array { + $headers = ['Content-Type: application/json']; + if ($sessionId) { + $headers[] = 'X-Transmission-Session-Id: ' . $sessionId; + } + if ($cfg['username'] !== '' || $cfg['password'] !== '') { + $basic = base64_encode($cfg['username'] . ':' . $cfg['password']); + $headers[] = 'Authorization: Basic ' . $basic; + } + return $headers; + } + + private function statusLabel(int $status, float $percent): string { + if ($percent >= 1.0) return 'completed'; + if ($status === 1 || $status === 2) return 'checking'; + if ($status === 3) return 'queued'; + if ($status === 4) return 'downloading'; + if ($status === 6) return 'seeding'; + if ($status === 0) return 'stopped'; + return 'unknown'; + } + + private function sanitizeUrl(string $url): string { + return $url; + } +} diff --git a/app/services/export/ExporterInterface.php b/app/services/export/ExporterInterface.php new file mode 100644 index 0000000..dae598e --- /dev/null +++ b/app/services/export/ExporterInterface.php @@ -0,0 +1,14 @@ +writeNfo($outPath, 'movie', $meta); + } + + public function exportSeries(string $seriesPath, array $meta): array { + $outPath = rtrim($seriesPath, '/') . '/tvshow.nfo'; + return $this->writeNfo($outPath, 'tvshow', $meta); + } + + private function writeNfo(string $path, string $root, array $meta): array { + $title = (string)($meta['title'] ?? ''); + $original = (string)($meta['original_title'] ?? ''); + $year = $meta['year'] ?? null; + $provider = (string)($meta['provider'] ?? ''); + $providerId = (string)($meta['provider_id'] ?? ''); + $providerUrl = (string)($meta['provider_url'] ?? ''); + + $xml = "\n"; + $xml .= "<{$root}>\n"; + if ($title !== '') $xml .= " " . htmlspecialchars($title, ENT_QUOTES) . "\n"; + if ($original !== '') $xml .= " " . htmlspecialchars($original, ENT_QUOTES) . "\n"; + if (is_int($year) || is_numeric($year)) $xml .= " " . (int)$year . "\n"; + if ($provider !== '' && $providerId !== '') { + $xml .= " " . + htmlspecialchars($providerId, ENT_QUOTES) . "\n"; + } + if ($providerUrl !== '') { + $xml .= " " . htmlspecialchars($providerUrl, ENT_QUOTES) . "\n"; + } + $xml .= "\n"; + + $ok = @file_put_contents($path, $xml) !== false; + return ['ok' => $ok, 'path' => $path, 'error' => $ok ? null : 'write failed']; + } +} diff --git a/app/services/export/KodiExporter.php b/app/services/export/KodiExporter.php new file mode 100644 index 0000000..61ae489 --- /dev/null +++ b/app/services/export/KodiExporter.php @@ -0,0 +1,57 @@ +writeNfo($outPath, 'movie', $meta); + } + + public function exportSeries(string $seriesPath, array $meta): array { + $outPath = rtrim($seriesPath, '/') . '/tvshow.nfo'; + return $this->writeNfo($outPath, 'tvshow', $meta); + } + + private function writeNfo(string $path, string $root, array $meta): array { + $title = (string)($meta['title'] ?? ''); + $original = (string)($meta['original_title'] ?? ''); + $year = $meta['year'] ?? null; + $provider = (string)($meta['provider'] ?? ''); + $providerId = (string)($meta['provider_id'] ?? ''); + $providerUrl = (string)($meta['provider_url'] ?? ''); + + $xml = "\n"; + $xml .= "<{$root}>\n"; + if ($title !== '') $xml .= " " . htmlspecialchars($title, ENT_QUOTES) . "\n"; + if ($original !== '') $xml .= " " . htmlspecialchars($original, ENT_QUOTES) . "\n"; + if (is_int($year) || is_numeric($year)) $xml .= " " . (int)$year . "\n"; + if ($provider !== '' && $providerId !== '') { + $xml .= " " . + htmlspecialchars($providerId, ENT_QUOTES) . "\n"; + } + if ($providerUrl !== '') { + $xml .= " " . htmlspecialchars($providerUrl, ENT_QUOTES) . "\n"; + } + $xml .= "\n"; + + $ok = @file_put_contents($path, $xml) !== false; + return ['ok' => $ok, 'path' => $path, 'error' => $ok ? null : 'write failed']; + } +} diff --git a/app/services/metadata/MetadataProvider.php b/app/services/metadata/MetadataProvider.php new file mode 100644 index 0000000..5ce3535 --- /dev/null +++ b/app/services/metadata/MetadataProvider.php @@ -0,0 +1,14 @@ +http = $http; + $this->logger = $logger; + } + + public function id(): string { + return 'omdb'; + } + + public function label(): string { + return 'IMDb (OMDb)'; + } + + public function supportsType(string $type): bool { + return in_array($type, ['movie','series'], true); + } + + public function buildUrl(string $externalId): string { + return $externalId !== '' ? ('https://www.imdb.com/title/' . $externalId) : ''; + } + + public function search(string $query, string $type, ?int $year, string $lang, array $config): array { + $apiKey = (string)($config['api_key'] ?? ''); + if ($apiKey === '') { + $this->logger?->log('warn', 'OMDb API key missing'); + return []; + } + $base = (string)($config['base_url'] ?? 'https://www.omdbapi.com/'); + $q = [ + 'apikey' => $apiKey, + 's' => $query, + ]; + if ($type !== '') { + $q['type'] = $type; + } + if ($year !== null && $year > 1800 && $year < 2100) { + $q['y'] = (string)$year; + } + $url = rtrim($base, '/') . '/?' . http_build_query($q); + $this->logger?->log('debug', 'OMDb request', ['url' => $this->sanitizeUrl($url)]); + $res = $this->http->getJson($url); + if (empty($res['ok']) || !is_array($res['data'])) { + $this->logger?->log('error', 'OMDb request failed', [ + 'status' => $res['status'] ?? null, + 'error' => $res['error'] ?? null, + ]); + return []; + } + $data = $res['data']; + if (!empty($data['Response']) && $data['Response'] === 'False') { + $this->logger?->log('warn', 'OMDb response false', ['error' => $data['Error'] ?? null]); + return []; + } + $items = is_array($data['Search'] ?? null) ? $data['Search'] : []; + $out = []; + foreach ($items as $it) { + if (!is_array($it)) continue; + $id = (string)($it['imdbID'] ?? ''); + $title = (string)($it['Title'] ?? ''); + $yearStr = (string)($it['Year'] ?? ''); + $yr = null; + if (preg_match('/\d{4}/', $yearStr, $m)) { + $yr = (int)$m[0]; + } + $poster = (string)($it['Poster'] ?? ''); + if ($poster === 'N/A') $poster = ''; + $out[] = [ + 'provider' => $this->id(), + 'provider_name' => $this->label(), + 'provider_id' => $id, + 'provider_url' => $this->buildUrl($id), + 'title_map' => [$lang => $title], + 'original_title' => $title, + 'year' => $yr, + 'poster' => $poster, + 'type' => (string)($it['Type'] ?? $type), + ]; + } + return $out; + } + + private function sanitizeUrl(string $url): string { + $debugKeys = filter_var(getenv('DEBUG_KEYS') ?: 'false', FILTER_VALIDATE_BOOLEAN); + if ($debugKeys) return $url; + return preg_replace('/apikey=[^&]+/i', 'apikey=DUMMY', $url) ?? $url; + } +} diff --git a/app/services/metadata/TvdbProvider.php b/app/services/metadata/TvdbProvider.php new file mode 100644 index 0000000..53966bf --- /dev/null +++ b/app/services/metadata/TvdbProvider.php @@ -0,0 +1,127 @@ +http = $http; + $this->logger = $logger; + } + + public function id(): string { + return 'tvdb'; + } + + public function label(): string { + return 'TVDB'; + } + + public function supportsType(string $type): bool { + return in_array($type, ['movie','series'], true); + } + + public function buildUrl(string $externalId): string { + return $externalId !== '' ? ('https://thetvdb.com/?tab=series&id=' . $externalId) : ''; + } + + public function search(string $query, string $type, ?int $year, string $lang, array $config): array { + $apiKey = (string)($config['api_key'] ?? ''); + if ($apiKey === '') { + $this->logger?->log('warn', 'TVDB API key missing'); + return []; + } + $token = $this->login($apiKey, (string)($config['pin'] ?? '')); + if ($token === '') { + $this->logger?->log('warn', 'TVDB login failed'); + return []; + } + + $q = [ + 'query' => $query, + 'type' => ($type === 'movie') ? 'movie' : 'series', + ]; + if ($year !== null && $year > 1800 && $year < 2100) { + $q['year'] = (string)$year; + } + $url = 'https://api4.thetvdb.com/v4/search?' . http_build_query($q); + $this->logger?->log('debug', 'TVDB search request', ['url' => $this->sanitizeUrl($url)]); + $headers = [ + 'Authorization: Bearer ' . ($this->shouldLogKeys() ? $token : 'DUMMY'), + 'Accept-Language: ' . $lang, + ]; + $res = $this->http->getJson($url, $headers); + if (empty($res['ok']) || !is_array($res['data'])) { + $this->logger?->log('error', 'TVDB search failed', [ + 'status' => $res['status'] ?? null, + 'error' => $res['error'] ?? null, + ]); + return []; + } + $items = is_array($res['data']['data'] ?? null) ? $res['data']['data'] : []; + $out = []; + foreach ($items as $it) { + if (!is_array($it)) continue; + $id = (string)($it['tvdb_id'] ?? $it['id'] ?? ''); + $title = (string)($it['name'] ?? $it['title'] ?? ''); + $yr = null; + if (isset($it['year']) && is_numeric($it['year'])) { + $yr = (int)$it['year']; + } else if (isset($it['firstAired']) && preg_match('/\d{4}/', (string)$it['firstAired'], $m)) { + $yr = (int)$m[0]; + } + $image = (string)($it['image_url'] ?? $it['image'] ?? ''); + $out[] = [ + 'provider' => $this->id(), + 'provider_name' => $this->label(), + 'provider_id' => $id, + 'provider_url' => $this->buildUrl($id), + 'title_map' => [$lang => $title], + 'original_title' => $title, + 'year' => $yr, + 'poster' => $image, + 'type' => (string)($it['type'] ?? $type), + ]; + } + return $out; + } + + private function login(string $apiKey, string $pin): string { + $payload = ['apikey' => $apiKey]; + if ($pin !== '') $payload['pin'] = $pin; + if ($this->logger) { + $safe = $payload; + if (!$this->shouldLogKeys()) { + $safe['apikey'] = 'DUMMY'; + if (isset($safe['pin'])) $safe['pin'] = 'DUMMY'; + } + $this->logger->log('debug', 'TVDB login request', ['payload' => $safe]); + } + $res = $this->http->postJson('https://api4.thetvdb.com/v4/login', $payload); + if (empty($res['ok']) || !is_array($res['data'])) { + $this->logger?->log('error', 'TVDB login request failed', [ + 'status' => $res['status'] ?? null, + 'error' => $res['error'] ?? null, + ]); + return ''; + } + $token = (string)($res['data']['data']['token'] ?? ''); + return $token; + } + + private function shouldLogKeys(): bool { + return filter_var(getenv('DEBUG_KEYS') ?: 'false', FILTER_VALIDATE_BOOLEAN); + } + + private function sanitizeUrl(string $url): string { + return $url; + } +} diff --git a/app/views/pages/account.php b/app/views/pages/account.php new file mode 100644 index 0000000..bfe3395 --- /dev/null +++ b/app/views/pages/account.php @@ -0,0 +1,119 @@ + + + + + + + <?php echo htmlspecialchars($t('account.page_title', 'scMedia / Account'), ENT_QUOTES); ?> + + + + + + + +
+
+
+

+
+ +
+ +
+
+

+
+
+ + + + +
+
+ +
+
+

+
+
+ + + +
+ + +
+
+
+
+ + + + + + + + + + diff --git a/app/views/pages/index.php b/app/views/pages/index.php new file mode 100644 index 0000000..9b25e72 --- /dev/null +++ b/app/views/pages/index.php @@ -0,0 +1,159 @@ + + + + + + + <?php echo htmlspecialchars($t('app.title', 'scMedia'), ENT_QUOTES); ?> + + + + + + + +
+
+ + + +
+ '', 'i18n' => '', 'key' => '', 'filter' => null], + ['label' => $t('grid.type', 'Type'), 'i18n' => 'grid.type', 'key' => 'type', 'filter' => ['type' => 'text', 'ops' => ['like','eq']]], + ['label' => $t('grid.name', 'Name'), 'i18n' => 'grid.name', 'sort' => 'name', 'key' => 'name', 'filter' => ['type' => 'text', 'ops' => ['like','eq','empty']]], + ['label' => $t('grid.year', 'Year'), 'i18n' => 'grid.year', 'key' => 'year', 'filter' => ['type' => 'number', 'ops' => ['eq','between','gt','lt']]], + ['label' => $t('grid.status', 'Status'), 'i18n' => 'grid.status', 'key' => 'status', 'filter' => ['type' => 'text', 'ops' => ['like','eq']]], + ['label' => $t('grid.issues', 'Issues'), 'i18n' => 'grid.issues', 'key' => 'issues', 'filter' => ['type' => 'text', 'ops' => ['like','eq','empty']]], + ]; + $attrs = ['data-table' => 'media']; + require __DIR__ . '/../partials/table.php'; + ?> + $t('sources.source', 'Source'), 'i18n' => 'sources.source', 'key' => 'source', 'filter' => ['type' => 'select', 'control' => 'select', 'options' => [ + ['value' => 'transmission', 'label' => 'Transmission'], + ]]], + ['label' => $t('sources.type', 'Type'), 'i18n' => 'sources.type', 'key' => 'type', 'filter' => ['type' => 'select', 'control' => 'select', 'options' => [ + ['value' => 'folder', 'label' => $t('sources.type.folder', 'Folder'), 'i18n' => 'sources.type.folder'], + ['value' => 'file', 'label' => $t('sources.type.file', 'File'), 'i18n' => 'sources.type.file'], + ]]], + ['label' => $t('sources.name', 'Name'), 'i18n' => 'sources.name', 'sort' => 'name', 'key' => 'name', 'filter' => ['type' => 'text', 'ops' => ['like','eq','empty']]], + ['label' => $t('sources.size', 'Size'), 'i18n' => 'sources.size', 'sort' => 'size', 'class' => 'align-right', 'key' => 'size', 'filter' => null], + ['label' => $t('sources.status', 'Status'), 'i18n' => 'sources.status', 'sort' => 'status', 'class' => 'align-center', 'key' => 'status', 'filter' => ['type' => 'select', 'control' => 'select', 'options' => [ + ['value' => 'checking', 'label' => 'checking', 'i18n' => 'sources.status.checking'], + ['value' => 'queued', 'label' => 'queued', 'i18n' => 'sources.status.queued'], + ['value' => 'downloading', 'label' => $t('sources.status.downloading', 'downloading'), 'i18n' => 'sources.status.downloading'], + ['value' => 'seeding', 'label' => $t('sources.status.seeding', 'seeding'), 'i18n' => 'sources.status.seeding'], + ['value' => 'stopped', 'label' => $t('sources.status.stopped', 'stopped'), 'i18n' => 'sources.status.stopped'], + ['value' => 'completed', 'label' => $t('sources.status.completed', 'completed'), 'i18n' => 'sources.status.completed'], + ['value' => 'unknown', 'label' => $t('sources.status.unknown', 'unknown'), 'i18n' => 'sources.status.unknown'], + ]]], + ['label' => $t('sources.progress', 'Progress'), 'i18n' => 'sources.progress', 'class' => 'align-right', 'key' => 'progress', 'filter' => null], + ]; + $attrs = ['data-table' => 'sources', 'data-view-config' => '1']; + require __DIR__ . '/../partials/table.php'; + ?> +
+ + + +
+

+
+ +

+      
+        
+        
+      
+    
+
+ + +
+
+

+ +
+
+
+
+ +

+      
+ + + + +
+
+ + +
+

Table view

+
+ + + + + + + + + + + + +
OnColumnWidthHeader alignCell alignOrder
+
+ + + + + +
+
+ + + +
+

+

+      
+        
+      
+    
+
+ + + + + + + + + + + + + diff --git a/app/views/pages/login.php b/app/views/pages/login.php new file mode 100644 index 0000000..abacb5f --- /dev/null +++ b/app/views/pages/login.php @@ -0,0 +1,83 @@ + + + + + + + <?php echo htmlspecialchars($t('auth.page_title', 'scMedia / Login'), ENT_QUOTES); ?> + + + + +
+
+
+

+
+
+ + +
+
+
+

+ +
+ + + + + +
+ + + + + + +
+
+ + + + + + diff --git a/app/views/pages/settings.php b/app/views/pages/settings.php new file mode 100644 index 0000000..3b9954b --- /dev/null +++ b/app/views/pages/settings.php @@ -0,0 +1,786 @@ + + + + + + + <?php echo htmlspecialchars($t('settings.page_title', 'scmedia / Settings'), ENT_QUOTES); ?> + + + + + + + +
+ + +
+ +
+
+

+ +
+ +
+ + + '', 'i18n' => '', 'key' => '', 'filter' => null], + ['label' => $t('settings.scan_profiles.th_on', 'On'), 'i18n' => 'settings.scan_profiles.th_on', 'key' => 'enabled', 'filter' => ['type' => 'boolean']], + ['label' => $t('settings.scan_profiles.th_type', 'Type'), 'i18n' => 'settings.scan_profiles.th_type', 'key' => 'profile_type', 'filter' => ['type' => 'text', 'ops' => ['like','eq']]], + ['label' => $t('settings.scan_profiles.th_name', 'Name'), 'i18n' => 'settings.scan_profiles.th_name', 'sort' => 'name', 'key' => 'name', 'filter' => ['type' => 'text', 'ops' => ['like','eq','empty']]], + ['label' => $t('settings.scan_profiles.th_root', 'Root path'), 'i18n' => 'settings.scan_profiles.th_root', 'key' => 'root_path', 'filter' => ['type' => 'text', 'ops' => ['like','eq','empty']]], + ['label' => $t('settings.scan_profiles.th_depth', 'Depth'), 'i18n' => 'settings.scan_profiles.th_depth', 'key' => 'max_depth', 'filter' => ['type' => 'number', 'ops' => ['eq','between','gt','lt']]], + ['label' => $t('settings.scan_profiles.th_excludes', 'Excludes'), 'i18n' => 'settings.scan_profiles.th_excludes', 'key' => 'exclude', 'filter' => ['type' => 'text', 'ops' => ['like','eq','empty']]], + ['label' => $t('settings.scan_profiles.th_ext', 'Ext'), 'i18n' => 'settings.scan_profiles.th_ext', 'key' => 'ext', 'filter' => ['type' => 'text', 'ops' => ['like','eq','empty']]], + ['label' => $t('settings.scan_profiles.th_last_scan', 'Last scan'), 'i18n' => 'settings.scan_profiles.th_last_scan', 'key' => 'last_scan', 'filter' => ['type' => 'date', 'ops' => ['eq','between']]], + ['label' => $t('settings.scan_profiles.th_result', 'Result'), 'i18n' => 'settings.scan_profiles.th_result', 'key' => 'last_result', 'filter' => ['type' => 'text', 'ops' => ['like','eq','empty']]], + ['label' => '', 'i18n' => '', 'key' => '', 'filter' => null], + ]; + $attrs = ['data-table' => 'profiles']; + require __DIR__ . '/../partials/table.php'; + ?> +
+ +
+

+
+ + + + +
+
+
+ + +
+
+

+ +
+ +
+ $t('settings.library_layout.th_type', 'Type'), 'i18n' => 'settings.library_layout.th_type', 'key' => 'type', 'filter' => ['type' => 'text', 'ops' => ['like','eq']]], + ['label' => $t('settings.library_layout.th_path', 'Path'), 'i18n' => 'settings.library_layout.th_path', 'sort' => 'path', 'key' => 'path', 'filter' => ['type' => 'text', 'ops' => ['like','eq','empty']]], + ['label' => $t('settings.library_layout.th_status', 'Status'), 'i18n' => 'settings.library_layout.th_status', 'key' => 'status', 'filter' => ['type' => 'text', 'ops' => ['like','eq']]], + ['label' => '', 'i18n' => '', 'key' => '', 'filter' => null], + ]; + $attrs = ['data-table' => 'roots']; + require __DIR__ . '/../partials/table.php'; + ?> +
+
+ +
+ + +
+
+

+
+ + +
+
+ +
+ $t('settings.plugins.th_name', 'Plugin'), 'i18n' => 'settings.plugins.th_name', 'sort' => 'name', 'key' => 'name', 'filter' => ['type' => 'text', 'ops' => ['like','eq','empty']]], + ['label' => $t('settings.plugins.th_type', 'Type'), 'i18n' => 'settings.plugins.th_type', 'key' => 'type', 'filter' => ['type' => 'text', 'ops' => ['like','eq']]], + ['label' => $t('settings.plugins.th_status', 'Status'), 'i18n' => 'settings.plugins.th_status', 'key' => 'status', 'filter' => ['type' => 'text', 'ops' => ['like','eq']]], + ['label' => '', 'i18n' => '', 'key' => '', 'filter' => null], + ]; + $attrs = ['data-table' => 'plugins']; + require __DIR__ . '/../partials/table.php'; + ?> +
+
+
+ + +
+
+

+ +
+
+ $t('settings.tasks.th_name', 'Task'), 'i18n' => 'settings.tasks.th_name', 'sort' => 'name', 'key' => 'name', 'filter' => ['type' => 'text', 'ops' => ['like','eq','empty']]], + ['label' => $t('settings.tasks.th_sources', 'Sources'), 'i18n' => 'settings.tasks.th_sources', 'key' => 'sources', 'filter' => ['type' => 'text', 'ops' => ['like','eq','empty']]], + ['label' => $t('settings.tasks.th_actions', 'Actions'), 'i18n' => 'settings.tasks.th_actions', 'key' => 'actions', 'filter' => ['type' => 'text', 'ops' => ['like','eq','empty']]], + ['label' => $t('settings.tasks.th_status', 'Status'), 'i18n' => 'settings.tasks.th_status', 'key' => 'status', 'filter' => ['type' => 'text', 'ops' => ['like','eq']]], + ['label' => '', 'i18n' => '', 'key' => '', 'filter' => null], + ]; + $attrs = ['data-table' => 'tasks']; + require __DIR__ . '/../partials/table.php'; + ?> +
+
+
+ + +
+
+

+
+ + +
+
+ +
+ $t('rules.th.name', 'Name'), 'i18n' => 'rules.th.name', 'sort' => 'name', 'key' => 'name', 'filter' => ['type' => 'text', 'ops' => ['like','eq','empty']]], + ['label' => $t('rules.th.type', 'Type'), 'i18n' => 'rules.th.type', 'sort' => 'type', 'key' => 'type', 'filter' => ['type' => 'text', 'ops' => ['like','eq']]], + ['label' => $t('rules.th.summary', 'Summary'), 'i18n' => 'rules.th.summary', 'key' => 'summary', 'filter' => ['type' => 'text', 'ops' => ['like','eq','empty']]], + ['label' => $t('rules.th.status', 'Status'), 'i18n' => 'rules.th.status', 'key' => 'status', 'filter' => ['type' => 'text', 'ops' => ['like','eq']]], + ['label' => '', 'i18n' => '', 'key' => '', 'filter' => null], + ]; + $attrs = ['data-table' => 'rules']; + require __DIR__ . '/../partials/table.php'; + ?> +
+
+ + +
+
+

+
+ +
+

+
+ + + + + +
+
+ +
+

+
+ + + + + + + +
+
+ +
+

+
+ +
+
+ +
+

+
+ + + +
+
+ +
+

+
+ + + + +
+
+ +
+

+
+ + +
+
+ + + + + + + + + + +
+
+
+
+ +
+

+
+
+ + +
+
+

+
+ + +
+
+
+ $t('settings.tools.th_name', 'Tool'), 'i18n' => 'settings.tools.th_name', 'sort' => 'name', 'key' => 'name', 'filter' => ['type' => 'text', 'ops' => ['like','eq','empty']]], + ['label' => $t('settings.tools.th_path', 'Path'), 'i18n' => 'settings.tools.th_path', 'key' => 'path', 'filter' => ['type' => 'text', 'ops' => ['like','eq','empty']]], + ['label' => '', 'i18n' => '', 'key' => '', 'filter' => null], + ]; + $attrs = ['data-table' => 'tools']; + require __DIR__ . '/../partials/table.php'; + ?> +
+
+
+ + +
+
+

+
+
+
+ + +
+ +
+
+ +
+ + +
+
+ +
+ +
+ + +
+
+
+ + + + +
+
+ '', 'key' => '', 'filter' => null], + ['label' => $t('settings.logs.when', 'When'), 'i18n' => 'settings.logs.when', 'key' => 'ts', 'sort' => 'ts', 'filter' => ['type' => 'date', 'ops' => ['eq','between']]], + ['label' => $t('settings.logs.level', 'Level'), 'i18n' => 'settings.logs.level', 'key' => 'level', 'sort' => 'level', 'filter' => ['type' => 'select', 'options' => ['debug','info','warn','error']]], + ['label' => $t('settings.logs.message', 'Message'), 'i18n' => 'settings.logs.message', 'key' => 'message', 'sort' => 'message', 'filter' => ['type' => 'text', 'ops' => ['like','eq','empty']]], + ['label' => $t('settings.logs.context', 'Context'), 'i18n' => 'settings.logs.context', 'key' => 'context_json', 'sort' => 'context_json', 'filter' => ['type' => 'text', 'ops' => ['like','eq','empty']]], + ]; + $attrs = ['data-table-id' => 'system-logs']; + $tbodyId = 'logsTableBody'; + require __DIR__ . '/../partials/table.php'; + ?> +
+ +
+ +
+
+ + + + +
+
+
+
+ +
+
+
+
+

+ +
+
+ 'Email', 'key' => 'email', 'filter' => ['type' => 'text', 'ops' => ['like','eq','empty']]], + ['label' => 'Roles', 'key' => 'roles', 'filter' => ['type' => 'text', 'ops' => ['like','eq','empty']]], + ['label' => 'Status', 'key' => 'status', 'filter' => ['type' => 'select', 'options' => ['active','disabled']]], + ['label' => 'Last login', 'key' => 'last_login_at', 'filter' => ['type' => 'date', 'ops' => ['eq','between']]], + ['label' => 'Actions', 'key' => '', 'filter' => null], + ]; + $attrs = ['data-table-id' => 'admin-users']; + $footer = false; + $tbodyId = 'adminUsers'; + require __DIR__ . '/../partials/table.php'; + ?> +
+
+
+
+ + +
+
+

+
+ +
+

+
+
+
+
-
+
+
+
+
-
+
+
+
+
-
+
+
+ + +

+        
+ +
+

+
+
+
+
-
+
+
+
+
-
+
+
+
DB
+
-
+
+
+
User
+
-
+
+
+
+ 'Table'], + ['label' => 'Rows'], + ]; + $footer = false; + require __DIR__ . '/../partials/table.php'; + ?> +
+

+          
+ + +

+        
+ +
+

+
+ + + +
+

+        
+
+ + +
+
+

+
+
+
+ +
+
+ scMedia + v0.0.0 +
+
+ SAFE-CAP + safe-cap.com +
+
+
+
+
+ $t('settings.about.table_name', 'Name'), 'i18n' => 'settings.about.table_name'], + ['label' => $t('settings.about.table_type', 'Type'), 'i18n' => 'settings.about.table_type'], + ['label' => $t('settings.about.table_author', 'Author'), 'i18n' => 'settings.about.table_author'], + ['label' => $t('settings.about.table_version', 'Version'), 'i18n' => 'settings.about.table_version'], + ['label' => $t('settings.about.table_update', 'Update'), 'i18n' => 'settings.about.table_update'], + ]; + $footer = false; + require __DIR__ . '/../partials/table.php'; + ?> +
+
+
+
+ + + + + + + + + + + + + + + + + + diff --git a/app/views/partials/header.php b/app/views/partials/header.php new file mode 100644 index 0000000..0a72644 --- /dev/null +++ b/app/views/partials/header.php @@ -0,0 +1,119 @@ + + +
+
+ + + scMedia + + + +
+ + +
+ +
+
>
+
+ +
> + +
+ + + +
+ + + + +
+ +
+
+ +
+
+
+
diff --git a/app/views/partials/table.php b/app/views/partials/table.php new file mode 100644 index 0000000..a6714c4 --- /dev/null +++ b/app/views/partials/table.php @@ -0,0 +1,68 @@ + $v) { + $attrPairs .= ' ' . htmlspecialchars((string)$k, ENT_QUOTES) . '="' . htmlspecialchars((string)$v, ENT_QUOTES) . '"'; +} +?> +
+
+ + + +
+ > + + + + + + + + + > + + + + + + > +
+ + + +
diff --git a/cli/scan.php b/cli/scan.php new file mode 100644 index 0000000..91e0370 --- /dev/null +++ b/cli/scan.php @@ -0,0 +1,31 @@ +create('scan', 'Scan (CLI)', [ + 'source' => 'cli', +]); + +echo "Queued job id={$jobId}\n"; + +try { + $jobs->start($jobId); + $result = $scanner->runScanJob($jobId); + $jobs->finish($jobId); + + echo "OK: scan finished\n"; + echo "Profiles: " . ($result['profiles'] ?? 0) . "\n"; + echo "Items seen: " . ($result['items_seen'] ?? 0) . "\n"; + exit(0); +} catch (Throwable $e) { + $jobs->log($jobId, 'error', $e->getMessage()); + $jobs->fail($jobId, $e->getMessage()); + fwrite(STDERR, "ERROR: " . $e->getMessage() . "\n"); + exit(1); +} diff --git a/cli/worker.php b/cli/worker.php new file mode 100644 index 0000000..304c3d3 --- /dev/null +++ b/cli/worker.php @@ -0,0 +1,81 @@ +fetchNextQueued(); + if (!$job) { + sleep($sleep); + continue; + } + + $jobId = (int)$job['id']; + $type = (string)$job['type']; + + echo "Picked job id={$jobId} type={$type}\n"; + + try { + $jobs->start($jobId); + $jobs->log($jobId, 'info', "Worker started job type={$type}"); + + if ($type === 'scan') { + $scanner->runScanJob($jobId); + $jobs->finish($jobId); + $jobs->log($jobId, 'info', "Worker finished scan"); + } elseif ($type === 'db_reset') { + $cfg = $config['app'] ?? []; + if (empty($cfg['allow_db_reset'])) { + throw new Exception("DB reset is disabled by config (app.allow_db_reset=false)"); + } + + $jobs->setProgress($jobId, 0, 1); + $log = []; + $schema->resetDatabase($log); + foreach ($log as $line) { + $jobs->log($jobId, 'info', (string)$line); + } + $jobs->setProgress($jobId, 1, 1); + $jobs->finish($jobId); + } elseif ($type === 'clear_index') { + $jobs->setProgress($jobId, 0, 3); + + $db->exec("DELETE FROM items"); + $jobs->setProgress($jobId, 1, 3); + $jobs->log($jobId, 'info', "items cleared"); + + // Note: keep jobs table; we clear logs for old jobs only (optional) + $db->exec("DELETE FROM job_logs WHERE job_id <> :id", [':id' => $jobId]); + $jobs->setProgress($jobId, 2, 3); + $jobs->log($jobId, 'info', "job_logs cleared (except current)"); + + $jobs->setProgress($jobId, 3, 3); + $jobs->finish($jobId); + } else { + throw new Exception("Unsupported job type: {$type}"); + } + } catch (Throwable $e) { + $jobs->log($jobId, 'error', $e->getMessage()); + $jobs->fail($jobId, $e->getMessage()); + fwrite(STDERR, "Job {$jobId} failed: " . $e->getMessage() . "\n"); + } + + sleep(1); +} diff --git a/config/config.php b/config/config.php new file mode 100644 index 0000000..0b889c6 --- /dev/null +++ b/config/config.php @@ -0,0 +1,86 @@ + [ + 'dsn' => (getenv('DB_DSN') ?: ('mysql:host=' . (getenv('DB_HOST') ?: '127.0.0.1') . ';port=' . (getenv('DB_PORT') ?: '3306') . ';dbname=' . (getenv('DB_NAME') ?: 'scmedia') . ';charset=utf8mb4')), + 'user' => (getenv('DB_USER') ?: 'scmedia'), + 'pass' => (getenv('DB_PASS') ?: 'changeme'), + ], + + 'app' => [ + // Generate once and keep immutable for this instance + 'app_id' => (getenv('APP_ID') ?: 'CHANGE_ME_UUID'), + 'env' => (getenv('APP_ENV') ?: 'development'), // development|production + 'backend_version' => (getenv('BACKEND_VERSION') ?: (getenv('APP_VERSION') ?: '0.1.0')), + 'db_version' => (getenv('DB_VERSION') ?: '0.1.0'), + 'plugins_version' => (getenv('PLUGINS_VERSION') ?: '0.1.0'), + + // Debug tools UI visibility + 'debug_tools_enabled' => $envBool('DEBUG', false), + 'debug_logs_enabled' => $envBool('DEBUG', false), + 'debug_keys_enabled' => $envBool('DEBUG_KEYS', false), + + // Dangerous: allows /api/debug/reset-db + 'allow_db_reset' => $envBool('ALLOW_DB_RESET', true), + + 'worker_sleep_seconds' => $envInt('WORKER_SLEEP_SECONDS', 2), + ], + + 'paths' => [ + 'incoming' => (getenv('PATH_INCOMING') ?: '/data/incoming'), + 'movies' => (getenv('PATH_MOVIES') ?: '/data/movies'), + 'series' => (getenv('PATH_SERIES') ?: '/data/series'), + ], + + 'video_ext' => array_values(array_filter(array_map('trim', explode(',', (getenv('VIDEO_EXT') ?: 'mkv,mp4,avi,mov,m4v,ts,m2ts,wmv'))))), + + 'scanner' => [ + 'max_depth' => $envInt('SCANNER_MAX_DEPTH', 3), + 'max_files_per_item' => $envInt('SCANNER_MAX_FILES_PER_ITEM', 3000), + ], + + 'auth' => [ + 'jwt_secret' => (getenv('JWT_SECRET') ?: 'CHANGE_ME_JWT_SECRET'), + 'access_ttl_seconds' => $envInt('ACCESS_TTL_SECONDS', 900), + 'refresh_ttl_web_days' => $envInt('REFRESH_TTL_WEB_DAYS', 14), + 'refresh_ttl_mobile_days' => $envInt('REFRESH_TTL_MOBILE_DAYS', 30), + 'challenge_ttl_seconds' => $envInt('AUTH_CHALLENGE_TTL_SECONDS', 300), + 'password_reset_ttl_minutes' => $envInt('PASSWORD_RESET_TTL_MINUTES', 30), + 'max_devices' => $envInt('AUTH_MAX_DEVICES', 5), + 'return_reset_token' => $envBool('AUTH_RETURN_RESET_TOKEN', false), + 'rate_limit_login_max' => $envInt('AUTH_LOGIN_MAX', 10), + 'rate_limit_login_window' => $envInt('AUTH_LOGIN_WINDOW_SECONDS', 900), + 'rate_limit_login_block' => $envInt('AUTH_LOGIN_BLOCK_SECONDS', 900), + 'rate_limit_mfa_max' => $envInt('AUTH_MFA_MAX', 6), + 'rate_limit_mfa_window' => $envInt('AUTH_MFA_WINDOW_SECONDS', 900), + 'rate_limit_mfa_block' => $envInt('AUTH_MFA_BLOCK_SECONDS', 900), + 'sse_key_ttl_seconds' => $envInt('AUTH_SSE_KEY_TTL_SECONDS', 90), + ], + + // Hard safety rails (GUI cannot exceed) + 'safety' => [ + 'hard_limits' => [ + 'max_depth' => 10, + 'max_files_per_item' => 200000, + 'max_items_per_scan' => 1000000, + ], + ], +]; diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..bde69d1 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,98 @@ +services: + nginx: + image: nginx:alpine + container_name: scmedia_nginx + depends_on: + - php + ports: + - "8088:80" + volumes: + - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro + - ./:/var/www:ro + networks: + - scmedia + + php: + build: + context: . + dockerfile: docker/php/Dockerfile + container_name: scmedia_php + environment: + APP_ENV: ${APP_ENV:-production} + APP_ID: ${APP_ID:-CHANGE_ME_UUID} + DEBUG_TOOLS_ENABLED: ${DEBUG_TOOLS_ENABLED:-false} + ALLOW_DB_RESET: ${ALLOW_DB_RESET:-false} + WORKER_SLEEP_SECONDS: ${WORKER_SLEEP_SECONDS:-2} + DB_HOST: ${DB_HOST:-db} + DB_PORT: ${DB_PORT:-3306} + DB_NAME: ${DB_NAME:-scmedia} + DB_USER: ${DB_USER:-scmedia} + DB_PASS: ${DB_PASS:-changeme} + DB_ROOT_PASS: ${DB_ROOT_PASS:-rootpass} + PATH_INCOMING: ${PATH_INCOMING:-/data/incoming} + PATH_MOVIES: ${PATH_MOVIES:-/data/movies} + PATH_SERIES: ${PATH_SERIES:-/data/series} + VIDEO_EXT: ${VIDEO_EXT:-mkv,mp4,avi,mov,m4v,ts,m2ts,wmv} + SCANNER_MAX_DEPTH: ${SCANNER_MAX_DEPTH:-3} + SCANNER_MAX_FILES_PER_ITEM: ${SCANNER_MAX_FILES_PER_ITEM:-3000} + volumes: + - ./:/var/www + # where scMedia scans media (bind-mount your CephFS path here) + - ./_data:/data + # writable storage + - scmedia_storage:/var/www/storage + networks: + - scmedia + + worker: + build: + context: . + dockerfile: docker/php/Dockerfile + container_name: scmedia_worker + depends_on: + - db + environment: + APP_ENV: ${APP_ENV:-production} + APP_ID: ${APP_ID:-CHANGE_ME_UUID} + DEBUG_TOOLS_ENABLED: ${DEBUG_TOOLS_ENABLED:-false} + ALLOW_DB_RESET: ${ALLOW_DB_RESET:-false} + WORKER_SLEEP_SECONDS: ${WORKER_SLEEP_SECONDS:-2} + DB_HOST: ${DB_HOST:-db} + DB_PORT: ${DB_PORT:-3306} + DB_NAME: ${DB_NAME:-scmedia} + DB_USER: ${DB_USER:-scmedia} + DB_PASS: ${DB_PASS:-changeme} + DB_ROOT_PASS: ${DB_ROOT_PASS:-rootpass} + PATH_INCOMING: ${PATH_INCOMING:-/data/incoming} + PATH_MOVIES: ${PATH_MOVIES:-/data/movies} + PATH_SERIES: ${PATH_SERIES:-/data/series} + VIDEO_EXT: ${VIDEO_EXT:-mkv,mp4,avi,mov,m4v,ts,m2ts,wmv} + SCANNER_MAX_DEPTH: ${SCANNER_MAX_DEPTH:-3} + SCANNER_MAX_FILES_PER_ITEM: ${SCANNER_MAX_FILES_PER_ITEM:-3000} + command: ["php", "cli/worker.php"] + volumes: + - ./:/var/www + - ./_data:/data + - scmedia_storage:/var/www/storage + networks: + - scmedia + + db: + image: mariadb:11 + container_name: scmedia_db + environment: + MARIADB_DATABASE: ${DB_NAME:-scmedia} + MARIADB_USER: ${DB_USER:-scmedia} + MARIADB_PASSWORD: ${DB_PASS:-changeme} + MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASS:-rootpass} + volumes: + - scmedia_db:/var/lib/mysql + networks: + - scmedia + +networks: + scmedia: + +volumes: + scmedia_db: + scmedia_storage: diff --git a/docker/nginx/default.conf b/docker/nginx/default.conf new file mode 100644 index 0000000..97dd640 --- /dev/null +++ b/docker/nginx/default.conf @@ -0,0 +1,42 @@ +server { + listen 80; + server_name _; + + root /var/www/public; + index index.php; + + # Basic hardening + client_max_body_size 64m; + + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + location = /api/events { + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root/index.php; + fastcgi_param SCRIPT_NAME /index.php; + fastcgi_param QUERY_STRING $query_string; + fastcgi_param PATH_INFO /api/events; + fastcgi_param DOCUMENT_ROOT $document_root; + fastcgi_pass php:9000; + fastcgi_read_timeout 3600; + fastcgi_send_timeout 3600; + fastcgi_keep_conn on; + fastcgi_buffering off; + fastcgi_cache off; + add_header X-Accel-Buffering no; + } + + location ~ \.php$ { + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param DOCUMENT_ROOT $document_root; + fastcgi_pass php:9000; + fastcgi_read_timeout 300; + } + + location ~ /(\.ht|\.git) { + deny all; + } +} diff --git a/docker/php/Dockerfile b/docker/php/Dockerfile new file mode 100644 index 0000000..c4b8cbf --- /dev/null +++ b/docker/php/Dockerfile @@ -0,0 +1,40 @@ +FROM php:8.3-fpm-alpine + +# System deps +RUN apk add --no-cache \ + bash \ + icu-libs icu-data-full \ + curl \ + libzip \ + mariadb-client \ + && apk add --no-cache --virtual .build-deps \ + curl-dev \ + icu-dev \ + libzip-dev \ + && docker-php-ext-install \ + pdo \ + pdo_mysql \ + intl \ + curl \ + && apk del .build-deps + +WORKDIR /var/www + +# Copy app +COPY . /var/www + +# PHP-FPM extra pools +COPY docker/php/conf/events.conf /usr/local/etc/php-fpm.d/events.conf + +# Writable dirs (create even if you don't use yet) +RUN mkdir -p /var/www/storage/logs \ + && chown -R www-data:www-data /var/www/storage + +RUN chmod +x /var/www/docker/scripts/entrypoint.sh \ + && chmod +x /var/www/docker/scripts/init-db.sh \ + && chmod +x /var/www/docker/scripts/wait-for-db.sh + +USER www-data + +ENTRYPOINT ["/var/www/docker/scripts/entrypoint.sh"] +CMD ["php-fpm", "-F"] diff --git a/docker/php/conf/events.conf b/docker/php/conf/events.conf new file mode 100644 index 0000000..5ef97b9 --- /dev/null +++ b/docker/php/conf/events.conf @@ -0,0 +1,10 @@ +[events] +user = www-data +group = www-data +listen = 9001 +pm = ondemand +pm.max_children = 40 +pm.process_idle_timeout = 120s +request_terminate_timeout = 0 +php_admin_value[max_execution_time] = 0 +php_admin_value[default_socket_timeout] = 3600 diff --git a/docker/scripts/entrypoint.sh b/docker/scripts/entrypoint.sh new file mode 100644 index 0000000..7e80fe6 --- /dev/null +++ b/docker/scripts/entrypoint.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +set -euo pipefail + +APP_ENV="${APP_ENV:-production}" +APP_ID="${APP_ID:-}" + +if [ -z "${APP_ID}" ]; then + if command -v uuidgen >/dev/null 2>&1; then + APP_ID="$(uuidgen)" + else + APP_ID="$(python3 - <<'PY' +import uuid +print(uuid.uuid4()) +PY +)" + fi +fi + +ENV_FILE="/var/www/.env" +if [ ! -f "${ENV_FILE}" ]; then + cat > "${ENV_FILE}" <&2 + exit 1 + fi + set -a + # shellcheck disable=SC1090 + . "${ENV_PATH}" + set +a +fi + +HOST="${DB_HOST:-db}" +PORT="${DB_PORT:-3306}" +NAME="${DB_NAME:-scmedia}" +USER="${DB_USER:-scmedia}" +PASS="${DB_PASS:-changeme}" +ROOT_PASS="${DB_ROOT_PASS:-${MARIADB_ROOT_PASSWORD:-}}" +PROTO_ARGS=() +if [ "${HOST}" = "localhost" ] || [ "${HOST}" = "127.0.0.1" ]; then + PROTO_ARGS=(--protocol=tcp) +fi + +if [ -z "${ROOT_PASS}" ]; then + echo "Missing DB_ROOT_PASS/MARIADB_ROOT_PASSWORD for init" >&2 + exit 1 +fi + +for i in $(seq 1 60); do + if mysqladmin ping -h"${HOST}" -P"${PORT}" "${PROTO_ARGS[@]}" -uroot -p"${ROOT_PASS}" --silent; then + break + fi + sleep 1 +done + +if [ "${MODE}" = "--destroy" ]; then + if mysql -h"${HOST}" -P"${PORT}" "${PROTO_ARGS[@]}" -uroot -p"${ROOT_PASS}" -N -e \ + "SELECT 1 FROM mysql.user WHERE User='${USER}' AND Host='%';" | grep -q 1; then + mysql -h"${HOST}" -P"${PORT}" "${PROTO_ARGS[@]}" -uroot -p"${ROOT_PASS}" -e \ + "REVOKE ALL PRIVILEGES, GRANT OPTION FROM '${USER}'@'%'; FLUSH PRIVILEGES;" + mysql -h"${HOST}" -P"${PORT}" "${PROTO_ARGS[@]}" -uroot -p"${ROOT_PASS}" -e \ + "DROP USER '${USER}'@'%';" + fi + mysql -h"${HOST}" -P"${PORT}" "${PROTO_ARGS[@]}" -uroot -p"${ROOT_PASS}" -e \ + "DROP DATABASE IF EXISTS \`${NAME}\`;" + echo "Destroyed database/user/privileges" + exit 0 +fi + +mysql -h"${HOST}" -P"${PORT}" "${PROTO_ARGS[@]}" -uroot -p"${ROOT_PASS}" -e \ + "CREATE DATABASE IF NOT EXISTS \`${NAME}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" +mysql -h"${HOST}" -P"${PORT}" "${PROTO_ARGS[@]}" -uroot -p"${ROOT_PASS}" -e \ + "CREATE USER IF NOT EXISTS '${USER}'@'%' IDENTIFIED BY '${PASS}';" +mysql -h"${HOST}" -P"${PORT}" "${PROTO_ARGS[@]}" -uroot -p"${ROOT_PASS}" -e \ + "GRANT ALL PRIVILEGES ON \`${NAME}\`.* TO '${USER}'@'%'; FLUSH PRIVILEGES;" + +if mysql -h"${HOST}" -P"${PORT}" "${PROTO_ARGS[@]}" -u"${USER}" -p"${PASS}" "${NAME}" -e "SHOW TABLES LIKE 'items'" | grep -q items; then + echo "Schema already present, skip import" + exit 0 +fi + +SCHEMA_PATH="${SCHEMA_PATH:-/var/www/sql/schema.sql}" +if [ ! -f "${SCHEMA_PATH}" ]; then + SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" + if [ -f "${PROJECT_ROOT}/sql/schema.sql" ]; then + SCHEMA_PATH="${PROJECT_ROOT}/sql/schema.sql" + fi +fi + +echo "Importing schema.sql from ${SCHEMA_PATH}..." +mysql -h"${HOST}" -P"${PORT}" "${PROTO_ARGS[@]}" -u"${USER}" -p"${PASS}" "${NAME}" < "${SCHEMA_PATH}" +echo "Done" diff --git a/docker/scripts/wait-for-db.sh b/docker/scripts/wait-for-db.sh new file mode 100644 index 0000000..f3c2698 --- /dev/null +++ b/docker/scripts/wait-for-db.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +set -euo pipefail + +HOST="${DB_HOST:-db}" +PORT="${DB_PORT:-3306}" +USER="${DB_USER:-scmedia}" +PASS="${DB_PASS:-changeme}" + +for i in $(seq 1 60); do + if mysqladmin ping -h"${HOST}" -P"${PORT}" -u"${USER}" -p"${PASS}" --silent; then + exit 0 + fi + sleep 1 +done + +echo "DB not ready after 60s" >&2 +exit 1 diff --git a/public/assets/assets/branding/scmedia/CODEX.md b/public/assets/assets/branding/scmedia/CODEX.md new file mode 100644 index 0000000..61bacf4 --- /dev/null +++ b/public/assets/assets/branding/scmedia/CODEX.md @@ -0,0 +1,38 @@ +# Codex import instructions (scMedia brand kit) + +Goal: place assets into the repo and wire them into the UI. + +## Recommended repo paths + +- `public/assets/branding/scmedia/logo/*` +- `public/assets/branding/scmedia/icons/*` +- `public/assets/branding/scmedia/ui/*` +- `public/assets/branding/scmedia/manifest.json` + +If your repo already uses a different static-assets convention, follow that convention instead. + +## How to use + +1) Use `logo/logo_horizontal_on_dark.png` in the top-left header (wordmark). +2) Use `logo/app_icon_square_256.png` for favicon/app icon sources; downscale as needed. +3) Use the icon shapes from `icons/icon_grid_on_dark.png` as the visual reference to implement your icon components. + +## Icon semantics mapping + +Use the following icon meanings consistently: +- Scan: start scanning jobs +- Refresh: reload lists / rescan UI state +- Preview: preview rename/move plan +- Apply/Execute: apply planned changes +- Settings: open configuration +- Job running: show running task status (spinner-like) +- Movie: movie category +- Series: TV series category +- Auto detect: auto-detect naming/structure +- Error/Warning: error state +- Skipped/Ignored: ignore / skip state + +## Design constraints + +- Dark-first UI, high contrast, soft rounded geometry. +- Prefer monochrome icons with accent usage only for states (primary action, error, success). diff --git a/public/assets/assets/branding/scmedia/README.md b/public/assets/assets/branding/scmedia/README.md new file mode 100644 index 0000000..94183d5 --- /dev/null +++ b/public/assets/assets/branding/scmedia/README.md @@ -0,0 +1,31 @@ +# scMedia Brand Kit (v1) + +This archive contains the generated **scMedia** logo + icon style reference + a UI preview, designed for a dark-first, minimalist, technical interface. + +## Included files + +- `logo/logo_on_dark.png` — hero logo composition (dark background) +- `logo/logo_horizontal_on_dark.png` — horizontal lockup (symbol + wordmark) +- `logo/app_icon_square_*.png` — square app icon exports (64/128/256/512) +- `icons/icon_grid_on_dark.png` — icon set grid reference (style + shapes) +- `ui/ui_preview_on_dark.png` — UI preview using icons instead of text labels +- `manifest.json` — palette + suggested paths + icon semantic mapping + +## Color palette + +Base: +- `#0b0f14` +- `#0f1620` +- `#111a25` + +Accent: +- `#3b82f6` (blue) +- `#38bdf8` (cyan) + +Status: +- Error: `#ef4444` +- Success: `#22c55e` + +## Notes + +- This kit is **PNG-based** (raster). If you want **SVG icons**, tell me the icon style preference (outline vs solid, stroke width), and I’ll generate a vector set. diff --git a/public/assets/assets/branding/scmedia/icons/icon_grid_on_dark.png b/public/assets/assets/branding/scmedia/icons/icon_grid_on_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..f97cee173ab98f4ed84aa8e8637d175e064153be GIT binary patch literal 298405 zcmV)_K!3l9P)3<9NzL2!Smv zgbv=*X3g1_MIxCXnM{yQ*(4G+wk;7tm}Y5>)*9FK$(LM;MUQgX#dUqOHjS2+nP+JW zEF?`$4Rm#8$jub_-w%I^pI-EBn%dfEZfT)hDn;cAq0#dW%u-<|%==t8Y`!_$2B_?Z z1=^xDLYVy%u64_{*}VQ?jy>i$etPjQ=~>pv=FOv&JrB#0SVAHMNFmW$a;RB+hHCUDv>>GtvifCSf^&L)9SdwMi3=VAO10VS`AO65OOy)eK zl+;@tLTHrIWYdyUpL065-26{Ed%N+)yiue)t3QcDA5_yZ`$z?>zS%-147)(c8NWghFc>5MMxf zXxHbo4}6zwa}&B;L}OuFAS{Qjz8a(3#}!KVHrC7rvI(j$S;i5JE@vcQ)v{U!#H9?dxOKCf#{ZTg_r<{=D~V z=zFaEgk!T|!v;S0xv%qzvtG)U!4aesXr&R-JlNLW!ku^C&dXkMI&JN3C|{$rMk_@w zH%YOOM+zrcBOs*2wjG>gf>b7rW7|k6@jZpss)Evj^;F%-nl@K8coB0Tsy^zJu@A!> zU0j+(R%ekcLO`$=QSz>ZeTkX`gi~wqeSxn*p^+E?Nu%(kAk)-MCMiMKF~TdV1)XRw z84lVAWYr9Zu7_>s!rAkzsU@S##R~sX;Q}qdvK>0Rx{=cKTWcNkBg8X-Agpx^Pnu_h z1SvElLn9=zS$qu$jY6QJS7o43h(x7%`nC%R#k`=me+$%GHvuROwr%0MWkv?q^FJ?r z6(9NNCrM<|tXnsL>-k72ain8ZE*g~5Bpi#zrbe0?Ge`lsnF7N@!)zMZ#Fov2j89Hb zC=}3IlS-y&Z*QZgyNmw*9=f`F=AzE)x?u^2IVzT3FIX3PHY5V$He&ZLJM_ z>#OJSq8FUTo8SBf1~zP@Z~1aO*9H7w%`b%57CVAFXuji3s-=1HrtA#ie*q8ya~BDC zLL$&?TKfR6I_ph*`I}!Nmn-w|+O0+@goV(;FpR#!P6}Gvnn)!r^2IWD-t!)+1hm;IQ&6$fKk7QW|&*f9DR>doBTcMiZpurCqaT?Dg+ ztVXLGZGMA8Eoq^IW^8N(?JHW^IzUR4?^gu>NWrBe1;0k4lwx`R@<>n%`HERh(gNk1 zhB?Uuu3I+3dlhX9Y6z5eXrm1De3z;5F_Ot7nT94jw_H)wF~_dj?ZVyO2U>$|OEzxW z#2K%68{hoe`IJ1!6@AK{=BOhN<~P5)if2COH150eE_!-8a9yJaMGJ(qam&-(cI{;x zcj}oqj^QcYQVHKvYM)iH)5PT~T7dHseBfX4R~0tQQvmEs5NuR4 zXThdX8Z84&92%uS`Jq))fr`j~odPSS*hnPaVOGWM*@261;L^#4a;=gn_{t=Se!)eu0V4;pwt&7UsI*!9kE=Msx&DXyE zea?K@i`cMngw4ZaSW;q1W8Jlc5&Sdh6m4zIIF8_|G`UN`Z{j9;g763LMj^XI&~pvI9Q7MU zFcAKQV9SQ}eBzTA^6vMX&6c4YQ@K1+N`wX}1t^VWOIkWxNhaau|J=nTm;9U?Z@huc zn>XW@N;nCNgyUe_wlPd8ALaY3dGJ2|dBdN%*!QrVBr8`R!V6A6gEzkZ)f}|4o3f{w z%DHGEv7}MfISHHbNsnYwa>-A>#e4c!@bxc$ithfEIF5x@Ax5mM;|MS8vy8*8>eN0t zcsn2F8#Y6%A~fXK2@1sm6Qf&s=}XTdm&@_n-(E?kp_y!B1HR`6FB+aeAdJ;DFa}7= zqPMpPrFC5|jksZ2NaKN%Y0RRvMoLk`qMLRZ-#UTiSd5L0VM%!66Q9gO4?Vz!^=s%` zwi3^EBdQr%|HKkd∝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

wgG-A=lzw^A%Yz3(hPUOJJB5*kB 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 literal 0 HcmV?d00001 diff --git a/public/assets/assets/branding/scmedia/logo/app_icon_square_256.png b/public/assets/assets/branding/scmedia/logo/app_icon_square_256.png new file mode 100644 index 0000000000000000000000000000000000000000..158424d904e798b475573540a4c0ac24fed8003c GIT binary patch literal 22572 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 z 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≀v-dBYO7TOyXuPbCAM&e7Ws%b%#KuHd!^o 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 R=Z63Q002ovPDHLkV1m`giZ%cM literal 0 HcmV?d00001 diff --git a/public/assets/assets/branding/scmedia/logo/logo_on_dark.png b/public/assets/assets/branding/scmedia/logo/logo_on_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..b528fac9126802e76a7077d15ababec3ea32a875 GIT binary patch literal 105510 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

<-6r7({MEcf)bVrF} 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≠qeYlQ+Ae;)Y$0J)W9flaPv{o=|1Ti1oZ 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%0DL(44-)W-gJ%vU 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

3xp>^_Nq+X%waJ%QWu^^F6rh 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

QAp~gxTzo1e$mff{{mn3I;NMjw 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 O0000 {}); + } + } + + function applyUi(ui) { + state.ui = ui || {}; + if (qs('accountLanguage')) qs('accountLanguage').value = state.ui.language || 'en'; + if (qs('accountTheme')) qs('accountTheme').value = state.ui.theme || 'dark'; + if (qs('accountTableMode')) qs('accountTableMode').value = state.ui.table_mode || 'pagination'; + if (qs('accountTableSize')) qs('accountTableSize').value = String(state.ui.table_page_size || 50); + } + + async function loadAccount() { + const res = await window.Api.request('/api/account', { method: 'GET' }); + const data = res?.data || res || {}; + applyProfile(data.profile || {}); + applyUi(data.ui || {}); + if (window.UserPrefs?.load) { + await window.UserPrefs.load(); + } + } + + async function saveProfile() { + const nickname = (qs('accountNickname')?.value || '').trim(); + const email = (qs('accountEmail')?.value || '').trim(); + const ui = { + language: qs('accountLanguage')?.value || 'en', + theme: qs('accountTheme')?.value || 'dark', + table_mode: qs('accountTableMode')?.value || 'pagination', + table_page_size: Number(qs('accountTableSize')?.value || 50), + }; + await window.Api.request('/api/account', { + method: 'POST', + body: { nickname, ui }, + }); + if (window.UserPrefs?.setUi) { + Object.keys(ui).forEach((key) => window.UserPrefs.setUi(key, ui[key])); + } + if (email && email !== state.profile?.email) { + await window.Api.request('/api/account/email', { + method: 'POST', + body: { email }, + }); + } + if (ui.theme && window.UI?.setTheme) { + window.UI.setTheme(ui.theme); + } + if (ui.language && ui.language !== (window.APP_LANG || 'en')) { + localStorage.setItem('scmedia_lang', ui.language); + } + } + + async function uploadAvatar() { + const file = qs('avatarFile')?.files?.[0]; + if (!file) return; + if (file.size > 5 * 1024 * 1024) { + alert('File too large (max 5MB)'); + return; + } + const form = new FormData(); + form.append('avatar', file); + await window.Api.request('/api/account/avatar', { + method: 'POST', + body: form, + headers: {}, + }); + await fetchAvatar(); + } + + async function changePassword() { + const current = qs('accountPasswordCurrent')?.value || ''; + const next = qs('accountPasswordNew')?.value || ''; + const confirm = qs('accountPasswordConfirm')?.value || ''; + if (!current || !next) { + setStatus('Missing password'); + return; + } + if (next !== confirm) { + setStatus('Passwords do not match'); + return; + } + setStatus('Saving…'); + await window.Api.request('/api/account/password', { + method: 'POST', + body: { current, next }, + }); + setStatus('Saved'); + qs('accountPasswordCurrent').value = ''; + qs('accountPasswordNew').value = ''; + qs('accountPasswordConfirm').value = ''; + if (window.Auth?.logout) { + window.Auth.logout(); + return; + } + if (window.Auth?.clearTokens) { + window.Auth.clearTokens(); + } + window.location.href = '/login'; + } + + function init() { + if (window.Auth?.requireAuth) { + window.Auth.requireAuth(); + } + window.UI?.initHeader?.(); + window.UI?.initThemeToggle?.(); + window.UI?.bindThemePreference?.(); + loadAccount().catch(() => {}); + + qs('btnAccountSave')?.addEventListener('click', () => saveProfile().catch((e) => alert(e.message))); + qs('btnAvatarUpload')?.addEventListener('click', () => uploadAvatar().catch((e) => alert(e.message))); + qs('btnPasswordChange')?.addEventListener('click', () => changePassword().catch((e) => setStatus(e.message))); + } + + init(); +})(); diff --git a/public/assets/js/admin.js b/public/assets/js/admin.js new file mode 100644 index 0000000..038586c --- /dev/null +++ b/public/assets/js/admin.js @@ -0,0 +1,157 @@ +// public/assets/admin.js +/* English comments: admin user management + audit */ + +function fmtDate(s) { + if (!s) return ''; + const d = new Date(s.replace(' ', 'T') + 'Z'); + if (Number.isNaN(d.getTime())) return s; + return d.toLocaleString(); +} + +function adminApi(path, opts = {}) { + return window.Api.request(path, opts); +} + +function handleAdminError(err) { + const message = err?.message || 'Request failed'; + alert(message); +} + +async function loadRoles() { + const res = await adminApi('/api/admin/roles'); + return res?.data?.items || []; +} + +async function loadUsers() { + const res = await adminApi('/api/admin/users'); + return res?.data?.items || []; +} + +async function loadAudit() { + const res = await adminApi('/api/admin/audit', { + method: 'POST', + body: { page: 1, per_page: 50 }, + }); + return res?.data?.items || []; +} + +function renderUsers(users, roles) { + const body = UI.qs('adminUsers'); + if (!body) return; + body.innerHTML = ''; + users.forEach((u) => { + const tr = document.createElement('tr'); + const rolesList = (u.roles || '').split(',').filter(Boolean); + const status = u.status || ''; + + const roleOptions = roles.map((r) => { + const selected = rolesList.includes(r.name) ? 'selected' : ''; + return ``; + }).join(''); + + tr.innerHTML = ` + ${u.email || ''} + + + + ${status} + ${fmtDate(u.last_login_at)} + +
+ + +
+ + `; + body.appendChild(tr); + }); +} + +function renderAudit(items) { + const body = UI.qs('adminAudit'); + if (!body) return; + body.innerHTML = ''; + items.forEach((a) => { + const tr = document.createElement('tr'); + tr.innerHTML = ` + ${fmtDate(a.created_at)} + ${a.actor_email || a.actor_user_id || ''} + ${a.action || ''} + ${a.target_type || ''} ${a.target_id || ''} + ${a.meta_json || ''} + `; + body.appendChild(tr); + }); +} + +let actionsBound = false; + +async function bindActions(roles) { + if (actionsBound) return; + const body = UI.qs('adminUsers'); + if (!body) return; + body.addEventListener('change', async (e) => { + const sel = e.target; + if (!sel || sel.dataset.action !== 'role') return; + const userId = sel.dataset.id; + const role = sel.value; + try { + await adminApi(`/api/admin/users/${userId}/roles`, { + method: 'POST', + body: JSON.stringify({ roles: [role] }), + }); + } catch (err) { + handleAdminError(err); + } + }); + body.addEventListener('click', async (e) => { + const btn = e.target.closest('button'); + if (!btn) return; + const action = btn.dataset.action; + const userId = btn.dataset.id; + if (action === 'toggle') { + const disabled = btn.dataset.status !== 'disabled'; + try { + await adminApi(`/api/admin/users/${userId}/disable`, { + method: 'POST', + body: JSON.stringify({ disabled }), + }); + init(); + } catch (err) { + handleAdminError(err); + } + } + if (action === 'reset2fa') { + try { + await adminApi(`/api/admin/users/${userId}/reset-2fa`, { method: 'POST' }); + } catch (err) { + handleAdminError(err); + } + } + }); + actionsBound = true; +} + +async function init() { + window.Auth.requireAuth(); + window.UI?.initHeader?.(); + if (!window.Auth.isAdmin()) { + UI.qs('adminUsers').innerHTML = 'Admin only'; + return; + } + const [roles, users, audit] = await Promise.all([loadRoles(), loadUsers(), loadAudit()]); + renderUsers(users, roles); + renderAudit(audit); + bindActions(roles); +} + +const btnReloadUsers = UI.qs('btnReloadUsers'); +if (btnReloadUsers) btnReloadUsers.addEventListener('click', init); +const btnReloadAudit = UI.qs('btnReloadAudit'); +if (btnReloadAudit) btnReloadAudit.addEventListener('click', init); + +init(); diff --git a/public/assets/js/api.js b/public/assets/js/api.js new file mode 100644 index 0000000..84026c4 --- /dev/null +++ b/public/assets/js/api.js @@ -0,0 +1,86 @@ +// public/assets/api.js +/* English comments: centralized API wrapper */ + +(function () { + function normalizeDateString(value) { + if (typeof value !== 'string') return value; + const s = value.trim(); + if (s === '') return value; + const isoDate = /^\d{4}-\d{2}-\d{2}$/; + const isoDateTime = /^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}/; + const dotDate = /^\d{2}\.\d{2}\.\d{4}$/; + const dotDateTime = /^\d{2}\.\d{2}\.\d{4}\s+\d{2}:\d{2}:\d{2}$/; + let v = s; + if (isoDate.test(v)) v = `${v} 00:00:00`; + if (dotDate.test(v)) { + const parts = v.split('.'); + v = `${parts[2]}-${parts[1]}-${parts[0]} 00:00:00`; + } else if (dotDateTime.test(v)) { + const [datePart, timePart] = v.split(/\s+/, 2); + const parts = datePart.split('.'); + v = `${parts[2]}-${parts[1]}-${parts[0]} ${timePart}`; + } + if (isoDateTime.test(v)) { + const d = new Date(v.replace(' ', 'T') + 'Z'); + if (!Number.isNaN(d.getTime())) { + return d.toISOString().slice(0, 19).replace('T', ' '); + } + } + return v; + } + + function normalizeDates(payload) { + if (payload === null || payload === undefined) return payload; + if (Array.isArray(payload)) return payload.map(normalizeDates); + if (typeof payload !== 'object') return payload; + const out = {}; + Object.keys(payload).forEach((key) => { + const value = payload[key]; + if (value && typeof value === 'object') { + out[key] = normalizeDates(value); + } else if (typeof value === 'string' && (key === 'ts' || key.endsWith('_at') || key.endsWith('_ts'))) { + out[key] = normalizeDateString(value); + } else { + out[key] = value; + } + }); + return out; + } + + async function request(path, opts = {}) { + const headers = { ...(opts.headers || {}) }; + const hasBodyObject = opts.body && typeof opts.body === 'object' && !(opts.body instanceof FormData); + const body = hasBodyObject ? JSON.stringify(normalizeDates(opts.body)) : opts.body; + if (hasBodyObject && !headers['Content-Type']) { + headers['Content-Type'] = 'application/json'; + } + if (window.Auth?.isAccessExpired?.() && window.Auth?.refreshTokens) { + await window.Auth.refreshTokens(); + } + const token = window.Auth?.getAccessToken?.(); + if (token) { + headers['Authorization'] = `Bearer ${token}`; + } + let res = await fetch(path, { credentials: 'same-origin', ...opts, headers, body }); + if (res.status === 401 && window.Auth?.refreshTokens) { + const refreshed = await window.Auth.refreshTokens(); + if (refreshed) { + const newToken = window.Auth.getAccessToken(); + if (newToken) headers['Authorization'] = `Bearer ${newToken}`; + res = await fetch(path, { credentials: 'same-origin', ...opts, headers, body }); + } else if (window.Auth?.redirectToLogin) { + window.Auth.redirectToLogin(); + } + } + const json = await res.json().catch(() => null); + if (!json || json.ok !== true) { + const msg = json?.error?.message || `Request failed: ${res.status}`; + throw new Error(msg); + } + return json; + } + + window.Api = { + request, + }; +})(); diff --git a/public/assets/js/app-config.js b/public/assets/js/app-config.js new file mode 100644 index 0000000..4754044 --- /dev/null +++ b/public/assets/js/app-config.js @@ -0,0 +1 @@ +const APP_VERSION = "0.1.0"; diff --git a/public/assets/js/app.js b/public/assets/js/app.js new file mode 100644 index 0000000..f6cb7d8 --- /dev/null +++ b/public/assets/js/app.js @@ -0,0 +1,1743 @@ +// public/assets/app.js +/* English comments: minimal JS without external libs */ + +const state = { + mediaItems: [], + mediaTab: 'movies', + + i18n: {}, + lang: 'en', + + ui: { + table_mode: 'pagination', + table_page_size: 50, + }, + background: { + mode: 'light', + max_parallel_jobs: 1, + max_network_jobs: 1, + max_io_jobs: 1, + batch_sleep_ms: 500, + watchdog_minutes: 10, + paused: false, + }, + tables: {}, + + activeJobId: null, + jobPollTimer: null, + queuePollTimer: null, + watchdogTimer: null, + sourcesPollTimer: null, + sourcesCache: null, + sourceDetail: null, + sourceDetailItem: null, + sourceDetailData: null, + sourceDetailLastFetch: 0, + eventsSource: null, + tasks: [], + lastTasksFetch: 0, + queueActiveList: [], + queueRecentList: [], + debugToolsEnabled: false, + sse: { + connected: false, + lastEventAt: 0, + lastEventType: '', + reconnects: 0, + retryDelayMs: 5000, + leaseKey: 'scmedia_sse_lease', + tabId: '', + }, +}; + +const LS_ACTIVE_JOB = 'scmedia_active_job_id'; + +function sleep(ms) { + return new Promise((r) => setTimeout(r, ms)); +} + +function paginateItems(items, page, perPage) { + const total = items.length; + const size = Math.max(1, Number(perPage || 50)); + const p = Math.max(1, Number(page || 1)); + const start = (p - 1) * size; + const slice = items.slice(start, start + size); + return { items: slice, total, page: p, per_page: size }; +} + +function api(path, opts = {}) { + return window.Api.request(path, opts); +} + +/* --------------------------- + i18n +--------------------------- */ + +function t(key, fallback = null) { + const v = state.i18n?.[key]; + if (typeof v === 'string') return v; + if (fallback !== null) return fallback; + return key; +} + +function updateThemeLabel() { + const label = UI.qs('themeState'); + if (label) { + const current = document.documentElement.getAttribute('data-theme') || 'dark'; + label.textContent = (current === 'light') + ? t('theme.light', 'Light') + : t('theme.dark', 'Dark'); + } +} + +function initSourceDialog() { + const closeBtn = UI.qs('btnSourceClose'); + const dlg = UI.qs('dlg-source'); + const approveBtn = UI.qs('btnSourceApprove'); + if (closeBtn && dlg) { + closeBtn.addEventListener('click', () => dlg.close()); + } + if (approveBtn) { + approveBtn.addEventListener('click', () => { + if (!state.sourceDetail) return; + api('/api/sources/approve', { + method: 'POST', + body: JSON.stringify({ source: state.sourceDetail.source, id: state.sourceDetail.id }), + }).catch(() => {}); + }); + } + if (dlg) { + dlg.addEventListener('close', () => { + state.sourceDetail = null; + state.sourceDetailItem = null; + state.sourceDetailData = null; + }); + } +} + + +function setVersion() { + const el = document.querySelector('[data-version] .version'); + if (el && typeof APP_VERSION === 'string') { + el.textContent = `v${APP_VERSION}`; + } +} +/* --------------------------- + Filters + Grid +--------------------------- */ + +async function loadUiSettings() { + try { + const res = await api('/api/settings'); + const data = res.data || res; + state.debugToolsEnabled = !!(data.meta?.debug_tools_enabled); + const prefs = window.UserPrefs ? await window.UserPrefs.load().catch(() => null) : null; + const ui = prefs || {}; + state.ui.table_mode = ui.table_mode || 'pagination'; + state.ui.table_page_size = ui.table_page_size || 50; + const bg = data.background || {}; + state.background = { + mode: bg.mode || 'light', + max_parallel_jobs: Number(bg.max_parallel_jobs || 1), + max_network_jobs: Number(bg.max_network_jobs || 1), + max_io_jobs: Number(bg.max_io_jobs || 1), + batch_sleep_ms: Number(bg.batch_sleep_ms || 500), + watchdog_minutes: Number(bg.watchdog_minutes || 10), + paused: !!bg.paused, + }; + } catch (e) { + state.ui.table_mode = 'pagination'; + state.ui.table_page_size = 50; + } +} + +function setSseIndicator(stateClass) { + if (window.UI?.updateSseIndicator) { + window.UI.updateSseIndicator(stateClass.replace('sse-', '')); + return; + } + const items = document.querySelectorAll('[data-sse-indicator]'); + items.forEach((el) => { + el.classList.remove('sse-ok', 'sse-idle', 'sse-offline'); + el.classList.add(stateClass); + }); +} + +function pulseSseIndicator() { + if (window.UI?.blinkSseIndicator) { + window.UI.blinkSseIndicator(); + return; + } + const items = document.querySelectorAll('[data-sse-indicator]'); + items.forEach((el) => { + el.classList.add('sse-blink'); + setTimeout(() => el.classList.remove('sse-blink'), 250); + }); +} + +function updateSseStats() { + const wrap = UI.qs('queueSseStats'); + if (!wrap || !state.debugToolsEnabled) return; + wrap.classList.remove('is-hidden'); + const el = wrap.querySelector('.queue-stats'); + if (!el) return; + const sse = window.UI?.getSseStats?.() || null; + const lastAt = state.sse.lastEventAt ? new Date(state.sse.lastEventAt).toLocaleTimeString() : '—'; + const reconnects = sse ? sse.reconnects : Number(state.sse.reconnects || 0); + state.sse.reconnects = reconnects; + el.textContent = `last: ${lastAt} | type: ${state.sse.lastEventType || '—'} | reconnects: ${reconnects}`; +} + +function noteSseEvent(type) { + state.sse.lastEventAt = Date.now(); + state.sse.lastEventType = type; + localStorage.setItem('scmedia_sse_last', String(state.sse.lastEventAt)); + pulseSseIndicator(); + updateSseStats(); +} + +function setSseConnected(connected) { + state.sse.connected = connected; + localStorage.setItem('scmedia_sse_connected', connected ? '1' : '0'); + if (connected && state.sse.lastEventAt === 0) { + state.sse.lastEventAt = Date.now(); + localStorage.setItem('scmedia_sse_last', String(state.sse.lastEventAt)); + } + const now = Date.now(); + if (!connected) { + setSseIndicator('sse-offline'); + return; + } + const recent = state.sse.lastEventAt > 0 && (now - state.sse.lastEventAt) <= 15000; + setSseIndicator(recent ? 'sse-ok' : 'sse-idle'); +} + +function initTables() { + if (!window.TableController) return; + const mode = state.ui.table_mode || 'pagination'; + const pageSize = state.ui.table_page_size || 50; + const grid = UI.qs('grid'); + const sourcesGrid = UI.qs('sources-grid'); + const getPrefs = (table) => { + const id = table?.dataset?.tableId || table?.id || ''; + const prefs = window.UserPrefs?.getTable?.(id) || {}; + return { id, prefs }; + }; + + if (grid) { + const { id, prefs } = getPrefs(grid); + state.tables.media = new TableController({ + table: grid, + mode, + pageSize, + sort: prefs.sort || '', + dir: prefs.dir || 'asc', + onSortChange: (sort, dir) => window.UserPrefs?.setTable?.(id, { sort, dir }), + fetchPage: async ({ page, per_page, sort, dir, filters, params }) => { + const res = await api('/api/media/list', { + method: 'POST', + body: { + page, + per_page, + sort, + dir, + filters, + params: { + tab: params?.tab || state.mediaTab || 'movies', + }, + }, + }); + const data = res.data || {}; + return { + items: data.items || [], + total: data.total || 0, + page: data.page || page, + per_page: data.per_page || per_page, + }; + }, + renderRow: renderMediaRow, + }); + } + + if (sourcesGrid) { + const { id, prefs } = getPrefs(sourcesGrid); + state.tables.sources = new TableController({ + table: sourcesGrid, + mode, + pageSize, + sort: prefs.sort || '', + dir: prefs.dir || 'asc', + onSortChange: (sort, dir) => window.UserPrefs?.setTable?.(id, { sort, dir }), + fetchPage: async ({ page, per_page, sort, dir, filters }) => { + if (Array.isArray(state.sourcesCache)) { + const filtered = applySourceFilters(state.sourcesCache, filters); + const sorted = sortSources(filtered, sort, dir); + return paginateItems(sorted, page, per_page); + } + const res = await api('/api/sources/list', { + method: 'POST', + body: { + page, + per_page, + sort, + dir, + filters, + }, + }); + const data = res.data || {}; + return { + items: data.items || [], + total: data.total || 0, + page: data.page || page, + per_page: data.per_page || per_page, + }; + }, + renderRow: renderSourceRow, + }); + } +} + +function sortSources(items, sort, dir) { + if (!sort) return [...items]; + const desc = dir === 'desc'; + const list = [...items]; + const get = (it) => { + if (sort === 'name') return (it.name || '').toLowerCase(); + if (sort === 'size') return Number(it.size_bytes || 0); + if (sort === 'status') return (it.status || '').toLowerCase(); + if (sort === 'source') return (it.source || '').toLowerCase(); + if (sort === 'progress') return Number(it.percent_done || 0); + return (it[sort] ?? '').toString().toLowerCase(); + }; + list.sort((a, b) => { + const av = get(a); + const bv = get(b); + if (av === bv) return 0; + if (desc) return av < bv ? 1 : -1; + return av > bv ? 1 : -1; + }); + return list; +} + +function matchFilterValue(current, op, value) { + const opKey = (op || 'eq').toLowerCase(); + if (opKey === 'empty') { + if (Array.isArray(current)) return current.length === 0; + return current === null || current === ''; + } + if (opKey === 'like') { + const needle = String(value || '').toLowerCase(); + const hay = String(current ?? '').toLowerCase(); + return needle === '' ? true : hay.includes(needle); + } + if (opKey === 'between' && Array.isArray(value) && value.length >= 2) { + const left = value[0]; + const right = value[1]; + const cur = Number(current); + const l = Number(left); + const r = Number(right); + if (!Number.isNaN(cur) && !Number.isNaN(l) && !Number.isNaN(r)) { + return cur >= l && cur <= r; + } + return String(current ?? '') >= String(left ?? '') && String(current ?? '') <= String(right ?? ''); + } + if (opKey === 'gt' || opKey === 'lt') { + const cur = Number(current); + const val = Number(value); + if (!Number.isNaN(cur) && !Number.isNaN(val)) { + return opKey === 'gt' ? cur > val : cur < val; + } + return opKey === 'gt' + ? String(current ?? '') > String(value ?? '') + : String(current ?? '') < String(value ?? ''); + } + return String(current ?? '').toLowerCase() === String(value ?? '').toLowerCase(); +} + +function applySourceFilters(items, filters) { + if (!Array.isArray(filters) || filters.length === 0) return items; + const map = { + source: it => it.source, + type: it => it.content_type, + name: it => it.name, + size: it => it.size_bytes, + status: it => it.status, + progress: it => Number(it.percent_done || 0) * 100, + }; + return items.filter((it) => { + return filters.every((f) => { + if (!f || !f.key) return true; + const getter = map[f.key]; + const current = getter ? getter(it) : it[f.key]; + return matchFilterValue(current, f.op, f.value); + }); + }); +} + +function renderMediaRow(body, it) { + if (state.mediaTab === 'series') { + renderSeriesRow(body, it); + } else { + renderFileRow(body, it); + } +} + +function renderSourceRow(body, it) { + const tr = document.createElement('tr'); + tr.appendChild(cellText(it.source ?? '', '', 'source')); + tr.appendChild(cellText(sourceTypeLabel(it.content_type), '', 'type')); + tr.appendChild(cellText(it.name ?? '', '', 'name')); + tr.appendChild(cellText(it.size_bytes ? formatSize(it.size_bytes) : '', 'align-right', 'size')); + tr.appendChild(cellText(it.status ?? '', 'align-center', 'status')); + const percent = Number(it.percent_done ?? 0); + const pctLabel = Number.isFinite(percent) ? Math.round(percent * 100) : 0; + tr.appendChild(cellText(`${pctLabel}%`, 'align-right', 'progress')); + tr.addEventListener('click', () => openSourceDetail(it)); + body.appendChild(tr); +} + +function sourceTypeLabel(type) { + if (type === 'folder') return t('sources.type.folder', 'Folder'); + if (type === 'file') return t('sources.type.file', 'File'); + return ''; +} + +function cellText(txt, className = '', key = '') { + const td = document.createElement('td'); + td.textContent = txt ?? ''; + if (className) td.className = className; + if (key) td.dataset.key = key; + return td; +} + +function createYearCell(year) { + const td = document.createElement('td'); + td.className = 'col-year'; + td.textContent = (year !== null && year !== undefined && year !== '') ? String(year) : ''; + return td; +} + +function createTitleCell(display, original, fallback) { + const td = document.createElement('td'); + td.className = 'col-title'; + const span = document.createElement('span'); + const displayText = display || fallback || ''; + const originalText = original || displayText; + span.textContent = displayText; + span.dataset.display = displayText; + span.dataset.original = originalText; + attachTitleToggle(span); + td.appendChild(span); + return td; +} + +function attachTitleToggle(el) { + const showOriginal = () => { + if (el.dataset.original) el.textContent = el.dataset.original; + }; + const showDisplay = () => { + if (el.dataset.display) el.textContent = el.dataset.display; + }; + el.addEventListener('mousedown', (e) => { + if (e.button !== 0) return; + showOriginal(); + }); + el.addEventListener('mouseup', showDisplay); + el.addEventListener('mouseleave', showDisplay); + el.addEventListener('touchstart', showOriginal, { passive: true }); + el.addEventListener('touchend', showDisplay); +} + +function typeLabel(v) { + if (v === 'auto') return t('types.auto', 'Auto'); + if (v === 'movie') return t('types.movie', 'Movie'); + if (v === 'series') return t('types.series', 'Series'); + return v; +} + +function cellType(it) { + const td = document.createElement('td'); + td.textContent = typeLabel(it.kind ?? 'auto'); + return td; +} + +function issueBadges(issues) { + if (!Array.isArray(issues) || issues.length === 0) return ''; + return issues.map(i => { + if (i === 'rename') return '📝'; + if (i === 'delete') return '🗑'; + if (i === 'unknown_type') return '❓'; + return '⚠'; + }).join(' '); +} + +function renderFileRow(body, it) { + const tr = document.createElement('tr'); + tr.dataset.path = it.abs_path || ''; + + const tdExpand = document.createElement('td'); + const btn = document.createElement('button'); + btn.className = 'expand-btn'; + btn.textContent = '+'; + btn.addEventListener('click', () => toggleFileRow(tr, it, btn)); + tdExpand.appendChild(btn); + tr.appendChild(tdExpand); + + tr.appendChild(cellType(it)); + const displayTitle = it.title_display || it.name || ''; + const originalTitle = it.title_original || displayTitle; + tr.appendChild(createTitleCell(displayTitle, originalTitle, it.name ?? '')); + tr.appendChild(createYearCell(it.year ?? '')); + tr.appendChild(cellText(it.needs_attention ? t('status.needs', 'Needs') : t('status.ok', 'OK'))); + tr.appendChild(cellText(issueBadges(it.issues))); + + body.appendChild(tr); +} + +function renderSeriesRow(body, it) { + const tr = document.createElement('tr'); + tr.dataset.series = it.series_key || ''; + + const tdExpand = document.createElement('td'); + const btn = document.createElement('button'); + btn.className = 'expand-btn'; + btn.textContent = '+'; + btn.addEventListener('click', () => toggleSeriesRow(tr, it, btn)); + tdExpand.appendChild(btn); + tr.appendChild(tdExpand); + + tr.appendChild(cellText(t('types.series', 'Series'))); + const displayTitle = it.title_display || it.series_key || ''; + const originalTitle = it.title_original || displayTitle; + tr.appendChild(createTitleCell(displayTitle, originalTitle, it.series_key ?? '')); + tr.appendChild(createYearCell(it.year ?? '')); + const status = (it.needs_attention > 0) ? t('status.needs', 'Needs') : t('status.ok', 'OK'); + tr.appendChild(cellText(status)); + tr.appendChild(cellText(issueBadges(it.issues))); + + body.appendChild(tr); +} + +async function loadMediaList() { + const mediaTable = state.tables.media; + const sourcesTable = state.tables.sources; + if (state.mediaTab === 'sources') { + if (sourcesTable) { + sourcesTable.setParams({}); + await sourcesTable.load(1, false); + } + return; + } + if (mediaTable) { + mediaTable.setParams({ tab: state.mediaTab }); + await mediaTable.load(1, false); + } +} + +async function loadSources() { + const sourcesTable = state.tables.sources; + if (sourcesTable) { + await sourcesTable.load(1, false); + } +} + +async function toggleFileRow(tr, it, btn) { + const next = tr.nextElementSibling; + if (next && next.classList.contains('detail-row')) { + next.remove(); + if (btn) btn.textContent = '+'; + return; + } + if (btn) btn.textContent = '-'; + + const detail = document.createElement('tr'); + detail.className = 'detail-row'; + const td = document.createElement('td'); + td.colSpan = 6; + td.textContent = t('common.loading', 'Loading…'); + detail.appendChild(td); + tr.after(detail); + + const res = await api('/api/media/file?path=' + encodeURIComponent(it.abs_path || '')); + if (!res.ok || !res.data) { + td.textContent = t('common.error', 'Error'); + return; + } + td.innerHTML = renderDetail(res.data); + bindMetadataHandlers(td); +} + +async function toggleSeriesRow(tr, it, btn) { + const next = tr.nextElementSibling; + if (next && next.classList.contains('detail-row')) { + next.remove(); + if (btn) btn.textContent = '+'; + return; + } + if (btn) btn.textContent = '-'; + + const detail = document.createElement('tr'); + detail.className = 'detail-row'; + const td = document.createElement('td'); + td.colSpan = 6; + td.textContent = t('common.loading', 'Loading…'); + detail.appendChild(td); + tr.after(detail); + + const res = await api('/api/media/series?key=' + encodeURIComponent(it.series_key || '')); + if (!res.ok || !res.data) { + td.textContent = t('common.error', 'Error'); + return; + } + td.innerHTML = renderSeriesDetail(res.data || {}); + bindSeriesDetailHandlers(td); + bindMetadataHandlers(td); +} + +function renderDetail(data) { + const file = data.file || {}; + const tracks = data.tracks || []; + const meta = data.meta || {}; + + let html = ''; + html += `
`; + html += `
${escapeHtml(file.abs_path || '')}
`; + html += `
` + + `${t('media.container','Container')}: ${escapeHtml(file.container || t('common.na','n/a'))} ` + + `${t('media.size','Size')}: ${formatSize(file.size_bytes || 0)} ` + + `${t('media.duration','Duration')}: ${formatDuration(file.duration_ms || 0)}` + + `
`; + html += `
`; + html += renderMetaBox(meta, file.name || '', file.kind || 'movie'); + + html += `` + + `` + + `` + + `` + + `` + + `` + + `` + + `` + + ``; + + for (const tr of tracks) { + const flags = []; + if (tr.default) flags.push('default'); + if (tr.forced) flags.push('forced'); + html += `` + + `` + + `` + + `` + + `` + + `` + + `` + + `` + + ``; + } + + html += `
${t('media.track.type','Type')}${t('media.track.lang','Lang')}${t('media.track.name','Name')}${t('media.track.codec','Codec')}${t('media.track.channels','Channels')}${t('media.track.flags','Flags')}${t('media.track.audio_type','Audio type')}
${escapeHtml(tr.type || '')}${escapeHtml(tr.lang || '')}${escapeHtml(tr.name_norm || tr.name || '')}${escapeHtml(tr.codec || '')}${escapeHtml(tr.channels || '')}${escapeHtml(flags.join(','))}${escapeHtml(tr.audio_type || '')}
`; + return html; +} + +function renderSeriesDetail(payload) { + const files = Array.isArray(payload.files) ? payload.files : []; + const meta = payload.meta || {}; + let html = renderMetaBox(meta, meta.title_display || '', 'series'); + html += `` + + `` + + `` + + `` + + `` + + `` + + ``; + for (const f of files) { + html += `` + + `` + + `` + + `` + + `` + + `` + + ``; + } + html += `
${t('grid.name','Name')}${t('grid.path','Path')}${t('grid.status','Status')}${t('grid.issues','Issues')}
${escapeHtml(f.name || '')}${escapeHtml(f.rel_path || f.abs_path || '')}${escapeHtml(f.needs_attention ? t('status.needs','Needs') : t('status.ok','OK'))}${escapeHtml(issueBadges(f.issues))}
`; + return html; +} + +function renderMetaBox(meta, fallbackTitle, type) { + const subjectKind = meta.subject_kind || type || 'movie'; + const subjectKey = meta.subject_key || ''; + const titleDisplay = meta.title_display || ''; + const titleOriginal = meta.title_original || ''; + const year = (meta.year !== null && meta.year !== undefined) ? String(meta.year) : ''; + const provider = meta.provider || ''; + const providerId = meta.provider_id || ''; + const source = meta.source || 'auto'; + const manualTitle = meta.manual_title || ''; + const manualYear = (meta.manual_year !== null && meta.manual_year !== undefined) ? String(meta.manual_year) : ''; + + let html = ''; + html += `
`; + html += `
`; + html += `
${t('meta.title','Title')}${escapeHtml(titleDisplay || fallbackTitle)}
`; + html += `
${t('meta.original','Original')}${escapeHtml(titleOriginal)}
`; + html += `
${t('meta.year','Year')}${escapeHtml(year)}
`; + html += `
${t('meta.provider','Provider')}${escapeHtml(providerId ? (provider + ' / ' + providerId) : provider)}
`; + html += `
${t('meta.source','Source')}${escapeHtml(source)}
`; + html += `
`; + + html += `
`; + html += ``; + html += `
`; + + html += `
` + + `` + + `` + + `` + + `` + + `
`; + html += `
`; + html += `
`; + return html; +} + +function bindSeriesDetailHandlers(root) { + root.querySelectorAll('button[data-action="file"]').forEach(btn => { + btn.addEventListener('click', async () => { + const tr = btn.closest('tr'); + if (!tr) return; + const path = tr.dataset.path || ''; + const next = tr.nextElementSibling; + if (next && next.classList.contains('detail-row')) { + next.remove(); + btn.textContent = '+'; + return; + } + btn.textContent = '-'; + const detail = document.createElement('tr'); + detail.className = 'detail-row'; + const td = document.createElement('td'); + td.colSpan = 5; + td.textContent = t('common.loading', 'Loading…'); + detail.appendChild(td); + tr.after(detail); + const res = await api('/api/media/file?path=' + encodeURIComponent(path)); + if (!res.ok || !res.data) { + td.textContent = t('common.error', 'Error'); + return; + } + td.innerHTML = renderDetail(res.data); + bindMetadataHandlers(td); + }); + }); +} + +function bindMetadataHandlers(root) { + root.querySelectorAll('.meta-box').forEach(box => { + const subjectKind = box.dataset.subjectKind || 'movie'; + const subjectKey = box.dataset.subjectKey || ''; + const type = box.dataset.type || 'movie'; + const resultsEl = box.querySelector('[data-role="results"]'); + const queryInput = box.querySelector('[data-role="query"]'); + const manualTitle = box.querySelector('[data-role="manual-title"]'); + const manualYear = box.querySelector('[data-role="manual-year"]'); + + const setDisplay = (data) => { + if (!data) return; + const title = data.title_display || ''; + const original = data.title_original || ''; + const year = (data.year !== null && data.year !== undefined) ? String(data.year) : ''; + const provider = data.meta?.provider || data.provider || ''; + const providerId = data.meta?.provider_id || data.provider_id || ''; + const source = data.meta?.source || data.source || 'auto'; + + const titleEl = box.querySelector('[data-role="title"]'); + const origEl = box.querySelector('[data-role="original"]'); + const yearEl = box.querySelector('[data-role="year"]'); + const provEl = box.querySelector('[data-role="provider"]'); + const srcEl = box.querySelector('[data-role="source"]'); + + if (titleEl) titleEl.textContent = title; + if (origEl) origEl.textContent = original; + if (yearEl) yearEl.textContent = year; + if (provEl) provEl.textContent = providerId ? `${provider} / ${providerId}` : provider; + if (srcEl) srcEl.textContent = source; + + if (manualTitle) manualTitle.value = data.meta?.manual_title || ''; + if (manualYear) manualYear.value = data.meta?.manual_year ?? ''; + + updateRowMeta(subjectKind, subjectKey, data); + }; + + const onSearch = async () => { + const query = queryInput?.value?.trim() || ''; + if (!query || subjectKey === '') return; + if (resultsEl) resultsEl.textContent = t('common.loading', 'Loading…'); + const res = await api('/api/metadata/search', { + method: 'POST', + body: JSON.stringify({ query, type }), + }); + if (!res.ok) { + if (resultsEl) resultsEl.textContent = t('common.error', 'Error'); + return; + } + renderMetaResults(resultsEl, res.data || [], async (selection) => { + const save = await api('/api/metadata/select', { + method: 'POST', + body: JSON.stringify({ + subject_kind: subjectKind, + subject_key: subjectKey, + selection, + }), + }); + if (save.ok) { + setDisplay(save.data || {}); + } + }); + }; + + const onSaveManual = async () => { + const title = manualTitle?.value?.trim() || ''; + const year = manualYear?.value?.trim() || ''; + if (subjectKey === '') return; + const save = await api('/api/metadata/manual', { + method: 'POST', + body: JSON.stringify({ + subject_kind: subjectKind, + subject_key: subjectKey, + title, + year: year === '' ? null : Number(year), + }), + }); + if (save.ok) { + setDisplay(save.data || {}); + } + }; + + const onClearManual = async () => { + if (subjectKey === '') return; + const save = await api('/api/metadata/manual/clear', { + method: 'POST', + body: JSON.stringify({ + subject_kind: subjectKind, + subject_key: subjectKey, + }), + }); + if (save.ok) { + setDisplay(save.data || {}); + } + }; + + const btnSearch = box.querySelector('[data-action="meta-search"]'); + const btnSave = box.querySelector('[data-action="meta-save"]'); + const btnClear = box.querySelector('[data-action="meta-clear"]'); + if (btnSearch) btnSearch.addEventListener('click', onSearch); + if (btnSave) btnSave.addEventListener('click', onSaveManual); + if (btnClear) btnClear.addEventListener('click', onClearManual); + }); +} + +function renderMetaResults(root, results, onSelect) { + if (!root) return; + root.innerHTML = ''; + if (!Array.isArray(results) || results.length === 0) { + root.textContent = t('meta.no_results', 'No results'); + return; + } + results.forEach(r => { + const btn = document.createElement('button'); + btn.type = 'button'; + btn.className = 'meta-result'; + + const img = document.createElement('img'); + img.alt = ''; + img.loading = 'lazy'; + img.src = r.poster || ''; + img.className = 'meta-poster'; + if (!r.poster) img.style.display = 'none'; + + const body = document.createElement('div'); + body.className = 'meta-result-body'; + + const title = document.createElement('div'); + title.className = 'meta-result-title'; + const titleMap = r.title_map || {}; + const bestTitle = titleMap[state.lang] || r.original_title || titleMap[Object.keys(titleMap)[0]] || ''; + title.textContent = bestTitle; + + const meta = document.createElement('div'); + meta.className = 'meta-result-meta'; + const year = (r.year !== null && r.year !== undefined) ? String(r.year) : ''; + const providerLabel = r.provider_name || r.provider || ''; + meta.textContent = `${providerLabel}${r.provider_id ? ' / ' + r.provider_id : ''}${year ? ' • ' + year : ''}`; + + body.appendChild(title); + body.appendChild(meta); + + btn.appendChild(img); + btn.appendChild(body); + btn.addEventListener('click', () => onSelect(r)); + root.appendChild(btn); + }); +} + +function updateRowMeta(kind, key, data) { + const rows = Array.from(document.querySelectorAll('#grid tbody tr')); + const row = rows.find(r => (kind === 'series') + ? r.dataset.series === key + : r.dataset.path === key); + if (!row) return; + const titleCell = row.querySelector('.col-title span'); + const yearCell = row.querySelector('.col-year'); + const title = data.title_display || ''; + const original = data.title_original || title; + const year = (data.year !== null && data.year !== undefined) ? String(data.year) : ''; + if (titleCell) { + titleCell.textContent = title; + titleCell.dataset.display = title; + titleCell.dataset.original = original; + } + if (yearCell) yearCell.textContent = year; +} + +function escapeHtml(s) { + return String(s).replace(/[&<>"']/g, c => ( + c === '&' ? '&' : + c === '<' ? '<' : + c === '>' ? '>' : + c === '"' ? '"' : ''' + )); +} + +function formatSize(bytes) { + const b = Number(bytes || 0); + if (!b) return '0 B'; + const units = ['B','KB','MB','GB','TB']; + let i = 0; + let v = b; + while (v >= 1024 && i < units.length - 1) { + v /= 1024; + i++; + } + return `${v.toFixed(1)} ${units[i]}`; +} + +function formatDuration(ms) { + const m = Number(ms || 0); + if (!m) return t('common.na','n/a'); + const total = Math.floor(m / 1000); + const h = Math.floor(total / 3600); + const min = Math.floor((total % 3600) / 60); + const s = total % 60; + return `${h}:${String(min).padStart(2,'0')}:${String(s).padStart(2,'0')}`; +} + +function formatSpeed(bytesPerSec) { + return `${UI.formatBytes(bytesPerSec)}/s`; +} + +function formatDate(ts) { + const n = Number(ts || 0); + if (!Number.isFinite(n) || n <= 0) return t('common.na', 'n/a'); + return new Date(n * 1000).toLocaleString(); +} + +function formatSeconds(sec) { + const n = Number(sec || 0); + if (!Number.isFinite(n) || n <= 0) return t('common.na', 'n/a'); + const h = Math.floor(n / 3600); + const m = Math.floor((n % 3600) / 60); + const s = n % 60; + return `${h}:${String(m).padStart(2,'0')}:${String(s).padStart(2,'0')}`; +} + +function openSourceDetail(item) { + const dlg = UI.qs('dlg-source'); + if (!dlg || !item?.id || !item?.source) return; + state.sourceDetail = { id: item.id, source: item.source }; + state.sourceDetailItem = item; + const title = UI.qs('sourceTitle'); + const meta = UI.qs('sourceMeta'); + const fieldsWrap = UI.qs('sourceFields'); + const raw = UI.qs('sourceRaw'); + if (title) title.textContent = t('sources.detail.title', 'Source detail'); + if (meta) meta.textContent = t('common.loading', 'Loading…'); + if (fieldsWrap) fieldsWrap.innerHTML = ''; + if (raw) raw.textContent = ''; + + fetchSourceDetail(item.source, item.id); + if (typeof dlg.showModal === 'function') dlg.showModal(); +} + +function refreshOpenSourceDetail() { + if (!state.sourceDetail) return; + const now = Date.now(); + if (now - state.sourceDetailLastFetch < 1500) return; + fetchSourceDetail(state.sourceDetail.source, state.sourceDetail.id); +} + +function fetchSourceDetail(source, id) { + state.sourceDetailLastFetch = Date.now(); + const title = UI.qs('sourceTitle'); + const meta = UI.qs('sourceMeta'); + const fieldsWrap = UI.qs('sourceFields'); + const raw = UI.qs('sourceRaw'); + const fallback = state.sourceDetailItem || {}; + api('/api/sources/detail?source=' + encodeURIComponent(source) + '&id=' + encodeURIComponent(id)) + .then(res => { + if (!res || res.ok !== true) { + const msg = res?.error?.message || res?.error || 'Request failed'; + throw new Error(msg); + } + const data = res.data || {}; + state.sourceDetailData = data; + const core = data.core || {}; + if (title) title.textContent = `${core.name || fallback.name || ''}`; + if (meta) { + const pct = Math.round((core.percent_done || 0) * 100); + meta.innerHTML = ` +
${t('sources.source','Source')}: ${core.source || fallback.source || ''}
+
${t('sources.status','Status')}: ${core.status || fallback.status || ''}
+
${t('sources.size','Size')}: ${UI.formatBytes(core.size_bytes || 0)}
+
${t('sources.progress','Progress')}: ${pct}%
+ `; + } + if (fieldsWrap) { + const fields = Array.isArray(data.fields) ? data.fields : []; + fieldsWrap.innerHTML = ''; + fields.forEach(f => { + const val = f.value; + let display = ''; + if (f.type === 'bytes') display = UI.formatBytes(val); + else if (f.type === 'speed') display = formatSpeed(val); + else if (f.type === 'date') display = formatDate(val); + else if (f.type === 'seconds') display = formatSeconds(val); + else if (f.type === 'list') display = Array.isArray(val) ? val.join(', ') : ''; + else display = (val ?? '').toString(); + const card = document.createElement('div'); + card.className = 'source-field'; + card.innerHTML = `
${f.label || f.key || ''}
${display}
`; + fieldsWrap.appendChild(card); + }); + const files = Array.isArray(data.files) ? data.files : []; + if (files.length > 0) { + const tree = buildFileTree(files); + const block = document.createElement('div'); + block.className = 'source-files'; + block.innerHTML = `
${t('sources.files', 'Files')}
`; + block.appendChild(renderFileTree(tree)); + fieldsWrap.appendChild(block); + } + const preview = data.preview || null; + if (preview) { + const block = document.createElement('div'); + block.className = 'source-preview'; + block.innerHTML = ` +
${t('sources.preview.title','Preview')}
+
+
+
${t('sources.preview.current','Current')}
+
${t('sources.preview.name','Name')}: ${preview.current?.name || ''}
+
${t('sources.preview.kind','Type')}: ${preview.current?.kind || ''}
+
${t('sources.preview.structure','Structure')}: ${preview.current?.structure || ''}
+
+
+
${t('sources.preview.planned','Planned')}
+
${t('sources.preview.name','Name')}: ${preview.planned?.name || ''}
+
${t('sources.preview.kind','Type')}: ${preview.planned?.kind || ''}
+
${t('sources.preview.structure','Structure')}: ${preview.planned?.structure || ''}
+ ${preview.planned?.note ? `
${preview.planned?.note}
` : ''} +
+
+ `; + fieldsWrap.appendChild(block); + } + } + if (raw) { + raw.textContent = JSON.stringify(data.raw || {}, null, 2); + } + }) + .catch(e => { + if (meta) meta.textContent = `${t('common.error','Error')}: ${e.message}`; + }); +} + + +function buildFileTree(files) { + const root = { name: '', children: new Map(), files: [] }; + files.forEach(f => { + const path = (f.path || '').split('/').filter(Boolean); + let node = root; + for (let i = 0; i < path.length; i++) { + const part = path[i]; + if (i === path.length - 1) { + node.files.push({ name: part, meta: f }); + } else { + if (!node.children.has(part)) { + node.children.set(part, { name: part, children: new Map(), files: [] }); + } + node = node.children.get(part); + } + } + }); + return root; +} + +function renderFileTree(node) { + const ul = document.createElement('ul'); + ul.className = 'file-tree'; + node.children.forEach(child => { + const li = document.createElement('li'); + li.innerHTML = `${child.name}`; + li.appendChild(renderFileTree(child)); + ul.appendChild(li); + }); + node.files.forEach(f => { + const li = document.createElement('li'); + const pct = Number.isFinite(f.meta?.percent_done) ? f.meta.percent_done : 0; + const pctText = pct ? ` (${pct}%)` : ''; + li.innerHTML = `${f.name}${pctText}`; + ul.appendChild(li); + }); + return ul; +} +/* --------------------------- + Jobs: global indicator + persistence +--------------------------- */ + +function setActiveJob(jobId) { + state.activeJobId = jobId ? String(jobId) : null; + if (state.activeJobId) { + localStorage.setItem(LS_ACTIVE_JOB, state.activeJobId); + } else { + localStorage.removeItem(LS_ACTIVE_JOB); + } + updateJobIndicatorVisible(!!state.activeJobId); +} + +function updateJobIndicatorVisible(show) { + const el = UI.qs('job-indicator'); + if (!el) return; + if (show) el.classList.remove('hidden'); + else el.classList.add('hidden'); +} + +function updateJobIndicator(job) { + const p = UI.qs('job-indicator-progress'); + if (!p) return; + + const total = Number(job.progress_total || 0); + const cur = Number(job.progress || 0); + const pct = total > 0 ? Math.floor((cur / total) * 100) : 0; + + p.max = 100; + p.value = pct; +} + +function updateQueueSummary(data) { + const summaryEl = UI.qs('queueSummary'); + if (!summaryEl) return; + const activeEl = summaryEl.querySelector('[data-queue-active]'); + const errorsEl = summaryEl.querySelector('[data-queue-errors]'); + const dividerEl = summaryEl.querySelector('[data-queue-divider]'); + if (activeEl || errorsEl) { + const activeLabel = activeEl?.dataset.queueActiveLabel || t('queue.active', 'Active'); + const errorsLabel = errorsEl?.dataset.queueErrorsLabel || t('queue.errors', 'Errors'); + const activeCount = Number(data.running || 0); + const errorsCount = Number(data.errors || 0); + if (activeEl) activeEl.textContent = `${activeLabel}: ${activeCount}`; + if (errorsEl) { + errorsEl.textContent = `${errorsLabel}: ${errorsCount}`; + errorsEl.classList.toggle('is-hidden', errorsCount <= 0); + } + if (dividerEl) dividerEl.classList.toggle('is-hidden', errorsCount <= 0); + return; + } + const textEl = summaryEl.querySelector('[data-queue-text]'); + const template = t('queue.summary', 'Active: {active} | Errors: {errors}'); + const text = template + .replace('{active}', String(data.running || 0)) + .replace('{errors}', String(data.errors || 0)); + if (textEl) { + textEl.textContent = text; + } else { + summaryEl.textContent = text; + } +} + +function isQueueMenuOpen() { + const menu = UI.qs('queueMenu'); + return !!menu && !menu.classList.contains('is-hidden'); +} + +function toggleQueueMenu() { + const menu = UI.qs('queueMenu'); + if (!menu) return; + menu.classList.toggle('is-hidden'); + if (!menu.classList.contains('is-hidden')) { + loadQueueStatus(); + loadQueueRecent(); + } +} + +async function cancelJobById(id) { + if (!id) return; + if (!confirm(t('job.cancel_confirm', 'Cancel job?'))) return; + try { + await api('/api/jobs/cancel', { + method: 'POST', + body: JSON.stringify({ id }), + }); + } catch (e) { + alert(`${t('common.error','Error')}: ${e.message}`); + } +} + +async function loadQueueRecent() { + try { + const res = await api('/api/jobs/recent'); + if (!res.ok || !res.data) return; + state.queueRecentList = res.data.items || []; + if (isQueueMenuOpen()) renderQueueMenu(); + } catch (e) { + // ignore + } +} + +function renderQueueMenu() { + const activeWrap = UI.qs('queueMenuActive'); + const finishedWrap = UI.qs('queueMenuFinished'); + if (!activeWrap || !finishedWrap) return; + + activeWrap.innerHTML = ''; + finishedWrap.innerHTML = ''; + + if (state.queueActiveList.length === 0) { + const empty = document.createElement('div'); + empty.className = 'queue-item-status'; + empty.textContent = t('queue.none_active', 'No active tasks'); + activeWrap.appendChild(empty); + } else { + state.queueActiveList.forEach(j => { + const row = document.createElement('div'); + row.className = 'queue-item'; + const title = document.createElement('div'); + const pct = j.progress_total > 0 ? Math.floor((j.progress / j.progress_total) * 100) : 0; + title.textContent = `${j.title} (${pct}%)`; + const actions = document.createElement('div'); + actions.className = 'queue-item-actions'; + const btn = document.createElement('button'); + btn.className = 'btn'; + btn.textContent = t('queue.cancel', 'Cancel'); + btn.addEventListener('click', () => cancelJobById(j.id)); + actions.appendChild(btn); + row.appendChild(title); + row.appendChild(actions); + activeWrap.appendChild(row); + }); + } + + if (state.queueRecentList.length === 0) { + const empty = document.createElement('div'); + empty.className = 'queue-item-status'; + empty.textContent = t('queue.none_finished', 'No finished tasks'); + finishedWrap.appendChild(empty); + } else { + state.queueRecentList.forEach(j => { + const row = document.createElement('div'); + row.className = 'queue-item'; + const title = document.createElement('div'); + title.textContent = j.title || ''; + const status = document.createElement('div'); + status.className = 'queue-item-status'; + status.textContent = j.status || ''; + row.appendChild(title); + row.appendChild(status); + finishedWrap.appendChild(row); + }); + } + updateSseStats(); +} + +async function loadQueueStatus() { + try { + const res = await api('/api/jobs/status'); + if (!res.ok || !res.data) return; + const data = res.data; + state.background.paused = !!data.paused; + state.queueActiveList = Array.isArray(data.active_list) ? data.active_list : []; + updateQueueSummary(data); + if (data.active) updateJobIndicator(data.active); + if (isQueueMenuOpen()) renderQueueMenu(); + } catch (e) { + // ignore + } +} + +function initQueuePanel() { + const summary = UI.qs('queueSummary'); + if (summary) { + summary.addEventListener('click', toggleQueueMenu); + } + document.addEventListener('click', (e) => { + const menu = UI.qs('queueMenu'); + if (!menu) return; + if (summary && (summary.contains(e.target) || menu.contains(e.target))) return; + menu.classList.add('is-hidden'); + }); + + updateQueueSummary({ running: 0, errors: 0 }); + loadQueueStatus(); +} + +function initWatchdog() { + const minutes = Number(state.background.watchdog_minutes || 0); + if (minutes <= 0) return; + const intervalMs = Math.max(1, Math.floor(minutes / 2)) * 60 * 1000; + if (state.watchdogTimer) clearInterval(state.watchdogTimer); + state.watchdogTimer = setInterval(() => { + api('/api/jobs/watchdog', { + method: 'POST', + body: JSON.stringify({ minutes }), + }).catch(() => {}); + }, intervalMs); +} + +function initSourcesPolling() { + if (state.sourcesPollTimer) clearInterval(state.sourcesPollTimer); +} + +function claimSseLease() { + if (!state.sse.tabId) { + const existing = sessionStorage.getItem('scmedia_sse_tab_id'); + state.sse.tabId = existing || Math.random().toString(36).slice(2); + sessionStorage.setItem('scmedia_sse_tab_id', state.sse.tabId); + } + const now = Date.now(); + const ttlMs = 15000; + const raw = localStorage.getItem(state.sse.leaseKey) || ''; + let lease = null; + try { + lease = raw ? JSON.parse(raw) : null; + } catch (e) { + lease = null; + } + if (lease && lease.ts && (now - lease.ts) < ttlMs && lease.id !== state.sse.tabId) { + return false; + } + localStorage.setItem(state.sse.leaseKey, JSON.stringify({ ts: now, id: state.sse.tabId })); + return true; +} + +function refreshSseLease() { + localStorage.setItem(state.sse.leaseKey, JSON.stringify({ ts: Date.now(), id: state.sse.tabId })); +} + +function releaseSseLease() { + const raw = localStorage.getItem(state.sse.leaseKey) || ''; + try { + const lease = raw ? JSON.parse(raw) : null; + if (lease && lease.id && lease.id !== state.sse.tabId) { + return; + } + } catch (e) { + // ignore + } + localStorage.removeItem(state.sse.leaseKey); +} + +function initEventsPipe() { + if (!window.EventSource) return false; + if (!claimSseLease()) { + return false; + } + try { + if (state.eventsSource) { + state.eventsSource.close(); + state.eventsSource = null; + } + const open = async () => { + if (!window.Auth?.getAccessToken?.() && window.Auth?.refreshTokens) { + await window.Auth.refreshTokens(); + } + const res = await window.Http.apiJson('/api/auth/sse-key', { method: 'POST' }); + const key = res?.data?.key || ''; + const ttl = Number(res?.data?.expires_in || 60); + if (!res?.ok || !key) { + initSourcesPolling(); + return; + } + document.cookie = `sse_key=${encodeURIComponent(key)}; path=/; max-age=${Math.max(10, ttl)}`; + await new Promise((r) => setTimeout(r, 50)); + const es = new EventSource('/api/events'); + state.eventsSource = es; + es.addEventListener('open', () => { + setSseConnected(true); + state.sse.retryDelayMs = 5000; + refreshSseLease(); + if (state.queuePollTimer) { + clearInterval(state.queuePollTimer); + state.queuePollTimer = null; + } + if (state.sourcesPollTimer) { + clearInterval(state.sourcesPollTimer); + state.sourcesPollTimer = null; + } + loadQueueStatus(); + }); + es.addEventListener('jobs', (e) => { + try { + const data = JSON.parse(e.data); + noteSseEvent('jobs'); + refreshSseLease(); + state.queueActiveList = Array.isArray(data.active_list) ? data.active_list : []; + updateQueueSummary(data); + if (data.active) updateJobIndicator(data.active); + if (isQueueMenuOpen()) renderQueueMenu(); + } catch (err) { + // ignore + } + }); + es.addEventListener('sources', (e) => { + try { + const payload = JSON.parse(e.data); + noteSseEvent('sources'); + refreshSseLease(); + const items = Array.isArray(payload.items) ? payload.items : []; + const removed = Array.isArray(payload.removed) ? payload.removed : []; + const isSnapshot = !!payload.snapshot; + + if (!Array.isArray(state.sourcesCache) || isSnapshot) { + state.sourcesCache = items; + } else { + const map = new Map(); + state.sourcesCache.forEach(it => { + const key = `${it.source || ''}:${it.id || ''}`; + if (key !== ':') map.set(key, it); + }); + items.forEach(it => { + const key = `${it.source || ''}:${it.id || ''}`; + if (key !== ':') map.set(key, it); + }); + removed.forEach(key => map.delete(key)); + state.sourcesCache = Array.from(map.values()); + } + + if (state.mediaTab === 'sources') { + const sourcesTable = state.tables.sources; + if (sourcesTable) sourcesTable.load(sourcesTable.page || 1, false); + } + refreshOpenSourceDetail(); + } catch (err) { + // ignore + } + }); + es.addEventListener('tick', () => { + noteSseEvent('tick'); + refreshSseLease(); + }); + es.addEventListener('error', () => { + if (state.eventsSource) state.eventsSource.close(); + state.eventsSource = null; + state.sse.reconnects += 1; + setSseConnected(false); + const delay = state.sse.retryDelayMs; + state.sse.retryDelayMs = Math.min(state.sse.retryDelayMs * 2, 60000); + releaseSseLease(); + setTimeout(() => initEventsPipe(), delay); + }); + }; + open().catch(() => { + initSourcesPolling(); + releaseSseLease(); + }); + return true; + } catch (e) { + state.eventsSource = null; + releaseSseLease(); + return false; + } +} + +async function restoreJobFromStorage() { + const id = localStorage.getItem(LS_ACTIVE_JOB); + if (!id) return; + + setActiveJob(id); + + // start polling silently + if (state.jobPollTimer) clearInterval(state.jobPollTimer); + state.jobPollTimer = setInterval(async () => { + try { + const res = await api('/api/jobs/get?id=' + encodeURIComponent(id)); + if (!res.ok || !res.job) return; + + updateJobIndicator(res.job); + + if (res.job.status === 'done' || res.job.status === 'error' || res.job.status === 'canceled') { + clearInterval(state.jobPollTimer); + state.jobPollTimer = null; + setActiveJob(null); + } + } catch (e) { + // ignore + } + }, 1200); +} + +/* --------------------------- + Scan +--------------------------- */ + +function openJobDialog() { + const dlg = UI.qs('dlg-job'); + if (dlg && typeof dlg.showModal === 'function') dlg.showModal(); +} + +async function cancelActiveJob() { + if (!state.activeJobId) return; + if (!confirm(t('job.cancel_confirm', 'Cancel job?'))) return; + try { + await api('/api/jobs/cancel', { + method: 'POST', + body: JSON.stringify({ id: state.activeJobId }), + }); + } catch (e) { + alert(`${t('common.error','Error')}: ${e.message}`); + } +} + +async function runScan() { + // Prefer job-based scan. If backend returns job_id, we track progress. + const res = await api('/api/items/scan', { method: 'POST', body: '{}' }); + + if (!res.ok) { + alert(t('errors.scan_failed', 'Scan failed') + ': ' + (res.error || '')); + return; + } + + if (res.job_id) { + openJobDialog(); + await watchJob(res.job_id, { autoClose: true }); + await loadMediaList(); + return; + } + + // Fallback (legacy): scan completes immediately + alert(t('messages.scan_finished', 'Scan finished')); + await loadMediaList(); +} + +async function watchJob(jobId, opts = {}) { + const statusEl = UI.qs('job-status'); + const prog = UI.qs('job-progress'); + const logEl = UI.qs('job-log'); + + setActiveJob(jobId); + + for (;;) { + const res = await api('/api/jobs/get?id=' + encodeURIComponent(jobId)); + if (!res.ok) { + if (statusEl) statusEl.textContent = t('errors.job_fetch', 'Error fetching job'); + setActiveJob(null); + return; + } + + const job = res.job; + updateJobIndicator(job); + + const total = Number(job.progress_total || 0); + const cur = Number(job.progress || 0); + const pct = total > 0 ? Math.floor((cur / total) * 100) : 0; + + if (statusEl) { + statusEl.textContent = + `${t('job.status', 'Status')}: ${job.status} | ${cur}/${total}`; + } + + if (prog) { + prog.max = 100; + prog.value = pct; + } + + if (logEl) { + logEl.textContent = job.log_text || ''; + } + + if (job.status === 'done' || job.status === 'error' || job.status === 'canceled') { + setActiveJob(null); + + if (opts.autoClose) { + // do not force-close dialog; user can read log + } + return; + } + + await sleep(1000); + } +} + +async function runDryRun() { + const dlg = UI.qs('dlg-dry-run'); + const out = UI.qs('dry-run-log'); + if (out) out.textContent = t('common.loading', 'Loading…'); + if (dlg && typeof dlg.showModal === 'function') dlg.showModal(); + + const q = new URLSearchParams(); + q.set('tab', state.mediaTab || 'movies'); + const res = await api('/api/media/dry-run?' + q.toString()); + if (!res.ok || !res.data) { + if (out) out.textContent = t('common.error', 'Error'); + return; + } + + const data = res.data; + let text = ''; + text += `${t('media.dry_run.summary','Summary')}\n`; + text += `${t('media.dry_run.files','Files')}: ${data.files}\n`; + text += `${t('media.dry_run.rename','Rename')}: ${data.rename}\n`; + text += `${t('media.dry_run.delete','Delete')}: ${data.delete}\n`; + text += `${t('media.dry_run.unknown','Unknown type')}: ${data.unknown_type}\n`; + text += `${t('media.dry_run.convert','Convert')}: ${data.convert}\n\n`; + text += `${t('media.dry_run.details','Details')}\n`; + for (const row of data.rows || []) { + text += `- ${row.name} | ${row.actions.join(', ')}\n`; + } + if (out) out.textContent = text; +} + +async function runApply() { + const res = await api('/api/media/apply', { + method: 'POST', + body: JSON.stringify({ tab: state.mediaTab || 'movies' }), + }); + + if (!res.ok) { + alert(t('errors.apply_failed', 'Apply failed') + ': ' + (res.error || '')); + return; + } + + if (res.job_id) { + openJobDialog(); + await watchJob(res.job_id, { autoClose: true }); + await loadMediaList(); + } +} + +/* --------------------------- + Init +--------------------------- */ + +function init() { + if (window.Auth?.requireAuth) { + window.Auth.requireAuth(); + } + window.UI?.initHeader?.(); + state.i18n = window.I18N || {}; + state.lang = window.APP_LANG || 'en'; + setVersion(); + if (window.UserPrefs?.load) { + window.UserPrefs.load().then((prefs) => { + if (prefs?.theme && window.UI?.setTheme) { + window.UI.setTheme(prefs.theme); + } + if (prefs?.language && prefs.language !== state.lang) { + localStorage.setItem('scmedia_lang', prefs.language); + } + }).catch(() => {}); + } + UI.initThemeToggle(); + updateThemeLabel(); + UI.bindThemePreference?.(() => updateThemeLabel()); + initSourceDialog(); + if (UI.qs('btn-scan')) UI.qs('btn-scan').addEventListener('click', runScan); + if (UI.qs('btnJobCancel')) UI.qs('btnJobCancel').addEventListener('click', cancelActiveJob); + + restoreJobFromStorage(); + initMediaTabs(); + updateTabVisibility(); + loadUiSettings() + .then(() => { + initTables(); + if (window.Sse?.on) { + window.Sse.on('jobs', (data) => { + if (!data) return; + noteSseEvent('jobs'); + state.queueActiveList = Array.isArray(data.active_list) ? data.active_list : []; + updateQueueSummary(data); + if (data.active) updateJobIndicator(data.active); + if (isQueueMenuOpen()) renderQueueMenu(); + }); + window.Sse.on('sources', (payload) => { + if (!payload) return; + noteSseEvent('sources'); + const items = Array.isArray(payload.items) ? payload.items : []; + const removed = Array.isArray(payload.removed) ? payload.removed : []; + const isSnapshot = !!payload.snapshot; + if (!Array.isArray(state.sourcesCache) || isSnapshot) { + state.sourcesCache = items; + } else { + const map = new Map(); + state.sourcesCache.forEach(it => { + const key = `${it.source || ''}:${it.id || ''}`; + if (key !== ':') map.set(key, it); + }); + items.forEach(it => { + const key = `${it.source || ''}:${it.id || ''}`; + if (key !== ':') map.set(key, it); + }); + removed.forEach(key => map.delete(key)); + state.sourcesCache = Array.from(map.values()); + } + if (state.mediaTab === 'sources') { + const sourcesTable = state.tables.sources; + if (sourcesTable) sourcesTable.load(sourcesTable.page || 1, false); + } + refreshOpenSourceDetail(); + }); + window.Sse.on('tick', () => { + noteSseEvent('tick'); + }); + } + window.Sse?.start?.(); + initWatchdog(); + loadMediaList(); + }) + .catch(() => { + initTables(); + window.Sse?.start?.(); + initWatchdog(); + loadMediaList(); + }); +} + +init(); + +window.addEventListener('pagehide', () => { + window.Sse?.stop?.(); +}); + +function initMediaTabs() { + const tabs = document.querySelectorAll('#media-tabs .tab'); + tabs.forEach(btn => { + btn.addEventListener('click', () => { + tabs.forEach(x => x.classList.remove('active')); + btn.classList.add('active'); + state.mediaTab = btn.dataset.tab || 'movies'; + updateTabVisibility(); + loadMediaList(); + }); + }); +} + +function updateTabVisibility() { + const grid = UI.qs('grid'); + const sourcesGrid = UI.qs('sources-grid'); + const showSources = state.mediaTab === 'sources'; + const gridWrap = grid?.closest('.table-wrap'); + const sourcesWrap = sourcesGrid?.closest('.table-wrap'); + if (gridWrap) gridWrap.classList.toggle('is-hidden', showSources); + if (sourcesWrap) sourcesWrap.classList.toggle('is-hidden', !showSources); +} diff --git a/public/assets/js/auth.js b/public/assets/js/auth.js new file mode 100644 index 0000000..b81e2d8 --- /dev/null +++ b/public/assets/js/auth.js @@ -0,0 +1,217 @@ +// public/assets/auth.js +/* English comments: auth token helpers and login UI */ + +(function () { + const LS_ACCESS = 'scmedia_access_token'; + const LS_REFRESH = 'scmedia_refresh_token'; + const LS_CLIENT = 'scmedia_client_type'; + let refreshPromise = null; + let refreshTimer = null; + + function getAccessToken() { + return localStorage.getItem(LS_ACCESS) || sessionStorage.getItem(LS_ACCESS) || ''; + } + + function getRefreshToken() { + return localStorage.getItem(LS_REFRESH) || sessionStorage.getItem(LS_REFRESH) || ''; + } + + function getClientType() { + return localStorage.getItem(LS_CLIENT) || sessionStorage.getItem(LS_CLIENT) || 'web'; + } + + function setTokens(tokens, clientType = 'web', remember = true) { + const storage = remember ? localStorage : sessionStorage; + if (tokens?.access_token) storage.setItem(LS_ACCESS, tokens.access_token); + if (tokens?.refresh_token) storage.setItem(LS_REFRESH, tokens.refresh_token); + storage.setItem(LS_CLIENT, clientType); + const other = remember ? sessionStorage : localStorage; + other.removeItem(LS_ACCESS); + other.removeItem(LS_REFRESH); + other.removeItem(LS_CLIENT); + } + + function clearTokens() { + localStorage.removeItem(LS_ACCESS); + localStorage.removeItem(LS_REFRESH); + localStorage.removeItem(LS_CLIENT); + sessionStorage.removeItem(LS_ACCESS); + sessionStorage.removeItem(LS_REFRESH); + sessionStorage.removeItem(LS_CLIENT); + } + + function parseJwt(token) { + if (!token) return null; + const parts = token.split('.'); + if (parts.length !== 3) return null; + try { + const payload = JSON.parse(atob(parts[1].replace(/-/g, '+').replace(/_/g, '/'))); + return payload || null; + } catch (e) { + return null; + } + } + + function getRoles() { + const payload = parseJwt(getAccessToken()); + return Array.isArray(payload?.roles) ? payload.roles : []; + } + + function isAccessExpired(leewaySeconds = 30) { + const payload = parseJwt(getAccessToken()); + const exp = Number(payload?.exp || 0); + if (!exp) return true; + const now = Math.floor(Date.now() / 1000); + return exp <= (now + leewaySeconds); + } + + function isAdmin() { + return getRoles().includes('admin'); + } + + function redirectToLogin() { + if (window.location.pathname !== '/login') { + window.location.href = '/login'; + } + } + + function requireAuth() { + const access = getAccessToken(); + const refresh = getRefreshToken(); + if (!access && !refresh) { + redirectToLogin(); + return; + } + if (!access && refresh) { + refreshTokens().then((ok) => { + if (!ok) redirectToLogin(); + }); + } + } + + async function refreshTokens() { + if (refreshPromise) return refreshPromise; + const refresh = getRefreshToken(); + if (!refresh) return false; + const clientType = getClientType(); + refreshPromise = (async () => { + const tryRefresh = async (token) => { + const res = await fetch('/api/auth/refresh', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ refresh_token: token, client_type: clientType }), + }); + if (!res.ok) return null; + const data = await res.json(); + if (!data?.ok) return null; + return data?.data || {}; + }; + + let data = await tryRefresh(refresh); + if (!data) { + const current = getRefreshToken(); + if (current && current !== refresh) { + data = await tryRefresh(current); + } + } + if (!data) { + clearTokens(); + return false; + } + setTokens(data, clientType); + return true; + })(); + try { + return await refreshPromise; + } finally { + refreshPromise = null; + } + } + + async function logout() { + const refresh = getRefreshToken(); + if (window.UI?.stopSseClient) { + window.UI.stopSseClient(); + } + clearTokens(); + try { + await fetch('/api/auth/logout', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(refresh ? { refresh_token: refresh } : {}), + }); + } catch (e) { + // Ignore logout network errors. + } + redirectToLogin(); + } + + function initSessionRefresh() { + if (refreshTimer) { + clearTimeout(refreshTimer); + refreshTimer = null; + } + const token = getAccessToken(); + const payload = parseJwt(token); + const exp = Number(payload?.exp || 0); + if (!exp) return; + const now = Math.floor(Date.now() / 1000); + const lead = 45; + const delayMs = Math.max(1000, (exp - now - lead) * 1000); + refreshTimer = setTimeout(async () => { + const ok = await refreshTokens(); + if (ok) { + initSessionRefresh(); + return; + } + clearTokens(); + redirectToLogin(); + }, delayMs); + } + + function initHeaderControls() { + const logoutBtn = document.getElementById('btnLogout'); + if (logoutBtn) { + logoutBtn.addEventListener('click', () => { + logout(); + }); + } + const adminBtn = document.getElementById('btnAdmin'); + if (adminBtn) { + adminBtn.classList.toggle('is-hidden', !isAdmin()); + } + loadHeaderAvatar().catch(() => {}); + } + + async function loadHeaderAvatar() { + const img = document.getElementById('headerAvatar'); + if (!img) return; + const token = getAccessToken(); + if (!token) return; + const res = await fetch('/api/account/avatar', { + headers: { Authorization: `Bearer ${token}` }, + }); + if (!res.ok) return; + const blob = await res.blob(); + const url = URL.createObjectURL(blob); + img.onload = () => URL.revokeObjectURL(url); + img.src = url; + } + + window.Auth = { + getAccessToken, + getRefreshToken, + setTokens, + clearTokens, + parseJwt, + getRoles, + isAdmin, + isAccessExpired, + requireAuth, + refreshTokens, + logout, + redirectToLogin, + initHeaderControls, + initSessionRefresh, + }; +})(); diff --git a/public/assets/js/http.js b/public/assets/js/http.js new file mode 100644 index 0000000..6a7fec2 --- /dev/null +++ b/public/assets/js/http.js @@ -0,0 +1,12 @@ +// public/assets/http.js +/* English comments: shared JSON fetch with auth refresh */ + +(function () { + async function apiJson(path, opts = {}) { + return window.Api.request(path, opts); + } + + window.Http = { + apiJson, + }; +})(); diff --git a/public/assets/js/login.js b/public/assets/js/login.js new file mode 100644 index 0000000..18ea88a --- /dev/null +++ b/public/assets/js/login.js @@ -0,0 +1,211 @@ +// public/assets/login.js +/* English comments: login + MFA flow */ + +const qs = (id) => document.getElementById(id); +const i18n = window.I18N || {}; +const t = (key, fallback) => { + if (key && Object.prototype.hasOwnProperty.call(i18n, key)) { + const val = i18n[key]; + return val !== '' ? val : fallback; + } + return fallback; +}; + +const errorKeyByMessage = { + 'Email and password required': 'auth.error.email_password_required', + 'Invalid credentials': 'auth.error.invalid_credentials', + 'Email required': 'auth.error.email_required', + 'Request failed': 'auth.error.request_failed', + 'Code required': 'auth.error.code_required', + 'Invalid code': 'auth.error.invalid_code', +}; + +function normalizeErrorMessage(message, fallbackKey, fallbackText) { + if (message && Object.prototype.hasOwnProperty.call(errorKeyByMessage, message)) { + return t(errorKeyByMessage[message], message); + } + return message || t(fallbackKey, fallbackText); +} + +function showError(msg) { + const el = qs('loginError'); + if (!el) return; + el.textContent = msg; + el.classList.remove('is-hidden'); +} + +function clearError() { + if (retryTimer) { + clearInterval(retryTimer); + retryTimer = null; + } + const el = qs('loginError'); + if (!el) return; + el.textContent = ''; + el.classList.add('is-hidden'); +} + +let retryTimer = null; +let retryUntilTs = 0; +let retryShown = null; + +function formatRetryMessage(secondsLeft) { + return t('auth.error.too_many_attempts', 'Too many attempts. Try again in {seconds}s.') + .replace('{seconds}', String(secondsLeft)); +} + +function showRetryError(seconds) { + const el = qs('loginError'); + if (!el) return; + const now = Date.now(); + retryUntilTs = now + Math.max(0, seconds) * 1000; + retryShown = null; + el.textContent = formatRetryMessage(Math.max(0, Math.ceil((retryUntilTs - now) / 1000))); + el.classList.remove('is-hidden'); + if (retryTimer) { + clearInterval(retryTimer); + } + retryTimer = setInterval(() => { + const remaining = Math.max(0, Math.ceil((retryUntilTs - Date.now()) / 1000)); + if (retryShown === null) { + retryShown = remaining; + } else if (retryShown > remaining) { + // Smoothly converge if timer drifts or tab throttles. + retryShown = Math.max(remaining, retryShown - 1); + } else { + retryShown = remaining; + } + el.textContent = formatRetryMessage(retryShown); + if (remaining <= 0) { + clearInterval(retryTimer); + retryTimer = null; + } + }, 250); +} + +async function login() { + clearError(); + const email = qs('loginEmail')?.value || ''; + const password = qs('loginPassword')?.value || ''; + const remember = !!qs('loginRemember')?.checked; + if (!email || !password) { + showError(t('auth.error.email_password_required', 'Email and password required')); + return; + } + const res = await fetch('/api/auth/login', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ email, password, client_type: 'web' }), + }); + const data = await res.json(); + if (!data?.ok) { + const retry = data?.error?.retry_after; + if (retry) { + showRetryError(retry); + } else { + const msg = normalizeErrorMessage(data?.error?.message || '', 'auth.error.login_failed', 'Login failed'); + showError(msg); + } + return; + } + if (data?.data?.mfa_required) { + window.__mfaChallenge = data?.data?.challenge_token || ''; + window.__rememberSession = remember; + qs('loginForm')?.classList.add('is-hidden'); + qs('mfaForm')?.classList.remove('is-hidden'); + return; + } + window.Auth.setTokens(data?.data || {}, 'web', remember); + window.location.href = '/'; +} + +function showForgot() { + qs('loginForm')?.classList.add('is-hidden'); + qs('mfaForm')?.classList.add('is-hidden'); + qs('forgotForm')?.classList.remove('is-hidden'); +} + +function showLoginForm() { + qs('forgotForm')?.classList.add('is-hidden'); + qs('mfaForm')?.classList.add('is-hidden'); + qs('loginForm')?.classList.remove('is-hidden'); +} + +async function sendForgot() { + clearError(); + const email = qs('forgotEmail')?.value || ''; + if (!email) { + showError(t('auth.error.email_required', 'Email required')); + return; + } + const res = await fetch('/api/auth/password/forgot', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ email }), + }); + const data = await res.json().catch(() => null); + if (!data?.ok) { + showError(normalizeErrorMessage(data?.error?.message || '', 'auth.error.request_failed', 'Request failed')); + return; + } + showError(t('auth.error.reset_sent', 'If this email exists, a reset link will be sent.')); +} + +async function verifyMfa() { + clearError(); + const code = qs('mfaCode')?.value || ''; + const challenge = window.__mfaChallenge || ''; + const remember = window.__rememberSession !== false; + if (!code || !challenge) { + showError(t('auth.error.code_required', 'Code required')); + return; + } + const res = await fetch('/api/auth/2fa/verify', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ challenge_token: challenge, code, client_type: 'web' }), + }); + const data = await res.json(); + if (!data?.ok) { + const retry = data?.error?.retry_after; + if (retry) { + showRetryError(retry); + } else { + const msg = normalizeErrorMessage(data?.error?.message || '', 'auth.error.invalid_code', 'Invalid code'); + showError(msg); + } + return; + } + window.Auth.setTokens(data?.data || {}, 'web', remember); + window.location.href = '/'; +} + +function init() { + const access = window.Auth?.getAccessToken?.() || ''; + const refresh = window.Auth?.getRefreshToken?.() || ''; + if (access && refresh && window.Auth?.refreshTokens) { + window.Auth.refreshTokens().then((ok) => { + if (ok) { + window.location.href = '/'; + } else if (window.Auth?.clearTokens) { + window.Auth.clearTokens(); + } + }); + return; + } + if (access && window.Auth?.clearTokens) { + window.Auth.clearTokens(); + } + const loginBtn = qs('btnLogin'); + if (loginBtn) loginBtn.addEventListener('click', login); + const forgotBtn = qs('btnForgot'); + if (forgotBtn) forgotBtn.addEventListener('click', showForgot); + const forgotSend = qs('btnForgotSend'); + if (forgotSend) forgotSend.addEventListener('click', sendForgot); + const forgotBack = qs('btnForgotBack'); + if (forgotBack) forgotBack.addEventListener('click', showLoginForm); + const verifyBtn = qs('btnMfaVerify'); + if (verifyBtn) verifyBtn.addEventListener('click', verifyMfa); +} + +init(); diff --git a/public/assets/js/prefs.js b/public/assets/js/prefs.js new file mode 100644 index 0000000..5cc09ba --- /dev/null +++ b/public/assets/js/prefs.js @@ -0,0 +1,80 @@ +// public/assets/prefs.js +/* English comments: user preference storage and sync */ + +(function () { + const DEFAULT_PREFS = { + language: 'en', + theme: 'dark', + table_mode: 'pagination', + table_page_size: 50, + tables: {}, + }; + + let prefs = { ...DEFAULT_PREFS }; + let loaded = false; + let saveTimer = null; + + function mergePrefs(next) { + if (!next || typeof next !== 'object') return; + prefs = { + ...prefs, + ...next, + tables: { ...(prefs.tables || {}), ...(next.tables || {}) }, + }; + } + + async function load() { + if (loaded) return prefs; + const res = await window.Api.request('/api/account', { method: 'GET' }); + const data = res?.data || res || {}; + mergePrefs(data.ui || {}); + loaded = true; + return prefs; + } + + function get() { + return prefs; + } + + function getTable(id) { + if (!id) return {}; + return (prefs.tables && prefs.tables[id]) ? prefs.tables[id] : {}; + } + + function scheduleSave() { + if (!loaded) return; + if (saveTimer) clearTimeout(saveTimer); + saveTimer = setTimeout(() => { + saveTimer = null; + save().catch(() => {}); + }, 500); + } + + async function save() { + if (!loaded) return; + await window.Api.request('/api/account', { + method: 'POST', + body: { ui: prefs }, + }); + } + + function setTable(id, data) { + if (!id) return; + prefs.tables = { ...(prefs.tables || {}), [id]: { ...(prefs.tables?.[id] || {}), ...data } }; + scheduleSave(); + } + + function setUi(key, value) { + if (!key) return; + prefs[key] = value; + scheduleSave(); + } + + window.UserPrefs = { + load, + get, + getTable, + setTable, + setUi, + }; +})(); diff --git a/public/assets/js/settings.js b/public/assets/js/settings.js new file mode 100644 index 0000000..2a31f3a --- /dev/null +++ b/public/assets/js/settings.js @@ -0,0 +1,3510 @@ +/* public/assets/settings.js */ + +const state = { + settings: null, + profiles: [], + dirty: false, + editProfileId: null, + draggingId: null, + mediaRules: null, + rulesList: [], + ruleSort: { + field: 'name', + dir: 'asc', + }, + tasksList: [], + toolsList: [], + toolEditType: null, + ruleEditId: null, + ruleEditType: null, + rootsList: [], + rootEditId: null, + taskEditId: null, + logsView: { + from: '', + to: '', + }, + auditItems: [], + auditSelected: new Map(), + auditItemsCache: new Map(), + logSelected: new Map(), + logItemsCache: new Map(), + snapshots: [], + ui: { + table_mode: 'pagination', + table_page_size: 50, + }, + tables: {}, + settingsLoadPromise: null, +}; + +const AUDIT_EVENTS = [ + 'register', + 'login_failed', + 'login_mfa_required', + 'login', + 'mfa_failed', + 'refresh', + 'logout', + 'mfa_setup', + 'mfa_enabled', + 'mfa_disabled', + 'password_reset_requested', + 'password_reset', + 'roles_changed', + 'user_disabled', + 'user_enabled', + 'mfa_reset', + 'forced_logout', + 'password_change', + 'password_change_failed', + 'email_change', +]; + +const i18n = { + lang: 'ru', + dict: {}, +}; + +function t(key, fallback) { + const v = i18n.dict && Object.prototype.hasOwnProperty.call(i18n.dict, key) ? i18n.dict[key] : null; + return (typeof v === 'string' && v.length) ? v : (fallback ?? key); +} + +function setStatus(text) { + const el = UI.qs('#status'); + if (el) el.textContent = text; +} + +function setDirty(d) { + state.dirty = d; + const btn = UI.qs('#btnSave'); + if (btn) btn.disabled = !d; + const statusEl = UI.qs('#status'); + + if (d) { + setStatus(t('common.unsaved_changes', 'Unsaved changes')); + if (statusEl) statusEl.classList.add('dirty'); + localStorage.setItem('scmedia_settings_dirty', '1'); + } + if (!d) { + if (statusEl) statusEl.classList.remove('dirty'); + localStorage.removeItem('scmedia_settings_dirty'); + } +} + +function paginateItems(items, page, perPage) { + const total = items.length; + const size = Math.max(1, Number(perPage || 50)); + const p = Math.max(1, Number(page || 1)); + const start = (p - 1) * size; + return { + items: items.slice(start, start + size), + total, + page: p, + per_page: size, + }; +} + +function sortItems(items, sortKey, dir, valueMap) { + if (!sortKey || !valueMap?.[sortKey]) return items; + const getter = valueMap[sortKey]; + const asc = dir !== 'desc'; + const out = [...items]; + out.sort((a, b) => { + const av = getter(a); + const bv = getter(b); + if (av === bv) return 0; + if (asc) return av < bv ? -1 : 1; + return av > bv ? -1 : 1; + }); + return out; +} + +const RULE_TYPES = { + name_map: { label: 'Name mapping', i18n: 'rules.type.name_map' }, + delete_track: { label: 'Delete tracks', i18n: 'rules.type.delete_track' }, + priorities: { label: 'Priorities', i18n: 'rules.type.priorities' }, + lang_fix: { label: 'Language fix', i18n: 'rules.type.lang_fix' }, + source_filter: { label: 'Source filter', i18n: 'rules.type.source_filter' }, +}; + +function ruleTypeLabel(type) { + const info = RULE_TYPES[type]; + if (!info) return type || ''; + return t(info.i18n, info.label); +} + +function buildSourceOptions(selected) { + const out = []; + const sourcesCfg = state.pluginConfig?.sources || {}; + if (sourcesCfg.transmission) { + out.push({ value: 'transmission', label: t('settings.plugins.transmission_label', 'Transmission') }); + } + if (selected && !out.some(o => o.value === selected)) { + out.push({ value: selected, label: selected }); + } + if (out.length === 0) { + out.push({ value: 'transmission', label: t('settings.plugins.transmission_label', 'Transmission') }); + } + return out; +} + +function renderSourceOptions(selected) { + return buildSourceOptions(selected) + .map(o => ``) + .join(''); +} + +function applyI18n() { + const themeLabel = UI.qs('#themeState'); + if (themeLabel) { + const mode = document.documentElement.getAttribute('data-theme') || 'dark'; + themeLabel.textContent = (mode === 'light') + ? t('theme.light', 'Light') + : t('theme.dark', 'Dark'); + } +} + +async function api(url, method = 'GET', body = null) { + const opts = { method }; + if (body !== null) { + opts.body = body; + } + const res = await window.Api.request(url, opts); + return res.data; +} + +function commaToList(s) { + const t = (s || '').split(',').map(x => x.trim()).filter(Boolean); + return Array.from(new Set(t)); +} + +function listToComma(a) { + if (!Array.isArray(a)) return ''; + return a.join(','); +} + +function formatBytes(n) { + const v = Number(n || 0); + if (!isFinite(v) || v <= 0) return ''; + const units = ['B', 'KB', 'MB', 'GB', 'TB']; + let idx = 0; + let cur = v; + while (cur >= 1024 && idx < units.length - 1) { + cur /= 1024; + idx += 1; + } + return `${cur.toFixed(cur >= 10 ? 0 : 1)} ${units[idx]}`; +} + +function initTabs() { + UI.qsa('nav.tabs .tab').forEach(btn => { + btn.addEventListener('click', () => { + console.log('[debug] tab click', btn.dataset.tab); + UI.qsa('nav.tabs .tab').forEach(x => x.classList.remove('active')); + UI.qsa('.tabpane').forEach(x => x.classList.remove('active')); + + btn.classList.add('active'); + const pane = UI.qs(`#pane-${btn.dataset.tab}`); + if (pane) pane.classList.add('active'); + if (btn.dataset.tab === 'debug') { + console.log('[debug] tab debug: loadDebugStats'); + loadDebugStats().catch(() => {}); + } + }); + }); +} + +function enforceAdminAccess() { + const auth = window.Auth; + if (!auth) return; + const access = auth.getAccessToken?.(); + const refresh = auth.getRefreshToken?.(); + if (!access && refresh && auth.refreshTokens) { + auth.refreshTokens().then((ok) => { + if (!ok || (auth.isAdmin && !auth.isAdmin())) { + window.location.href = '/'; + } + }); + return; + } + if (auth.isAdmin && !auth.isAdmin()) { + window.location.href = '/'; + } +} + +function bindDirtyInputs() { + // NOTE: language switch should NOT mark settings dirty + UI.qsa('input,select').forEach(el => { + if (el.dataset.local === 'true') return; + if (el.closest('#ruleModal')) return; + + el.addEventListener('change', () => setDirty(true)); + el.addEventListener('input', () => setDirty(true)); + }); +} + +function setVersion() { + const el = UI.qs('[data-version] .version'); + if (el && typeof APP_VERSION === 'string') { + el.textContent = `v${APP_VERSION}`; + } +} + +function updateAboutVersions(meta) { + const uiVersion = (typeof APP_VERSION === 'string' && APP_VERSION) ? APP_VERSION : ''; + const backendVersion = meta?.backend_version || ''; + const dbVersion = meta?.db_version || ''; + + const pluginsTable = UI.qs('#aboutPluginsTable tbody'); + if (pluginsTable) { + const plugins = [ + { name: 'UI', type: 'Core', author: 'SAFE-CAP', version: uiVersion || '-', update: '-' }, + { name: 'Backend', type: 'Core', author: 'SAFE-CAP', version: backendVersion || '-', update: '-' }, + { name: 'Database', type: 'Core', author: 'SAFE-CAP', version: dbVersion || '-', update: '-' }, + { name: 'OMDb', type: 'Metadata', author: 'OMDb API', version: '0.1.0', update: '-' }, + { name: 'TVDB', type: 'Metadata', author: 'TheTVDB', version: '0.1.0', update: '-' }, + { name: 'Kodi', type: 'Export', author: 'Kodi', version: '0.1.0', update: '-' }, + { name: 'Jellyfin', type: 'Export', author: 'Jellyfin', version: '0.1.0', update: '-' }, + { name: 'Transmission', type: 'Source', author: 'Transmission', version: '0.1.0', update: '-' }, + ]; + pluginsTable.innerHTML = ''; + for (const p of plugins) { + const tr = document.createElement('tr'); + const tdName = document.createElement('td'); + tdName.textContent = p.name; + const tdType = document.createElement('td'); + tdType.textContent = p.type; + const tdAuthor = document.createElement('td'); + tdAuthor.textContent = p.author; + const tdVersion = document.createElement('td'); + tdVersion.textContent = p.version; + const tdUpdate = document.createElement('td'); + tdUpdate.textContent = p.update; + tr.append(tdName, tdType, tdAuthor, tdVersion, tdUpdate); + pluginsTable.appendChild(tr); + } + } +} + +/* --------------------------- + Profiles +--------------------------- */ + +function renderProfileRow(tbody, p) { + const tpl = UI.qs('#tplProfileRow'); + const frag = tpl.content.cloneNode(true); + const tr = frag.querySelector('tr'); + tr.dataset.id = String(p.id); + tr.draggable = true; + + const enabled = tr.querySelector('[data-field="enabled"]'); + enabled.checked = !!p.enabled; + enabled.dataset.action = 'toggle'; + enabled.dataset.id = String(p.id); + + tr.querySelector('[data-field="profile_type"]').textContent = typeLabel(p.profile_type || 'scan'); + tr.querySelector('[data-field="name"]').textContent = p.name || ''; + tr.querySelector('[data-field="root_path"]').textContent = p.root_path || ''; + tr.querySelector('[data-field="max_depth"]').textContent = String(p.max_depth ?? ''); + tr.querySelector('[data-field="exclude"]').textContent = (p.exclude_patterns || []).join(', '); + tr.querySelector('[data-field="ext"]').textContent = + (p.include_ext_mode === 'custom') + ? ((p.include_ext || []).join(',')) + : t('settings.scan_profiles.ext_default', 'default'); + + tr.querySelector('[data-field="last_scan"]').textContent = + p.last_scan_at ? String(p.last_scan_at) : t('common.never', 'never'); + + tr.querySelector('[data-field="last_result"]').textContent = + p.last_result || t('common.never', 'never'); + + const btns = tr.querySelectorAll('button[data-action]'); + btns.forEach(b => { + b.dataset.id = String(p.id); + b.addEventListener('click', onProfileAction); + }); + enabled.addEventListener('change', onProfileToggle); + + tbody.appendChild(frag); +} + +function renderProfiles() { + const table = state.tables.profiles; + if (table) { + table.reload().then(applyI18n); + return; + } + + const tbody = UI.qs('#profilesTable tbody'); + tbody.innerHTML = ''; + for (const p of state.profiles) { + renderProfileRow(tbody, p); + } + applyI18n(); +} + +function typeLabel(v) { + if (v === 'analyze') return t('settings.scan_profiles.type_analyze', 'Analyze'); + return t('settings.scan_profiles.type_scan', 'Scan'); +} + +async function onProfileToggle(e) { + const id = Number(e.target.dataset.id); + const p = state.profiles.find(x => x.id === id); + if (!p) return; + + p.enabled = e.target.checked ? 1 : 0; + + await api(`/api/scan-profiles/${id}`, 'PUT', { + enabled: !!p.enabled, + name: p.name, + root_path: p.root_path, + max_depth: p.max_depth, + profile_type: p.profile_type || 'scan', + exclude_patterns: p.exclude_patterns || [], + include_ext_mode: p.include_ext_mode || 'default', + include_ext: p.include_ext || null, + }); + + setStatus(t('common.saved', 'Saved')); +} + +async function onProfileAction(e) { + const action = e.target.dataset.action; + const id = Number(e.target.dataset.id); + + if (action === 'edit') { + openProfileModal(id); + return; + } + + if (action === 'drag') { + return; + } + + if (action === 'del') { + if (!confirm(t('settings.scan_profiles.confirm_delete', 'Delete profile?'))) return; + await api(`/api/scan-profiles/${id}`, 'DELETE'); + state.profiles = state.profiles.filter(x => x.id !== id); + renderProfiles(); + return; + } +} + +function openProfileModal(id = null) { + state.editProfileId = id; + + const modal = UI.qs('#modal'); + modal.style.display = 'flex'; + + const isNew = id === null; + UI.qs('#modalTitle').textContent = isNew + ? t('settings.scan_profiles.modal_add', 'Add profile') + : t('settings.scan_profiles.modal_edit', 'Edit profile'); + + const p = isNew ? { + enabled: 1, + name: '', + root_path: '', + max_depth: 3, + exclude_patterns: [], + include_ext_mode: 'default', + include_ext: null, + profile_type: 'scan', + } : state.profiles.find(x => x.id === id); + + UI.qs('#pEnabled').value = p.enabled ? '1' : '0'; + UI.qs('#pName').value = p.name || ''; + UI.qs('#pRoot').value = p.root_path || ''; + UI.qs('#pDepth').value = String(p.max_depth || 3); + UI.qs('#pType').value = p.profile_type || 'scan'; + UI.qs('#pExcludes').value = listToComma(p.exclude_patterns || []); + UI.qs('#pExtMode').value = p.include_ext_mode || 'default'; + UI.qs('#pExtCustom').value = listToComma(p.include_ext || []); + refreshExtCustomVisibility(); +} + +function closeProfileModal() { + UI.qs('#modal').style.display = 'none'; + state.editProfileId = null; +} + +function refreshExtCustomVisibility() { + const mode = UI.qs('#pExtMode').value; + UI.qs('#pExtCustomWrap').style.display = (mode === 'custom') ? 'block' : 'none'; +} + +async function saveProfileModal() { + const isNew = state.editProfileId === null; + + const payload = { + enabled: UI.qs('#pEnabled').value === '1', + name: UI.qs('#pName').value.trim(), + root_path: UI.qs('#pRoot').value.trim(), + max_depth: Number(UI.qs('#pDepth').value || 3), + profile_type: UI.qs('#pType').value || 'scan', + exclude_patterns: commaToList(UI.qs('#pExcludes').value), + include_ext_mode: UI.qs('#pExtMode').value, + include_ext: (UI.qs('#pExtMode').value === 'custom') ? commaToList(UI.qs('#pExtCustom').value) : null, + }; + + if (isNew) { + const data = await api('/api/scan-profiles', 'POST', payload); + payload.id = data.id; + state.profiles.push(payload); + } else { + const id = state.editProfileId; + await api(`/api/scan-profiles/${id}`, 'PUT', payload); + const idx = state.profiles.findIndex(x => x.id === id); + state.profiles[idx] = { ...state.profiles[idx], ...payload }; + } + + closeProfileModal(); + await loadProfiles(); +} + +function initProfileReorder() { + const tbody = UI.qs('#profilesTable tbody'); + if (!tbody) return; + + tbody.addEventListener('dragstart', (e) => { + const handle = e.target.closest('.drag-handle'); + const tr = e.target.closest('tr'); + if (!handle || !tr) { + e.preventDefault(); + return; + } + state.draggingId = tr.dataset.id || null; + e.dataTransfer.effectAllowed = 'move'; + }); + + tbody.addEventListener('dragover', (e) => { + e.preventDefault(); + const tr = e.target.closest('tr'); + if (!tr || !state.draggingId) return; + + const dragging = tbody.querySelector(`tr[data-id="${state.draggingId}"]`); + if (!dragging || dragging === tr) return; + + const rect = tr.getBoundingClientRect(); + const after = e.clientY > rect.top + rect.height / 2; + if (after) { + tr.after(dragging); + } else { + tr.before(dragging); + } + }); + + tbody.addEventListener('drop', async (e) => { + e.preventDefault(); + if (!state.draggingId) return; + state.draggingId = null; + await persistProfileOrder(); + }); +} + +async function persistProfileOrder() { + const rows = Array.from(UI.qs('#profilesTable tbody').querySelectorAll('tr')); + const ids = rows.map(r => Number(r.dataset.id)).filter(Boolean); + if (ids.length === 0) return; + + await api('/api/scan-profiles/reorder', 'POST', { ids }); + state.profiles.sort((a, b) => ids.indexOf(a.id) - ids.indexOf(b.id)); + setStatus(t('common.saved', 'Saved')); +} + +/* --------------------------- + Settings UI mapping +--------------------------- */ + +function applySettingsToUI(all, userUi = null) { + const data = all.data || all; // tolerate nesting + state.settings = data; + + // Debug visibility + const meta = data.meta || {}; + if (meta.debug_tools_enabled) { + UI.qs('#tabDebug').style.display = 'block'; + } + if (!meta.allow_db_reset) { + UI.qs('#btnResetDb').disabled = true; + const restoreBtn = UI.qs('#btnDbRestore'); + if (restoreBtn) restoreBtn.disabled = true; + } + updateAboutVersions(meta); + const envEl = UI.qs('#serverEnv'); + if (envEl) envEl.value = meta.env || ''; + const appIdEl = UI.qs('#serverAppId'); + if (appIdEl) appIdEl.value = meta.app_id || ''; + const debugEl = UI.qs('#serverDebug'); + if (debugEl) debugEl.value = meta.debug_tools_enabled ? 'true' : 'false'; + const backendEl = UI.qs('#serverBackendVersion'); + if (backendEl) backendEl.value = meta.backend_version || ''; + const dbVerEl = UI.qs('#serverDbVersion'); + if (dbVerEl) dbVerEl.value = meta.db_version || ''; + + // Scanner defaults + const sd = data.scanner_defaults || {}; + UI.qs('#videoExt').value = listToComma(sd.video_ext || []); + UI.qs('#maxDepthDefault').value = String(sd.max_depth_default ?? 3); + UI.qs('#maxFilesPerItem').value = String(sd.max_files_per_item ?? 3000); + UI.qs('#maxItemsPerScan').value = String(sd.max_items_per_scan ?? 0); + + // Paths (roots list) + const paths = data.paths || {}; + state.rootsList = buildRootsList(paths); + renderRootsList(); + + // Layout (rules moved to Rules tab) + const layout = data.layout || {}; + const cp = layout.collision_policy || 'stop'; + const collisionEl = UI.qs('#collisionPolicy'); + if (collisionEl) collisionEl.value = cp; + + // Tools list + const tools = data.tools || {}; + state.toolsList = buildToolsList(tools); + renderToolsList(); + + // Logs + const logs = data.logs || {}; + UI.qs('#logsRetention').value = String(logs.retention_days ?? 7); + UI.qs('#logsLevel').value = logs.level || 'info'; + + initLogsViewDates(); + + // Rules list (new UI) + const rulesList = Array.isArray(data.rules) ? data.rules : []; + state.rulesList = rulesList.map(r => normalizeRule(r)); + renderRulesList(); + + // Tasks list + const tasks = Array.isArray(data.tasks) ? data.tasks : []; + state.tasksList = tasks.map(t => normalizeTask(t)); + renderTasksList(); + + // Plugins + state.pluginConfig = { + metadata: data.metadata || {}, + exports: data.exports || {}, + sources: data.sources || {}, + }; + normalizePluginConfig(); + renderPluginsList(); + + // UI settings (per-user, stored in account prefs) + const ui = userUi || {}; + const tableMode = ui.table_mode || 'pagination'; + const tableSize = ui.table_page_size || 50; + state.ui = { table_mode: tableMode, table_page_size: tableSize }; + const serverUi = data.ui || {}; + UI.qs('#uiSseTickSeconds').value = String(serverUi.sse_tick_seconds ?? 10); + + // Background policies + const bg = data.background || {}; + const bgMode = UI.qs('#bgMode'); + if (bgMode) bgMode.value = bg.mode || 'light'; + const bgParallel = UI.qs('#bgMaxParallel'); + if (bgParallel) bgParallel.value = String(bg.max_parallel_jobs ?? 1); + const bgNetwork = UI.qs('#bgMaxNetwork'); + if (bgNetwork) bgNetwork.value = String(bg.max_network_jobs ?? 1); + const bgIo = UI.qs('#bgMaxIo'); + if (bgIo) bgIo.value = String(bg.max_io_jobs ?? 1); + const bgSleep = UI.qs('#bgBatchSleep'); + if (bgSleep) bgSleep.value = String(bg.batch_sleep_ms ?? 500); + const bgWatchdog = UI.qs('#bgWatchdog'); + if (bgWatchdog) bgWatchdog.value = String(bg.watchdog_minutes ?? 10); + const bgSseTtl = UI.qs('#bgSseTtl'); + if (bgSseTtl) bgSseTtl.value = String(bg.sse_session_ttl_seconds ?? 20); + + const safety = data.safety || {}; + const safetyDepth = UI.qs('#safetyMaxDepth'); + if (safetyDepth) safetyDepth.value = String(safety.max_depth ?? 10); + const safetyFiles = UI.qs('#safetyMaxFiles'); + if (safetyFiles) safetyFiles.value = String(safety.max_files_per_item ?? 200000); + const safetyItems = UI.qs('#safetyMaxItems'); + if (safetyItems) safetyItems.value = String(safety.max_items_per_scan ?? 1000000); + + setDirty(false); +} + +function collectSettingsFromUI() { + const meta = state.settings?.meta || {}; + const rev = meta.settings_revision ?? 1; + + const scanner_defaults = { + video_ext: commaToList(UI.qs('#videoExt').value), + max_depth_default: Number(UI.qs('#maxDepthDefault').value || 3), + max_files_per_item: Number(UI.qs('#maxFilesPerItem').value || 3000), + max_items_per_scan: Number(UI.qs('#maxItemsPerScan').value || 0), + }; + + const paths = buildPathsPayload(); + + const layout = { + collision_policy: UI.qs('#collisionPolicy')?.value || 'stop', + }; + + const tools = { + mkvmerge_path: toolPathByType('mkvmerge'), + mkvpropedit_path: toolPathByType('mkvpropedit'), + ffmpeg_path: toolPathByType('ffmpeg'), + }; + + const logs = { + retention_days: Number(UI.qs('#logsRetention').value || 7), + level: UI.qs('#logsLevel').value || 'info', + }; + + const background = { + mode: UI.qs('#bgMode')?.value || 'light', + max_parallel_jobs: Number(UI.qs('#bgMaxParallel')?.value || 1), + max_network_jobs: Number(UI.qs('#bgMaxNetwork')?.value || 1), + max_io_jobs: Number(UI.qs('#bgMaxIo')?.value || 1), + batch_sleep_ms: Number(UI.qs('#bgBatchSleep')?.value || 500), + watchdog_minutes: Number(UI.qs('#bgWatchdog')?.value || 10), + sse_session_ttl_seconds: Number(UI.qs('#bgSseTtl')?.value || 20), + paused: !!state.settings?.background?.paused, + }; + const ui = { + sse_tick_seconds: Number(UI.qs('#uiSseTickSeconds')?.value || 10), + }; + const safety = { + max_depth: Number(UI.qs('#safetyMaxDepth')?.value || 10), + max_files_per_item: Number(UI.qs('#safetyMaxFiles')?.value || 200000), + max_items_per_scan: Number(UI.qs('#safetyMaxItems')?.value || 1000000), + }; + + const rules = state.rulesList || []; + const tasks = state.tasksList || []; + + const metadata = state.pluginConfig?.metadata || {}; + const exportsCfg = state.pluginConfig?.exports || {}; + const sources = state.pluginConfig?.sources || {}; + + return { + if_revision: rev, + scanner_defaults, + paths, + tools, + logs, + layout, + ui, + safety, + rules, + sources, + metadata, + exports: exportsCfg, + background, + tasks, + }; +} + +function refreshStrategyVisibility() { + // No-op (layout rules moved to Rules tab) +} + +/* --------------------------- + Data loading +--------------------------- */ + +async function loadSettings() { + setStatus(t('common.loading_settings', 'Loading settings…')); + const data = await api('/api/settings', 'GET'); + console.log('[debug] loadSettings', data); + const meta = data.data?.meta || data.meta || {}; + state.debugToolsEnabled = !!meta.debug_tools_enabled; + const prefs = window.UserPrefs ? await window.UserPrefs.load().catch(() => null) : null; + + // Prefer per-user language, fall back to server default + const lang = (prefs?.language || window.APP_LANG || data.data?.general?.language || data.general?.language || 'ru'); + + // Apply settings to UI, then set status + applySettingsToUI(data, prefs); + if (meta.debug_tools_enabled) { + loadDebugStats().catch(() => {}); + } + + setStatus(t('common.loaded', 'Loaded')); +} + +async function loadDiagnostics() { + const data = await api('/api/settings/diagnostics', 'GET'); + const diag = data.data || data || {}; + const phpEl = UI.qs('#serverPhpVersion'); + if (phpEl) phpEl.value = diag.php_version || ''; + const diskEl = UI.qs('#serverDisk'); + if (diskEl) { + const free = formatBytes(diag.disk?.free_bytes); + const total = formatBytes(diag.disk?.total_bytes); + diskEl.value = (free && total) ? `${free} / ${total}` : ''; + } + const binsEl = UI.qs('#serverBinaries'); + if (binsEl) { + const bins = diag.binaries || {}; + const parts = Object.keys(bins).map(k => `${k}:${bins[k] ? 'ok' : 'missing'}`); + binsEl.value = parts.join(' '); + } + const jobsEl = UI.qs('#serverJobs'); + if (jobsEl) { + const jobs = diag.jobs || {}; + jobsEl.value = `running=${jobs.running || 0} queued=${jobs.queued || 0} error=${jobs.errors || 0}`; + } +} + +async function loadSnapshots() { + const data = await api('/api/settings/snapshots', 'GET'); + const items = data.data?.items || data.items || []; + state.snapshots = items; + renderSnapshots(); +} + +function renderSnapshots() { + const tbody = UI.qs('#snapshotsTable tbody'); + if (!tbody) return; + tbody.innerHTML = ''; + (state.snapshots || []).forEach((s) => { + const tr = document.createElement('tr'); + tr.dataset.id = String(s.id || ''); + const tdId = document.createElement('td'); + tdId.textContent = String(s.id || ''); + const tdLabel = document.createElement('td'); + tdLabel.textContent = s.label || ''; + const tdDate = document.createElement('td'); + tdDate.textContent = s.created_at || ''; + const tdActions = document.createElement('td'); + const btnRestore = document.createElement('button'); + btnRestore.className = 'btn'; + btnRestore.textContent = t('settings.server.snapshot_restore', 'Restore'); + btnRestore.addEventListener('click', () => restoreSnapshot(Number(s.id || 0))); + const btnDelete = document.createElement('button'); + btnDelete.className = 'btn'; + btnDelete.textContent = t('common.delete', 'Delete'); + btnDelete.addEventListener('click', () => deleteSnapshot(Number(s.id || 0))); + tdActions.appendChild(btnRestore); + tdActions.appendChild(btnDelete); + tr.appendChild(tdId); + tr.appendChild(tdLabel); + tr.appendChild(tdDate); + tr.appendChild(tdActions); + tbody.appendChild(tr); + }); +} + +async function createSnapshot() { + const hint = UI.qs('#snapshotsHint'); + if (hint) hint.textContent = t('common.saving', 'Saving…'); + try { + const label = UI.qs('#snapshotLabel')?.value || ''; + await api('/api/settings/snapshots', 'POST', { label }); + if (UI.qs('#snapshotLabel')) UI.qs('#snapshotLabel').value = ''; + await loadSnapshots(); + if (hint) hint.textContent = t('common.saved', 'Saved'); + } catch (e) { + if (hint) hint.textContent = `${t('common.error', 'Error')}: ${e.message}`; + } +} + +async function restoreSnapshot(id) { + if (!id) return; + const ok = confirm(t('settings.server.snapshot_restore_confirm', 'Restore this snapshot? Current settings will be replaced.')); + if (!ok) return; + const hint = UI.qs('#snapshotsHint'); + if (hint) hint.textContent = t('common.running', 'Running…'); + try { + await api('/api/settings/snapshots/restore', 'POST', { id }); + await loadSettings(); + if (hint) hint.textContent = t('common.saved', 'Saved'); + } catch (e) { + if (hint) hint.textContent = `${t('common.error', 'Error')}: ${e.message}`; + } +} + +async function deleteSnapshot(id) { + if (!id) return; + const ok = confirm(t('settings.server.snapshot_delete_confirm', 'Delete this snapshot?')); + if (!ok) return; + const hint = UI.qs('#snapshotsHint'); + if (hint) hint.textContent = t('common.running', 'Running…'); + try { + await api(`/api/settings/snapshots/${id}`, 'DELETE'); + await loadSnapshots(); + if (hint) hint.textContent = t('common.saved', 'Saved'); + } catch (e) { + if (hint) hint.textContent = `${t('common.error', 'Error')}: ${e.message}`; + } +} + +/* --------------------------- + Rules UI (new) +--------------------------- */ + +function normalizeRule(r) { + const id = r?.id || `r_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`; + return { + id, + type: r?.type || 'name_map', + name: r?.name || '', + enabled: (r?.enabled !== false), + config: r?.config || {}, + }; +} + +function normalizeTask(t) { + const id = t?.id || `task_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`; + return { + id, + name: t?.name || '', + enabled: t?.enabled !== false, + sources: Array.isArray(t?.sources) ? t.sources : [], + actions: Array.isArray(t?.actions) ? t.actions : [], + }; +} + +function renderRuleRow(tbody, r) { + const tr = document.createElement('tr'); + tr.dataset.id = r.id; + + const tdName = document.createElement('td'); + tdName.textContent = r.name || t('rules.unnamed', 'Untitled'); + + const tdType = document.createElement('td'); + tdType.textContent = ruleTypeLabel(r.type); + + const tdSummary = document.createElement('td'); + tdSummary.textContent = ruleSummary(r); + + const tdStatus = document.createElement('td'); + tdStatus.textContent = r.enabled ? t('rules.status.on', 'On') : t('rules.status.off', 'Off'); + + const tdActions = document.createElement('td'); + const btnEdit = document.createElement('button'); + btnEdit.className = 'btn'; + btnEdit.textContent = t('common.edit', 'Edit'); + btnEdit.addEventListener('click', () => openRuleModal(r.type, r.id)); + + const btnToggle = document.createElement('button'); + btnToggle.className = 'btn'; + btnToggle.textContent = r.enabled ? t('rules.disable', 'Disable') : t('rules.enable', 'Enable'); + btnToggle.addEventListener('click', () => { + r.enabled = !r.enabled; + renderRulesList(); + setDirty(true); + }); + + const btnDel = document.createElement('button'); + btnDel.className = 'btn'; + btnDel.textContent = t('common.delete', 'Delete'); + btnDel.addEventListener('click', () => { + if (!confirm(t('rules.confirm_delete', 'Delete rule?'))) return; + state.rulesList = state.rulesList.filter(x => x.id !== r.id); + renderRulesList(); + setDirty(true); + }); + + tdActions.appendChild(btnEdit); + tdActions.appendChild(btnToggle); + tdActions.appendChild(btnDel); + + tr.appendChild(tdName); + tr.appendChild(tdType); + tr.appendChild(tdSummary); + tr.appendChild(tdStatus); + tr.appendChild(tdActions); + + tbody.appendChild(tr); +} + +function renderRulesList() { + const field = state.ruleSort.field || 'name'; + const dir = state.ruleSort.dir || 'asc'; + const sortField = UI.qs('#rulesSortField'); + if (sortField) sortField.value = field; + const sortBtn = UI.qs('#rulesSortDir'); + if (sortBtn) sortBtn.textContent = (dir === 'asc') ? '↑' : '↓'; + + const table = state.tables.rules; + if (table) { + table.setSort(field, dir); + table.reload(); + return; + } + + const tbody = UI.qs('#rulesTable tbody'); + if (!tbody) return; + tbody.innerHTML = ''; + + const rows = sortItems(state.rulesList, field, dir, { + name: r => (r.name || '').toLowerCase(), + type: r => (r.type || '').toLowerCase(), + }); + + rows.forEach(r => renderRuleRow(tbody, r)); +} + +function renderTaskRow(tbody, task) { + const tr = document.createElement('tr'); + tr.dataset.id = task.id; + const tdName = document.createElement('td'); + tdName.textContent = task.name || t('rules.unnamed', 'Untitled'); + + const tdSources = document.createElement('td'); + tdSources.textContent = (task.sources || []).map(taskSourceLabel).join(', '); + + const tdActions = document.createElement('td'); + tdActions.textContent = (task.actions || []).map(taskActionLabel).join(', '); + + const tdStatus = document.createElement('td'); + tdStatus.textContent = task.enabled ? t('settings.tasks.status.on', 'On') : t('settings.tasks.status.off', 'Off'); + + const tdButtons = document.createElement('td'); + const btnEdit = document.createElement('button'); + btnEdit.className = 'btn'; + btnEdit.textContent = t('common.edit', 'Edit'); + btnEdit.addEventListener('click', () => openTaskModal(task.id)); + const btnToggle = document.createElement('button'); + btnToggle.className = 'btn'; + btnToggle.textContent = task.enabled ? t('rules.disable', 'Disable') : t('rules.enable', 'Enable'); + btnToggle.addEventListener('click', () => { + task.enabled = !task.enabled; + renderTasksList(); + setDirty(true); + }); + const btnDel = document.createElement('button'); + btnDel.className = 'btn'; + btnDel.textContent = t('common.delete', 'Delete'); + btnDel.addEventListener('click', () => { + if (!confirm(t('settings.tasks.confirm_delete', 'Delete task?'))) return; + state.tasksList = state.tasksList.filter(x => x.id !== task.id); + renderTasksList(); + setDirty(true); + }); + tdButtons.appendChild(btnEdit); + tdButtons.appendChild(btnToggle); + tdButtons.appendChild(btnDel); + + tr.appendChild(tdName); + tr.appendChild(tdSources); + tr.appendChild(tdActions); + tr.appendChild(tdStatus); + tr.appendChild(tdButtons); + tbody.appendChild(tr); +} + +function renderTasksList() { + const table = state.tables.tasks; + if (table) { + table.reload(); + return; + } + const tbody = UI.qs('#tasksTable tbody'); + if (!tbody) return; + tbody.innerHTML = ''; + state.tasksList.forEach(task => renderTaskRow(tbody, task)); +} + +function taskSourceLabel(src) { + if (src === 'library') return t('settings.tasks.source.library', 'Library'); + if (src === 'transmission') return t('settings.tasks.source.transmission', 'Transmission'); + if (src === 'staging') return t('settings.tasks.source.staging', 'Staging'); + return src || ''; +} + +function taskActionLabel(action) { + if (action === 'analyze') return t('settings.tasks.action.analyze', 'Analyze'); + if (action === 'identify') return t('settings.tasks.action.identify', 'Identify'); + if (action === 'normalize') return t('settings.tasks.action.normalize', 'Normalize'); + if (action === 'rename') return t('settings.tasks.action.rename', 'Rename'); + if (action === 'export') return t('settings.tasks.action.export', 'Export'); + return action || ''; +} + +function sourceStatusOptions(source) { + if (source === 'transmission') { + return [ + { value: 'completed', label: t('sources.status.completed', 'completed') }, + { value: 'downloading', label: t('sources.status.downloading', 'downloading') }, + { value: 'seeding', label: t('sources.status.seeding', 'seeding') }, + { value: 'stopped', label: t('sources.status.stopped', 'stopped') }, + { value: 'unknown', label: t('sources.status.unknown', 'unknown') }, + ]; + } + return []; +} + +function renderStatusOptions(source) { + const options = sourceStatusOptions(source); + if (options.length === 0) { + return ``; + } + return options.map(opt => ``).join(''); +} + +function conditionFieldOptions() { + return [ + { value: 'status', label: t('rules.cond.status', 'Status') }, + { value: 'label', label: t('rules.cond.label', 'Label') }, + { value: 'name_regex', label: t('rules.cond.name_regex', 'Name regex') }, + { value: 'path_regex', label: t('rules.cond.path_regex', 'Path regex') }, + { value: 'min_size', label: t('rules.cond.min_size', 'Min size') }, + ]; +} + +function conditionOperatorOptions(field) { + if (field === 'status') { + return [ + { value: 'any', label: t('rules.op.any', 'any') }, + { value: 'in', label: '=' }, + { value: 'not_in', label: '!=' }, + ]; + } + if (field === 'min_size') { + return [ + { value: '>=', label: '>=' }, + { value: '>', label: '>' }, + { value: '<=', label: '<=' }, + { value: '<', label: '<' }, + { value: '=', label: '=' }, + { value: '!=', label: '!=' }, + ]; + } + if (field === 'name_regex' || field === 'path_regex') { + return [ + { value: 'regex', label: 'regex' }, + { value: 'not_regex', label: '!regex' }, + ]; + } + if (field === 'label') { + return [ + { value: 'contains', label: t('rules.op.contains', 'contains') }, + { value: 'not_contains', label: t('rules.op.not_contains', 'not contains') }, + { value: '=', label: '=' }, + { value: '!=', label: '!=' }, + ]; + } + return [ + { value: '=', label: '=' }, + ]; +} + +function createConditionValueControl(field, source, op, value) { + if (field === 'status') { + const sel = document.createElement('select'); + sel.multiple = true; + sel.dataset.field = 'cond_value'; + sel.innerHTML = renderStatusOptions(source); + const values = Array.isArray(value) ? value : []; + Array.from(sel.options).forEach(opt => { + if (values.includes(opt.value)) opt.selected = true; + }); + if (op === 'any') { + sel.disabled = true; + } + return sel; + } + if (field === 'min_size') { + const input = document.createElement('input'); + input.type = 'number'; + input.dataset.field = 'cond_value'; + input.value = value ?? ''; + return input; + } + const input = document.createElement('input'); + input.type = 'text'; + input.dataset.field = 'cond_value'; + input.value = value ?? ''; + return input; +} + +function formatConditionValue(field, source, value, op) { + if (field === 'status') { + if (op === 'any') return t('rules.op.any', 'any'); + const values = Array.isArray(value) ? value : []; + const labels = sourceStatusOptions(source).reduce((acc, s) => { + acc[s.value] = s.label; + return acc; + }, {}); + const parts = values.map(v => labels[v] || v).filter(Boolean); + const orLabel = t('rules.logic.or', 'OR'); + return parts.length ? parts.join(` ${orLabel} `) : t('rules.statuses.none', 'No statuses'); + } + if (field === 'min_size') { + return String(value ?? ''); + } + return String(value ?? ''); +} + +function formatConditionField(field) { + const opt = conditionFieldOptions().find(o => o.value === field); + return opt ? opt.label : field; +} + +function formatConditionOp(field, op) { + if (field === 'status' && op === 'any') return '='; + if (op) return op; + const opts = conditionOperatorOptions(field); + return opts.length ? opts[0].value : '='; +} + +function ruleSummary(r) { + const cfg = r.config || {}; + if (r.type === 'name_map') { + return `${cfg.mode || 'exact'}: ${cfg.pattern || '*'} -> ${cfg.canonical || '*'}`; + } + if (r.type === 'delete_track') { + return `type=${cfg.track_type || '*'} lang=${cfg.lang || '*'} audio=${cfg.audio_type || '*'} contains=${cfg.name_contains || '*'}`; + } + if (r.type === 'priorities') { + const langs = Array.isArray(cfg.languages) ? cfg.languages.join(',') : ''; + const aud = Array.isArray(cfg.audio_types) ? cfg.audio_types.join(',') : ''; + return `langs=${langs || '*'} audio=${aud || '*'}`; + } + if (r.type === 'lang_fix') { + return `${cfg.from_lang || '*'} -> ${cfg.to_lang || '*'} (${cfg.mode || 'exact'})`; + } + if (r.type === 'source_filter') { + const conds = Array.isArray(cfg.conditions) ? cfg.conditions : []; + const condText = conds + .filter(c => c?.enabled !== false) + .map(c => `${c.field || '?'}${c.op || '='}${Array.isArray(c.value) ? c.value.join(',') : (c.value ?? '')}`) + .join(' '); + return `src=${cfg.source || '*'} ${condText || '*'}`; + } + return ''; +} + +function initRulesUi() { + const addBtn = UI.qs('#btnAddRule'); + const menu = UI.qs('#ruleTypeMenu'); + const sortField = UI.qs('#rulesSortField'); + const sortDir = UI.qs('#rulesSortDir'); + const modalClose = UI.qs('#ruleModalClose'); + const modalCancel = UI.qs('#ruleModalCancel'); + const modalSave = UI.qs('#ruleModalSave'); + + if (addBtn && menu) { + addBtn.addEventListener('click', (e) => { + e.preventDefault(); + addBtn.parentElement?.classList.toggle('open'); + }); + menu.querySelectorAll('button[data-rule-type]').forEach(btn => { + btn.addEventListener('click', () => { + const type = btn.dataset.ruleType || 'name_map'; + addBtn.parentElement?.classList.remove('open'); + openRuleModal(type, null); + }); + }); + document.addEventListener('click', (e) => { + if (!addBtn.parentElement?.contains(e.target)) { + addBtn.parentElement?.classList.remove('open'); + } + }); + } + + if (sortField) { + sortField.addEventListener('change', () => { + state.ruleSort.field = sortField.value || 'name'; + renderRulesList(); + }); + } + + if (sortDir) { + sortDir.addEventListener('click', () => { + state.ruleSort.dir = (state.ruleSort.dir === 'asc') ? 'desc' : 'asc'; + renderRulesList(); + }); + } + + if (modalClose) modalClose.addEventListener('click', closeRuleModal); + if (modalCancel) modalCancel.addEventListener('click', closeRuleModal); + if (modalSave) { + modalSave.addEventListener('click', () => { + if (state.taskEditId !== null) return; + saveRuleModal(); + }); + } +} + +function initTaskModalRouting() { + const modalSave = UI.qs('#ruleModalSave'); + const modalCancel = UI.qs('#ruleModalCancel'); + const modalClose = UI.qs('#ruleModalClose'); + if (modalSave) { + modalSave.addEventListener('click', () => { + const body = UI.qs('#ruleModalBody'); + if (!body) return; + if (state.taskEditId !== null) { + saveTaskModal(body); + return; + } + }); + } + if (modalCancel) modalCancel.addEventListener('click', closeRuleModal); + if (modalClose) modalClose.addEventListener('click', closeRuleModal); +} + +function openRuleModal(type, id = null) { + const modal = UI.qs('#ruleModal'); + const body = UI.qs('#ruleModalBody'); + const title = UI.qs('#ruleModalTitle'); + if (!modal || !body || !title) return; + + const rule = id ? state.rulesList.find(r => r.id === id) : null; + const data = rule ? { ...rule } : normalizeRule({ type }); + data.type = type || data.type; + + state.ruleEditId = data.id; + state.ruleEditType = data.type; + state.toolEditType = null; + state.taskEditId = null; + + title.textContent = `${t('rules.modal_title', 'Rule')}: ${ruleTypeLabel(data.type)}`; + body.innerHTML = renderRuleForm(data); + applyRuleFormValues(body, data); + if (data.type === 'source_filter') { + const sourceSel = body.querySelector('[data-field="source"]'); + if (sourceSel) { + sourceSel.addEventListener('change', () => { + renderConditionsTable(body, sourceSel.value, readConditionsTable(body)); + }); + } + } + modal.style.display = 'flex'; +} + +function closeRuleModal() { + const modal = UI.qs('#ruleModal'); + if (modal) modal.style.display = 'none'; + state.ruleEditId = null; + state.ruleEditType = null; + state.toolEditType = null; + state.rootEditId = null; + state.pluginEditType = null; + state.taskEditId = null; +} + +function renderRuleForm(rule) { + const cfg = rule.config || {}; + let fields = ''; + if (rule.type === 'name_map') { + fields += ` + + + + `; + } else if (rule.type === 'delete_track') { + fields += ` + + + + + + + `; + } else if (rule.type === 'priorities') { + fields += ` + + + `; + } else if (rule.type === 'lang_fix') { + fields += ` + + + + `; + } else if (rule.type === 'source_filter') { + const selectedSource = cfg.source || 'transmission'; + const conditions = Array.isArray(cfg.conditions) ? cfg.conditions : []; + fields += ` + + + `; + } + + return ` +
+ + + ${fields} +
+ `; +} + +function applyRuleFormValues(body, rule) { + const cfg = rule.config || {}; + const setVal = (field, value) => { + const el = body.querySelector(`[data-field="${field}"]`); + if (el) el.value = value ?? ''; + }; + setVal('name', rule.name || ''); + setVal('enabled', rule.enabled ? '1' : '0'); + if (rule.type === 'name_map') { + setVal('pattern', cfg.pattern || ''); + setVal('canonical', cfg.canonical || ''); + setVal('mode', cfg.mode || 'exact'); + } else if (rule.type === 'delete_track') { + setVal('track_type', cfg.track_type || ''); + setVal('lang', cfg.lang || ''); + setVal('audio_type', cfg.audio_type || ''); + setVal('name_contains', cfg.name_contains || ''); + setVal('except_default', cfg.except_default ? '1' : '0'); + setVal('except_forced', cfg.except_forced ? '1' : '0'); + } else if (rule.type === 'priorities') { + setVal('languages', (cfg.languages || []).join(',')); + setVal('audio_types', (cfg.audio_types || []).join(',')); + } else if (rule.type === 'lang_fix') { + setVal('from_lang', cfg.from_lang || ''); + setVal('to_lang', cfg.to_lang || ''); + setVal('mode', cfg.mode || 'exact'); + } else if (rule.type === 'source_filter') { + setVal('source', cfg.source || 'transmission'); + const conditions = Array.isArray(cfg.conditions) ? cfg.conditions : buildLegacyConditions(cfg); + renderConditionsTable(body, cfg.source || 'transmission', conditions); + } +} + +function buildLegacyConditions(cfg) { + const conditions = []; + const statuses = Array.isArray(cfg.statuses) ? cfg.statuses : (cfg.status ? [cfg.status] : []); + if (statuses.length > 0) { + conditions.push({ field: 'status', op: 'in', value: statuses }); + } + if (cfg.label) { + conditions.push({ field: 'label', op: 'contains', value: cfg.label }); + } + if (cfg.name_regex) { + conditions.push({ field: 'name_regex', op: 'regex', value: cfg.name_regex }); + } + if (cfg.path_regex) { + conditions.push({ field: 'path_regex', op: 'regex', value: cfg.path_regex }); + } + if (cfg.min_size) { + conditions.push({ field: 'min_size', op: '>=', value: Number(cfg.min_size) }); + } + return conditions; +} + +function renderConditionsTable(body, source, conditions) { + const table = body.querySelector('[data-field="conditions_table"]'); + if (!table) return; + const tbody = table.querySelector('tbody'); + if (!tbody) return; + tbody.innerHTML = ''; + (conditions || []).forEach(c => renderConditionRow(tbody, source, c)); + + initConditionBuilder(body, source, () => { + const cond = readConditionBuilder(body); + if (!cond) return; + renderConditionRow(tbody, source, cond); + }); +} + +function renderConditionRow(tbody, source, cond) { + const tr = document.createElement('tr'); + const fieldCell = document.createElement('td'); + const opCell = document.createElement('td'); + const valueCell = document.createElement('td'); + const enabledCell = document.createElement('td'); + const delCell = document.createElement('td'); + + const field = cond.field || 'status'; + const op = cond.op || ''; + const value = cond.value ?? ''; + + tr.dataset.field = field; + tr.dataset.op = op; + tr.dataset.value = JSON.stringify(value); + tr.dataset.enabled = (cond.enabled === false) ? '0' : '1'; + + fieldCell.textContent = formatConditionField(field); + opCell.textContent = formatConditionOp(field, op); + valueCell.textContent = formatConditionValue(field, source, value, op); + + const enabledBtn = document.createElement('button'); + enabledBtn.type = 'button'; + enabledBtn.className = 'btn'; + const setEnabledLabel = (on) => { + enabledBtn.textContent = on ? t('common.yes','Yes') : t('common.no','No'); + }; + setEnabledLabel(cond.enabled !== false); + enabledBtn.addEventListener('click', () => { + const on = tr.dataset.enabled !== '1'; + tr.dataset.enabled = on ? '1' : '0'; + setEnabledLabel(on); + }); + + const removeBtn = document.createElement('button'); + removeBtn.type = 'button'; + removeBtn.className = 'btn'; + removeBtn.textContent = 'X'; + removeBtn.addEventListener('click', () => tr.remove()); + + enabledCell.appendChild(enabledBtn); + delCell.appendChild(removeBtn); + tr.append(fieldCell, opCell, valueCell, enabledCell, delCell); + tbody.appendChild(tr); +} + +function readConditionsTable(body) { + const rows = Array.from(body.querySelectorAll('[data-field="conditions_table"] tbody tr')); + return rows.map(row => { + const field = row.dataset.field || ''; + const op = row.dataset.op || ''; + let value = row.dataset.value || ''; + try { + value = JSON.parse(value); + } catch { + // keep raw + } + const enabled = row.dataset.enabled !== '0'; + return { field, op, value, enabled }; + }).filter(c => c.field); +} + +function initConditionBuilder(body, source, onAdd) { + const builder = body.querySelector('[data-field="conditions_builder"]'); + if (!builder) return; + const fieldSel = builder.querySelector('[data-field="cond_builder_field"]'); + const opSel = builder.querySelector('[data-field="cond_builder_op"]'); + const valueWrap = builder.querySelector('[data-field="cond_builder_value"]'); + const addBtn = builder.querySelector('[data-action="add_condition"]'); + if (!fieldSel || !opSel || !valueWrap || !addBtn) return; + + fieldSel.innerHTML = ''; + conditionFieldOptions().forEach(opt => { + const o = document.createElement('option'); + o.value = opt.value; + o.textContent = opt.label; + fieldSel.appendChild(o); + }); + + const refreshBuilder = (field, op, value) => { + opSel.innerHTML = ''; + conditionOperatorOptions(field).forEach(opt => { + const o = document.createElement('option'); + o.value = opt.value; + o.textContent = opt.label; + if (opt.value === op) o.selected = true; + opSel.appendChild(o); + }); + if (!opSel.value && opSel.options.length > 0) opSel.value = opSel.options[0].value; + valueWrap.innerHTML = ''; + valueWrap.appendChild(createConditionValueControl(field, source, opSel.value, value)); + }; + + refreshBuilder(fieldSel.value || 'status', opSel.value || '', ''); + fieldSel.onchange = () => refreshBuilder(fieldSel.value, '', ''); + opSel.onchange = () => { + const currentEl = valueWrap.querySelector('[data-field="cond_value"]'); + let val = ''; + if (currentEl && currentEl.multiple) { + val = Array.from(currentEl.selectedOptions).map(o => o.value).filter(Boolean); + } else if (currentEl) { + val = currentEl.value ?? ''; + } + refreshBuilder(fieldSel.value, opSel.value, val); + }; + + addBtn.onclick = () => onAdd(); +} + +function readConditionBuilder(body) { + const builder = body.querySelector('[data-field="conditions_builder"]'); + if (!builder) return null; + const field = builder.querySelector('[data-field="cond_builder_field"]')?.value || ''; + const op = builder.querySelector('[data-field="cond_builder_op"]')?.value || ''; + const valueEl = builder.querySelector('[data-field="cond_value"]'); + let value = ''; + if (valueEl && valueEl.multiple) { + value = Array.from(valueEl.selectedOptions).map(o => o.value).filter(Boolean); + } else if (valueEl) { + value = valueEl.value ?? ''; + } + if (field === 'min_size') { + value = Number(value || 0); + } + if (!field) return null; + return { field, op, value, enabled: true }; +} + +function saveRuleModal() { + const modal = UI.qs('#ruleModal'); + const body = UI.qs('#ruleModalBody'); + if (!modal || !body) return; + if (state.pluginEditType) { + savePluginModal(body); + setDirty(true); + closeRuleModal(); + return; + } + if (state.rootEditId !== null) { + const type = body.querySelector('[data-field="root_type"]')?.value || 'movie'; + const path = body.querySelector('[data-field="root_path"]')?.value?.trim() || ''; + const enabled = body.querySelector('[data-field="root_enabled"]')?.value === '1'; + const current = state.rootsList.find(r => r.id === state.rootEditId); + if (current) { + current.type = type; + current.path = path; + current.enabled = enabled; + } else { + state.rootsList.push({ + id: state.rootEditId, + type, + path, + enabled, + }); + } + renderRootsList(); + setDirty(true); + closeRuleModal(); + return; + } + if (state.toolEditType) { + const path = body.querySelector('[data-field="tool_path"]')?.value?.trim() || ''; + updateToolPath(state.toolEditType, path); + setDirty(true); + closeRuleModal(); + return; + } + const id = state.ruleEditId; + const type = state.ruleEditType; + const current = state.rulesList.find(r => r.id === id) || normalizeRule({ type }); + + const getVal = (field) => body.querySelector(`[data-field="${field}"]`)?.value ?? ''; + const name = getVal('name').trim(); + const enabled = getVal('enabled') === '1'; + const config = {}; + + if (type === 'name_map') { + config.pattern = getVal('pattern').trim(); + config.canonical = getVal('canonical').trim(); + config.mode = getVal('mode') || 'exact'; + } else if (type === 'delete_track') { + config.track_type = getVal('track_type').trim(); + config.lang = getVal('lang').trim(); + config.audio_type = getVal('audio_type').trim(); + config.name_contains = getVal('name_contains').trim(); + config.except_default = getVal('except_default') === '1'; + config.except_forced = getVal('except_forced') === '1'; + } else if (type === 'priorities') { + config.languages = commaToList(getVal('languages')); + config.audio_types = commaToList(getVal('audio_types')); + } else if (type === 'lang_fix') { + config.from_lang = getVal('from_lang').trim(); + config.to_lang = getVal('to_lang').trim(); + config.mode = getVal('mode') || 'exact'; + } else if (type === 'source_filter') { + config.source = getVal('source').trim(); + config.conditions = readConditionsTable(body); + } + + const updated = { + id: current.id, + type, + name, + enabled, + config, + }; + + const idx = state.rulesList.findIndex(r => r.id === current.id); + if (idx >= 0) { + state.rulesList[idx] = updated; + } else { + state.rulesList.push(updated); + } + renderRulesList(); + setDirty(true); + closeRuleModal(); +} + +function escapeHtml(s) { + return String(s).replace(/[&<>"']/g, c => ( + c === '&' ? '&' : + c === '<' ? '<' : + c === '>' ? '>' : + c === '"' ? '"' : ''' + )); +} + +function cellText(value) { + const td = document.createElement('td'); + td.textContent = value ?? ''; + return td; +} + +async function loadProfiles() { + const data = await api('/api/scan-profiles', 'GET'); + state.profiles = data; + renderProfiles(); +} + +function initTableControllers() { + if (!window.TableController) return; + const mode = state.ui.table_mode || 'pagination'; + const pageSize = state.ui.table_page_size || 50; + const getPrefs = (table) => { + const id = table?.dataset?.tableId || table?.id || ''; + const prefs = window.UserPrefs?.getTable?.(id) || {}; + return { id, prefs }; + }; + + const profilesTable = UI.qs('#profilesTable'); + if (profilesTable) { + const { id, prefs } = getPrefs(profilesTable); + state.tables.profiles = new TableController({ + table: profilesTable, + mode, + pageSize, + sort: prefs.sort || '', + dir: prefs.dir || 'asc', + onSortChange: (sort, dir) => window.UserPrefs?.setTable?.(id, { sort, dir }), + fetchPage: ({ page, per_page, sort, dir }) => { + const sorted = sortItems(state.profiles, sort, dir, { + name: p => (p.name || '').toLowerCase(), + }); + return Promise.resolve(paginateItems(sorted, page, per_page)); + }, + renderRow: renderProfileRow, + }); + } + + const rootsTable = UI.qs('#rootsTable'); + if (rootsTable) { + const { id, prefs } = getPrefs(rootsTable); + state.tables.roots = new TableController({ + table: rootsTable, + mode, + pageSize, + sort: prefs.sort || '', + dir: prefs.dir || 'asc', + onSortChange: (sort, dir) => window.UserPrefs?.setTable?.(id, { sort, dir }), + fetchPage: ({ page, per_page, sort, dir }) => { + const sorted = sortItems(state.rootsList, sort, dir, { + path: r => (r.path || '').toLowerCase(), + }); + return Promise.resolve(paginateItems(sorted, page, per_page)); + }, + renderRow: renderRootRow, + }); + } + + const toolsTable = UI.qs('#toolsTable'); + if (toolsTable) { + const { id, prefs } = getPrefs(toolsTable); + state.tables.tools = new TableController({ + table: toolsTable, + mode, + pageSize, + sort: prefs.sort || '', + dir: prefs.dir || 'asc', + onSortChange: (sort, dir) => window.UserPrefs?.setTable?.(id, { sort, dir }), + fetchPage: ({ page, per_page, sort, dir }) => { + const sorted = sortItems(state.toolsList, sort, dir, { + name: t => (t.label || '').toLowerCase(), + }); + return Promise.resolve(paginateItems(sorted, page, per_page)); + }, + renderRow: renderToolRow, + }); + } + + const rulesTable = UI.qs('#rulesTable'); + if (rulesTable) { + const { id, prefs } = getPrefs(rulesTable); + state.tables.rules = new TableController({ + table: rulesTable, + mode, + pageSize, + sort: prefs.sort || '', + dir: prefs.dir || 'asc', + onSortChange: (sort, dir) => window.UserPrefs?.setTable?.(id, { sort, dir }), + fetchPage: ({ page, per_page, sort, dir }) => { + const sortKey = sort || state.ruleSort.field; + const sortDir = dir || state.ruleSort.dir; + const sorted = sortItems(state.rulesList, sortKey, sortDir, { + name: r => (r.name || '').toLowerCase(), + type: r => (r.type || '').toLowerCase(), + }); + return Promise.resolve(paginateItems(sorted, page, per_page)); + }, + renderRow: renderRuleRow, + }); + } + + const pluginsTable = UI.qs('#pluginsTable'); + if (pluginsTable) { + const { id, prefs } = getPrefs(pluginsTable); + state.tables.plugins = new TableController({ + table: pluginsTable, + mode, + pageSize, + sort: prefs.sort || '', + dir: prefs.dir || 'asc', + onSortChange: (sort, dir) => window.UserPrefs?.setTable?.(id, { sort, dir }), + fetchPage: ({ page, per_page, sort, dir }) => { + const list = buildPluginsList(); + const sorted = sortItems(list, sort, dir, { + name: p => (p.label || '').toLowerCase(), + }); + return Promise.resolve(paginateItems(sorted, page, per_page)); + }, + renderRow: renderPluginRow, + }); + } + + const tasksTable = UI.qs('#tasksTable'); + if (tasksTable) { + const { id, prefs } = getPrefs(tasksTable); + state.tables.tasks = new TableController({ + table: tasksTable, + mode, + pageSize, + sort: prefs.sort || '', + dir: prefs.dir || 'asc', + onSortChange: (sort, dir) => window.UserPrefs?.setTable?.(id, { sort, dir }), + fetchPage: ({ page, per_page, sort, dir }) => { + const sorted = sortItems(state.tasksList, sort, dir, { + name: t => (t.name || '').toLowerCase(), + }); + return Promise.resolve(paginateItems(sorted, page, per_page)); + }, + renderRow: renderTaskRow, + }); + } +} + +/* --------------------------- + Actions +--------------------------- */ + +async function doSave() { + const prevRetention = Number(state.settings?.logs?.retention_days ?? 7); + const payload = collectSettingsFromUI(); + const newRetention = Number(payload.logs?.retention_days ?? 7); + if (prevRetention > 0 && newRetention > 0 && newRetention < prevRetention) { + if (!confirm(t('settings.logs.retention_warn', 'Older logs will be deleted. Continue?'))) { + return; + } + } + setStatus(t('common.saving', 'Saving…')); + await api('/api/settings', 'POST', payload); + setDirty(false); + await loadSettings(); + setStatus(t('common.saved', 'Saved')); +} + +async function generatePreview() { + const box = UI.qs('#previewBox'); + if (!box) return; + + box.textContent = t('common.generating_preview', 'Generating preview…'); + + try { + const movies = await api('/api/layout/preview', 'POST', { kind: 'movies', mode: 'samples', limit: 10 }); + const series = await api('/api/layout/preview', 'POST', { kind: 'series', mode: 'samples', limit: 10 }); + + let txt = ''; + txt += `${t('settings.preview.movies','MOVIES')}\n`; + for (const ex of movies.examples || []) { + txt += `- ${ex.input.title} (${ex.input.year ?? t('common.na','n/a')}) -> ${ex.output_abs}\n`; + } + txt += `\n${t('settings.preview.series','SERIES')}\n`; + for (const ex of series.examples || []) { + txt += `- ${ex.input.title} (${ex.input.year ?? t('common.na','n/a')}) -> ${ex.output_abs}\n`; + } + + box.textContent = txt; + } catch (e) { + box.textContent = `${t('common.error','Error')}: ${e.message}`; + } +} + +async function loadDebugStats() { + const filesEl = UI.qs('#dbgContentFiles'); + if (!filesEl) return; + console.log('[debug] loadDebugStats: start'); + try { + const data = await api('/api/debug/stats', 'GET'); + console.log('[debug] loadDebugStats: response', data); + const content = data?.content || {}; + const db = data?.db || {}; + const info = data?.db_info || {}; + UI.qs('#dbgContentFiles').textContent = String(content.files ?? 0); + UI.qs('#dbgContentMeta').textContent = String(content.meta ?? 0); + UI.qs('#dbgContentItems').textContent = String(content.items ?? 0); + UI.qs('#dbgDbTables').textContent = String(db.tables ?? 0); + UI.qs('#dbgDbSize').textContent = UI.formatBytes(db.size_bytes ?? 0); + UI.qs('#dbgDbName').textContent = String(info.db_name || '-'); + UI.qs('#dbgDbUser').textContent = String(info.current_user || info.user_name || '-'); + console.log('[debug] loadDebugStats: db_info', info); + loadDebugTables(); + } catch (e) { + console.log('[debug] loadDebugStats: error', e); + UI.qs('#dbgContentFiles').textContent = '-'; + UI.qs('#dbgContentMeta').textContent = '-'; + UI.qs('#dbgContentItems').textContent = '-'; + UI.qs('#dbgDbTables').textContent = '-'; + UI.qs('#dbgDbSize').textContent = '-'; + UI.qs('#dbgDbName').textContent = '-'; + UI.qs('#dbgDbUser').textContent = '-'; + const body = UI.qs('#dbgDbTablesList tbody'); + if (body) body.innerHTML = ''; + const preview = UI.qs('#dbgDbTablePreview'); + if (preview) preview.textContent = ''; + } +} + +async function loadDebugTables() { + const table = UI.qs('#dbgDbTablesList'); + if (!table) return; + const body = table.querySelector('tbody'); + const status = UI.qs('#dbgDbTablesStatus'); + if (body) body.innerHTML = ''; + if (status) status.textContent = t('common.loading', 'Loading…'); + console.log('[debug] loadDebugTables: start'); + try { + const data = await api('/api/debug/db-tables', 'GET'); + const items = Array.isArray(data?.items) ? data.items : []; + if (status) status.textContent = `items: ${items.length}`; + console.log('[debug] loadDebugTables: items', items.length, items.slice(0, 3)); + if (body) { + if (items.length === 0) { + const row = document.createElement('tr'); + const cell = document.createElement('td'); + cell.colSpan = 2; + cell.textContent = t('common.empty', 'Empty'); + row.appendChild(cell); + body.appendChild(row); + } else { + items.forEach((item) => { + const row = document.createElement('tr'); + row.className = 'db-table-row'; + row.dataset.tableName = item.name || ''; + const name = document.createElement('td'); + name.textContent = item.name || ''; + const count = document.createElement('td'); + count.textContent = String(item.rows ?? 0); + row.appendChild(name); + row.appendChild(count); + body.appendChild(row); + }); + } + } + } catch (e) { + if (body) { + body.innerHTML = `${escapeHtml(e.message)}`; + } + if (status) status.textContent = `error: ${e.message}`; + } +} + +async function loadDebugTablePreview(tableName) { + const preview = UI.qs('#dbgDbTablePreview'); + if (!preview) return; + if (!tableName) { + preview.textContent = ''; + return; + } + preview.textContent = t('common.loading', 'Loading…'); + try { + const data = await api('/api/debug/db-table?name=' + encodeURIComponent(tableName) + '&limit=50', 'GET'); + const rows = Array.isArray(data?.rows) ? data.rows : []; + preview.textContent = rows.length === 0 + ? t('common.empty', 'Empty') + : JSON.stringify(rows, null, 2); + } catch (e) { + preview.textContent = `${t('common.error','Error')}: ${e.message}`; + } +} + +async function debugClearContent() { + UI.qs('#dbgContentOut').textContent = t('common.running', 'Running…'); + try { + await api('/api/debug/clear-content', 'POST', { confirm: UI.qs('#dbgContentConfirm').value.trim() }); + UI.qs('#dbgContentOut').textContent = 'OK'; + window.location.href = '/'; + } catch (e) { + UI.qs('#dbgContentOut').textContent = `${t('common.error','Error')}: ${e.message}`; + } +} + +async function debugResetDb() { + UI.qs('#dbgResetOut').textContent = t('common.running', 'Running…'); + try { + const data = await api('/api/debug/reset-db', 'POST', { confirm: UI.qs('#dbgResetConfirm').value.trim() }); + const log = data.log || []; + UI.qs('#dbgResetOut').textContent = log.join('\n'); + window.location.href = '/'; + } catch (e) { + UI.qs('#dbgResetOut').textContent = `${t('common.error','Error')}: ${e.message}`; + } +} + +async function debugDump() { + const out = UI.qs('#dbgDumpOut'); + out.textContent = t('common.running', 'Running…'); + try { + const res = await fetch('/api/debug/db-dump'); + if (!res.ok) { + throw new Error(`Request failed: ${res.status}`); + } + const blob = await res.blob(); + const url = URL.createObjectURL(blob); + const ts = new Date().toISOString().replace(/[:.]/g, '-'); + const a = document.createElement('a'); + a.href = url; + a.download = `scmedia_dump_${ts}.sql`; + document.body.appendChild(a); + a.click(); + a.remove(); + URL.revokeObjectURL(url); + out.textContent = 'OK'; + } catch (e) { + out.textContent = `${t('common.error','Error')}: ${e.message}`; + } +} + +async function debugRestore() { + const out = UI.qs('#dbgDumpOut'); + const file = UI.qs('#dbgRestoreFile')?.files?.[0]; + if (!file) { + out.textContent = `${t('common.error','Error')}: ${t('settings.debug.dump.restore', 'Restore dump')}`; + return; + } + const ok = confirm(t('settings.debug.dump.restore_confirm', 'Restore database from dump? This will overwrite current data.')); + if (!ok) return; + out.textContent = t('common.running', 'Running…'); + try { + const sql = await file.text(); + await api('/api/debug/db-restore', 'POST', { confirm: 'RESTORE DATABASE', sql }); + out.textContent = 'OK'; + window.location.href = '/'; + } catch (e) { + out.textContent = `${t('common.error','Error')}: ${e.message}`; + } +} + +function init() { + if (window.Auth?.requireAuth) { + window.Auth.requireAuth(); + } + enforceAdminAccess(); + window.UI?.initHeader?.(); + if (window.UserPrefs?.load) { + window.UserPrefs.load().then((prefs) => { + if (prefs?.theme && window.UI?.setTheme) { + window.UI.setTheme(prefs.theme); + } + if (prefs?.language && prefs.language !== (window.APP_LANG || 'en')) { + localStorage.setItem('scmedia_lang', prefs.language); + } + }).catch(() => {}); + } + i18n.dict = window.I18N || {}; + i18n.lang = window.APP_LANG || 'en'; + initTabs(); + setVersion(); + initProfileReorder(); + const logsType = UI.qs('#logsType'); + if (logsType) { + logsType.addEventListener('change', updateLogsTypeUI); + updateLogsTypeUI(); + } + updateAuditEventOptions([]); + const logsEvent = UI.qs('#logsFilterEvent'); + if (logsEvent) { + logsEvent.value = loadLogsEventFilter(); + logsEvent.addEventListener('change', async () => { + saveLogsEventFilter(logsEvent.value || 'all'); + if (!state.tables.audit) return; + const hint = UI.qs('#logsHint'); + if (hint) hint.textContent = t('common.loading', 'Loading…'); + try { + const from = UI.qs('#logsDateFrom').value || ''; + const to = UI.qs('#logsDateTo').value || ''; + state.auditItemsCache = new Map(); + clearAuditSelections(); + const filters = []; + if (from && to) { + filters.push({ key: 'created_at', op: 'between', value: [from, to] }); + } + const eventValue = logsEvent.value || 'all'; + if (eventValue !== 'all') { + filters.push({ key: 'action', op: 'eq', value: eventValue }); + } + state.tables.audit.setFilters(filters); + await state.tables.audit.load(1, false); + const total = Number(state.tables.audit.total || 0); + if (hint) hint.textContent = `${t('common.loaded', 'Loaded')} (${total})`; + } catch (e) { + if (hint) hint.textContent = `${t('common.error','Error')}: ${e.message}`; + } + }); + } + UI.qs('#btnSave')?.addEventListener('click', doSave); + UI.qs('#btnExport')?.addEventListener('click', () => window.open('/api/settings', '_blank')); + + UI.qs('#btnAddProfile')?.addEventListener('click', () => openProfileModal(null)); + UI.qs('#modalClose')?.addEventListener('click', closeProfileModal); + UI.qs('#modalSave')?.addEventListener('click', saveProfileModal); + UI.qs('#pExtMode')?.addEventListener('change', refreshExtCustomVisibility); + + UI.qs('#btnPreview')?.addEventListener('click', generatePreview); + UI.qs('#btnAddRoot')?.addEventListener('click', () => openRootModal(null)); + + UI.qs('#btnClearContent')?.addEventListener('click', debugClearContent); + UI.qs('#btnResetDb')?.addEventListener('click', debugResetDb); + UI.qs('#btnDbDump')?.addEventListener('click', debugDump); + UI.qs('#btnDbRestore')?.addEventListener('click', debugRestore); + const dbTable = UI.qs('#dbgDbTablesList'); + if (dbTable) { + dbTable.addEventListener('dblclick', (e) => { + const row = e.target.closest('tr[data-table-name]'); + if (!row) return; + loadDebugTablePreview(row.dataset.tableName || ''); + }); + } + UI.qs('#btnDetectTools')?.addEventListener('click', detectTools); + UI.qs('#btnCreateSnapshot')?.addEventListener('click', createSnapshot); + UI.qs('#btnLoadLogs')?.addEventListener('click', loadLogs); + UI.qs('#btnCleanupLogs')?.addEventListener('click', cleanupLogs); + UI.qs('#btnResetLogsDate')?.addEventListener('click', resetLogsDates); + UI.qs('#btnLogsCopy')?.addEventListener('click', () => copySelectedLogs().catch(() => {})); + UI.qs('#btnLogsSelectAll')?.addEventListener('click', () => selectAllLogsOnPage()); + initLogsTabs(); + initToolsUi(); + initPluginsUi(); + initTasksUi(); + initTaskModalRouting(); + + initRulesUi(); + + bindDirtyInputs(); + UI.initThemeToggle(); + UI.bindThemePreference?.(() => applyI18n()); + initUnsavedGuard(); + + state.settingsLoadPromise = loadSettings(); + Promise.all([state.settingsLoadPromise, loadProfiles(), loadDiagnostics(), loadSnapshots()]) + .then(() => { + initTableControllers(); + initLogsTable(); + renderProfiles(); + renderRootsList(); + renderToolsList(); + renderRulesList(); + renderPluginsList(); + renderTasksList(); + }) + .catch(e => setStatus(`${t('common.error','Error')}: ${e.message}`)); +} + +init(); + +function initUnsavedGuard() { + window.addEventListener('beforeunload', (e) => { + if (!state.dirty) return; + e.preventDefault(); + e.returnValue = ''; + }); + + document.querySelectorAll('a[href]').forEach(a => { + a.addEventListener('click', (e) => { + if (!state.dirty) return; + const ok = confirm(t('settings.unsaved_confirm', 'Unsaved changes. Leave settings?')); + if (!ok) { + e.preventDefault(); + } + }); + }); +} + +async function loadLogs() { + const type = UI.qs('#logsType')?.value || 'system'; + if (type === 'audit') { + await loadAuditLogs(); + return; + } + const from = UI.qs('#logsDateFrom').value; + const to = UI.qs('#logsDateTo').value; + const level = UI.qs('#logsFilterLevel').value || 'all'; + const hint = UI.qs('#logsHint'); + if (!from || !to) { + if (hint) hint.textContent = t('settings.logs.date_required', 'Select a date range'); + return; + } + if (hint) hint.textContent = t('common.loading', 'Loading…'); + try { + initLogsTable(); + if (!state.tables.logs) return; + state.logItemsCache = new Map(); + clearLogSelections(); + const filters = []; + if (from && to) { + filters.push({ key: 'ts', op: 'between', value: [from, to] }); + } + if (level && level !== 'all') { + filters.push({ key: 'level', op: 'eq', value: level }); + } + state.tables.logs.setFilters(filters); + await state.tables.logs.load(1, false); + const total = Number(state.tables.logs.total || 0); + if (hint) hint.textContent = `${t('common.loaded', 'Loaded')} (${total})`; + saveLogsViewDates(from, to); + } catch (e) { + if (hint) hint.textContent = `${t('common.error','Error')}: ${e.message}`; + } +} + +async function loadAuditLogs() { + const hint = UI.qs('#logsHint'); + if (hint) hint.textContent = t('common.loading', 'Loading…'); + try { + initAuditTable(); + if (!state.tables.audit) return; + state.auditItemsCache = new Map(); + clearAuditSelections(); + const from = UI.qs('#logsDateFrom').value || ''; + const to = UI.qs('#logsDateTo').value || ''; + const eventFilter = UI.qs('#logsFilterEvent').value || 'all'; + const filters = []; + if (from && to) { + filters.push({ key: 'created_at', op: 'between', value: [from, to] }); + } + if (eventFilter && eventFilter !== 'all') { + filters.push({ key: 'action', op: 'eq', value: eventFilter }); + } + state.tables.audit.setFilters(filters); + await state.tables.audit.load(1, false); + const total = Number(state.tables.audit.total || 0); + if (hint) hint.textContent = `${t('common.loaded', 'Loaded')} (${total})`; + } catch (e) { + if (hint) hint.textContent = `${t('common.error','Error')}: ${e.message}`; + } +} + +function updateAuditEventOptions(items) { + const sel = UI.qs('#logsFilterEvent'); + if (!sel) return; + const current = sel.value || 'all'; + const saved = loadLogsEventFilter(); + const fromItems = Array.from(new Set(items.map(x => x.action).filter(Boolean))); + const combined = [...AUDIT_EVENTS, ...fromItems.filter(x => !AUDIT_EVENTS.includes(x))]; + const options = ['all', ...combined]; + sel.innerHTML = options.map(v => { + if (v === 'all') { + return ``; + } + return ``; + }).join(''); + const preferred = current !== 'all' ? current : saved; + sel.value = options.includes(preferred) ? preferred : 'all'; +} + +function renderAuditLogs() {} + +function normalizeAuditDate(value) { + if (!value) return ''; + const s = String(value); + if (/^\d{2}\.\d{2}\.\d{4}/.test(s)) { + const parts = s.slice(0, 10).split('.'); + return `${parts[2]}-${parts[1]}-${parts[0]}`; + } + if (/^\d{4}-\d{2}-\d{2}/.test(s)) { + return s.slice(0, 10); + } + const d = new Date(s); + if (Number.isNaN(d.getTime())) return ''; + return d.toISOString().slice(0, 10); +} + +function formatLogContext(value) { + if (!value || value === 'null') { + return ''; + } + try { + return ' ' + JSON.stringify(JSON.parse(value)); + } catch (e) { + return ' ' + value; + } +} + +function logRowId(row) { + if (row?.id !== undefined && row?.id !== null) return String(row.id); + return `${row?.ts || ''}|${row?.level || ''}|${row?.message || ''}`; +} + +function updateLogSelectionCount() { + const el = UI.qs('#logsSelectionCount'); + if (!el) return; + const count = state.logSelected.size; + el.textContent = count ? `${t('settings.logs.selected', 'Selected')}: ${count}` : ''; +} + +function clearLogSelections() { + state.logSelected = new Map(); + updateLogSelectionCount(); +} + +function updateAuditSelectionCount() { + const el = UI.qs('#logsSelectionCount'); + if (!el) return; + const count = state.auditSelected.size; + el.textContent = count ? `${t('settings.logs.selected', 'Selected')}: ${count}` : ''; +} + +function clearAuditSelections() { + state.auditSelected = new Map(); + updateAuditSelectionCount(); +} + +function renderLogRow(body, row) { + const tr = document.createElement('tr'); + const id = logRowId(row); + state.logItemsCache.set(id, row); + + const selTd = document.createElement('td'); + const checkbox = document.createElement('input'); + checkbox.type = 'checkbox'; + checkbox.dataset.logSelect = '1'; + checkbox.dataset.id = id; + checkbox.checked = state.logSelected.has(id); + selTd.appendChild(checkbox); + tr.appendChild(selTd); + + const ctx = (formatLogContext(row.context_json) || '').trim(); + tr.appendChild(cellText(row.ts || '')); + tr.appendChild(cellText(row.level || '')); + tr.appendChild(cellText(row.message || '')); + tr.appendChild(cellText(ctx)); + + body.appendChild(tr); +} + +function renderAuditRow(body, row) { + const tr = document.createElement('tr'); + const id = logRowId(row); + state.auditItemsCache.set(id, row); + + const selTd = document.createElement('td'); + const checkbox = document.createElement('input'); + checkbox.type = 'checkbox'; + checkbox.dataset.auditSelect = '1'; + checkbox.dataset.id = id; + checkbox.checked = state.auditSelected.has(id); + selTd.appendChild(checkbox); + tr.appendChild(selTd); + + tr.appendChild(cellText(row.created_at || '')); + tr.appendChild(cellText(row.actor_email || row.actor_user_id || '')); + tr.appendChild(cellText(row.action || '')); + tr.appendChild(cellText(`${row.target_type || ''} ${row.target_id || ''}`.trim())); + tr.appendChild(cellText(row.meta_json || '')); + + body.appendChild(tr); +} + +function initLogsTable() { + const table = UI.qs('#logsTable'); + if (!table || !window.TableController) return; + const mode = state.ui.table_mode || 'pagination'; + const pageSize = state.ui.table_page_size || 50; + const id = table?.dataset?.tableId || table?.id || ''; + const prefs = window.UserPrefs?.getTable?.(id) || {}; + + state.tables.logs = new TableController({ + table, + mode, + pageSize, + sort: prefs.sort || '', + dir: prefs.dir || 'asc', + onSortChange: (sort, dir) => window.UserPrefs?.setTable?.(id, { sort, dir }), + fetchPage: async ({ page, per_page, sort, dir, filters }) => { + const data = await api('/api/logs', 'POST', { + page, + per_page, + sort, + dir, + filters, + }); + return { + items: data.items || [], + total: data.total || 0, + page: data.page || page, + per_page: data.per_page || per_page, + }; + }, + renderRow: renderLogRow, + }); + state.tables.logs.total = 0; + state.tables.logs.page = 1; + state.tables.logs.updateFooter(); + + const body = table.querySelector('tbody'); + if (body && !body.dataset.bindLogs) { + body.dataset.bindLogs = '1'; + body.addEventListener('change', (e) => { + const input = e.target; + if (!input || input.dataset.logSelect !== '1') return; + const id = input.dataset.id || ''; + if (!id) return; + if (input.checked) { + const row = state.logItemsCache.get(id); + if (row) state.logSelected.set(id, row); + } else { + state.logSelected.delete(id); + } + updateLogSelectionCount(); + }); + } +} + +function initAuditTable() { + const table = UI.qs('#adminAuditTable'); + if (!table || !window.TableController) return; + const mode = state.ui.table_mode || 'pagination'; + const pageSize = state.ui.table_page_size || 50; + const id = table?.dataset?.tableId || table?.id || ''; + const prefs = window.UserPrefs?.getTable?.(id) || {}; + + state.tables.audit = new TableController({ + table, + mode, + pageSize, + sort: prefs.sort || '', + dir: prefs.dir || 'asc', + onSortChange: (sort, dir) => window.UserPrefs?.setTable?.(id, { sort, dir }), + fetchPage: async ({ page, per_page, sort, dir, filters }) => { + const data = await api('/api/admin/audit', 'POST', { + page, + per_page, + sort, + dir, + filters, + }); + const items = data.items || []; + updateAuditEventOptions(items); + return { + items, + total: data.total || 0, + page: data.page || page, + per_page: data.per_page || per_page, + }; + }, + renderRow: renderAuditRow, + }); + state.tables.audit.total = 0; + state.tables.audit.page = 1; + state.tables.audit.updateFooter(); + + const body = table.querySelector('tbody'); + if (body && !body.dataset.bindAudit) { + body.dataset.bindAudit = '1'; + body.addEventListener('change', (e) => { + const input = e.target; + if (!input || input.dataset.auditSelect !== '1') return; + const id = input.dataset.id || ''; + if (!id) return; + if (input.checked) { + const row = state.auditItemsCache.get(id); + if (row) state.auditSelected.set(id, row); + } else { + state.auditSelected.delete(id); + } + updateAuditSelectionCount(); + }); + } +} + +async function copySelectedLogs() { + const type = UI.qs('#logsType')?.value || 'system'; + const items = type === 'audit' + ? Array.from(state.auditSelected.values()) + : Array.from(state.logSelected.values()); + if (!items.length) return; + const lines = items.map((r) => { + if (type === 'audit') { + return `${r.created_at || ''} | ${r.actor_email || r.actor_user_id || ''} | ${r.action || ''} | ${r.target_type || ''} ${r.target_id || ''} | ${r.meta_json || ''}`; + } + const ctx = formatLogContext(r.context_json); + return `${r.ts || ''} [${r.level || ''}] ${r.message || ''}${ctx}`; + }); + const text = lines.join('\n'); + try { + await navigator.clipboard.writeText(text); + } catch (e) { + const ta = document.createElement('textarea'); + ta.value = text; + document.body.appendChild(ta); + ta.select(); + document.execCommand('copy'); + ta.remove(); + } +} + +function selectAllLogsOnPage() { + const type = UI.qs('#logsType')?.value || 'system'; + const body = type === 'audit' ? UI.qs('#adminAudit') : UI.qs('#logsTableBody'); + if (!body) return; + const inputs = Array.from(body.querySelectorAll(type === 'audit' ? 'input[data-audit-select="1"]' : 'input[data-log-select="1"]')); + if (!inputs.length) return; + const allSelected = inputs.every(input => input.checked); + inputs.forEach((input) => { + if (input.checked === !allSelected) return; + input.checked = !allSelected; + input.dispatchEvent(new Event('change', { bubbles: true })); + }); +} + +async function cleanupLogs() { + const hint = UI.qs('#logsSettingsHint'); + if (!confirm(t('settings.logs.delete_all_warn', 'Delete all logs?'))) { + return; + } + const keepDays = 0; + if (hint) hint.textContent = t('common.running', 'Running…'); + try { + const data = await api('/api/logs/cleanup', 'POST', { keep_days: keepDays }); + if (hint) hint.textContent = t('settings.logs.cleaned', 'Cleaned') + ` (${data.deleted || 0})`; + if (state.tables.logs?.tbody) { + state.tables.logs.tbody.innerHTML = ''; + } + if (state.tables.logs) { + state.tables.logs.total = 0; + state.tables.logs.page = 1; + state.tables.logs.updateFooter(); + } + clearLogSelections(); + } catch (e) { + if (hint) hint.textContent = `${t('common.error','Error')}: ${e.message}`; + } +} + +function initLogsTabs() { + const tabs = document.querySelectorAll('.logs-tabs .tab'); + const panes = document.querySelectorAll('.logs-pane'); + tabs.forEach(btn => { + btn.addEventListener('click', () => { + tabs.forEach(x => x.classList.remove('active')); + panes.forEach(x => x.classList.remove('active')); + btn.classList.add('active'); + const target = btn.dataset.logsTab || 'view'; + UI.qs(`#logs-pane-${target}`).classList.add('active'); + }); + }); +} + +function initLogsViewDates() { + const saved = loadLogsViewDates(); + if (saved) { + UI.qs('#logsDateFrom').value = saved.from; + UI.qs('#logsDateTo').value = saved.to; + return; + } + resetLogsDates(); +} + +function resetLogsDates() { + const today = new Date(); + const yyyy = String(today.getFullYear()); + const mm = String(today.getMonth() + 1).padStart(2, '0'); + const dd = String(today.getDate()).padStart(2, '0'); + const d = `${yyyy}-${mm}-${dd}`; + UI.qs('#logsDateFrom').value = d; + UI.qs('#logsDateTo').value = d; + saveLogsViewDates(d, d); + if (state.tables.logs?.tbody) { + state.tables.logs.tbody.innerHTML = ''; + } + if (state.tables.logs) { + state.tables.logs.total = 0; + state.tables.logs.page = 1; + state.tables.logs.updateFooter(); + } + clearLogSelections(); + clearAuditSelections(); + const hint = UI.qs('#logsHint'); + if (hint) hint.textContent = ''; +} + +function updateLogsTypeUI() { + const sel = UI.qs('#logsType'); + const type = sel ? sel.value : 'system'; + const levelControls = UI.qs('#logsControlsLevel'); + const eventControls = UI.qs('#logsControlsEvent'); + const systemActions = UI.qs('#logsControlsSystemActions'); + const output = UI.qs('#logsOutputWrap'); + const auditWrap = UI.qs('#logsAuditWrap'); + const auditBody = UI.qs('#adminAudit'); + const hint = UI.qs('#logsHint'); + + const isAudit = type === 'audit'; + if (levelControls) levelControls.classList.toggle('is-hidden', isAudit); + if (eventControls) eventControls.classList.toggle('is-hidden', !isAudit); + if (systemActions) systemActions.classList.toggle('is-hidden', false); + if (output) output.classList.toggle('is-hidden', isAudit); + if (auditWrap) auditWrap.classList.toggle('is-hidden', !isAudit); + if (isAudit) { + state.auditItems = []; + clearLogSelections(); + if (auditBody) auditBody.innerHTML = ''; + if (hint) hint.textContent = ''; + updateAuditSelectionCount(); + } else { + updateLogSelectionCount(); + } +} + +function saveLogsViewDates(from, to) { + state.logsView.from = from; + state.logsView.to = to; + localStorage.setItem('scmedia_logs_from', from); + localStorage.setItem('scmedia_logs_to', to); +} + +function loadLogsViewDates() { + const from = localStorage.getItem('scmedia_logs_from') || ''; + const to = localStorage.getItem('scmedia_logs_to') || ''; + if (!from || !to) return null; + return { from, to }; +} + +function saveLogsEventFilter(value) { + localStorage.setItem('scmedia_logs_event', value || 'all'); +} + +function loadLogsEventFilter() { + return localStorage.getItem('scmedia_logs_event') || 'all'; +} + +async function detectTools() { + if (state.settingsLoadPromise) { + await state.settingsLoadPromise; + } + const hint = UI.qs('#toolsHint'); + if (hint) hint.textContent = t('common.running', 'Running…'); + try { + const data = await api('/api/tools/detect-binaries', 'GET'); + state.toolsList = buildToolsList(data || {}); + renderToolsList(); + setDirty(true); + if (hint) hint.textContent = t('settings.tools.detected', 'Detected'); + } catch (e) { + if (hint) hint.textContent = `${t('common.error','Error')}: ${e.message}`; + } +} + +function buildToolsList(tools) { + const list = []; + if (tools.mkvmerge_path) list.push({ type: 'mkvmerge', label: 'mkvmerge', path: tools.mkvmerge_path }); + if (tools.mkvpropedit_path) list.push({ type: 'mkvpropedit', label: 'mkvpropedit', path: tools.mkvpropedit_path }); + if (tools.ffmpeg_path) list.push({ type: 'ffmpeg', label: 'ffmpeg', path: tools.ffmpeg_path }); + return list; +} + +function toolPathByType(type) { + const t = state.toolsList.find(x => x.type === type); + return t ? t.path : ''; +} + +function updateToolPath(type, path) { + const existing = state.toolsList.find(x => x.type === type); + if (path === '' && existing) { + state.toolsList = state.toolsList.filter(x => x.type !== type); + } else if (existing) { + existing.path = path; + } else if (path !== '') { + state.toolsList.push({ type, label: type, path }); + } + renderToolsList(); +} + +function renderToolRow(tbody, tl) { + const tr = document.createElement('tr'); + const tdName = document.createElement('td'); + tdName.textContent = t(`settings.tools.${tl.type}`, tl.label); + const tdPath = document.createElement('td'); + tdPath.textContent = tl.path || ''; + const tdActions = document.createElement('td'); + const btnEdit = document.createElement('button'); + btnEdit.className = 'btn'; + btnEdit.textContent = t('common.edit', 'Edit'); + btnEdit.addEventListener('click', () => openToolModal(tl.type)); + const btnRemove = document.createElement('button'); + btnRemove.className = 'btn'; + btnRemove.textContent = t('common.delete', 'Delete'); + btnRemove.addEventListener('click', () => { + updateToolPath(tl.type, ''); + setDirty(true); + }); + tdActions.appendChild(btnEdit); + tdActions.appendChild(btnRemove); + tr.appendChild(tdName); + tr.appendChild(tdPath); + tr.appendChild(tdActions); + tbody.appendChild(tr); +} + +function renderToolsList() { + const table = state.tables.tools; + if (table) { + table.reload(); + return; + } + const tbody = UI.qs('#toolsTable tbody'); + if (!tbody) return; + tbody.innerHTML = ''; + state.toolsList.forEach(tl => renderToolRow(tbody, tl)); +} + +function initToolsUi() { + const btnAdd = UI.qs('#btnAddTool'); + const menu = UI.qs('#toolTypeMenu'); + if (btnAdd && menu) { + btnAdd.addEventListener('click', (e) => { + e.preventDefault(); + btnAdd.parentElement?.classList.toggle('open'); + }); + menu.querySelectorAll('button[data-tool-type]').forEach(btn => { + btn.addEventListener('click', () => { + const type = btn.dataset.toolType || 'mkvmerge'; + btnAdd.parentElement?.classList.remove('open'); + openToolModal(type); + }); + }); + document.addEventListener('click', (e) => { + if (!btnAdd.parentElement?.contains(e.target)) { + btnAdd.parentElement?.classList.remove('open'); + } + }); + } +} + +function initTasksUi() { + const btnAdd = UI.qs('#btnAddTask'); + if (!btnAdd) return; + btnAdd.addEventListener('click', () => openTaskModal(null)); +} + +function openTaskModal(id = null) { + const modal = UI.qs('#ruleModal'); + const body = UI.qs('#ruleModalBody'); + const title = UI.qs('#ruleModalTitle'); + if (!modal || !body || !title) return; + + state.ruleEditId = null; + state.ruleEditType = null; + state.toolEditType = null; + state.taskEditId = (id !== null && id !== undefined) ? id : 'new'; + + const task = id ? state.tasksList.find(t => t.id === id) : null; + const current = task || normalizeTask({}); + + title.textContent = t('settings.tasks.modal_title', 'Task'); + const checked = (list, value) => list.includes(value) ? 'checked' : ''; + + body.innerHTML = ` +
+ + +
+
${t('settings.tasks.field_sources', 'Sources')}
+
+ + + +
+
+
+
${t('settings.tasks.field_actions', 'Actions')}
+
+ + + + + +
+
+
+ `; + const enabledSel = body.querySelector('[data-field="task_enabled"]'); + if (enabledSel) enabledSel.value = current.enabled ? '1' : '0'; + + modal.style.display = 'flex'; +} + +function saveTaskModal(body) { + const name = body.querySelector('[data-field="task_name"]')?.value?.trim() || ''; + const enabled = body.querySelector('[data-field="task_enabled"]')?.value === '1'; + const sources = []; + if (body.querySelector('[data-field="src_library"]')?.checked) sources.push('library'); + if (body.querySelector('[data-field="src_transmission"]')?.checked) sources.push('transmission'); + if (body.querySelector('[data-field="src_staging"]')?.checked) sources.push('staging'); + const actions = []; + if (body.querySelector('[data-field="act_analyze"]')?.checked) actions.push('analyze'); + if (body.querySelector('[data-field="act_identify"]')?.checked) actions.push('identify'); + if (body.querySelector('[data-field="act_normalize"]')?.checked) actions.push('normalize'); + if (body.querySelector('[data-field="act_rename"]')?.checked) actions.push('rename'); + if (body.querySelector('[data-field="act_export"]')?.checked) actions.push('export'); + + const updated = { + id: state.taskEditId || normalizeTask({}).id, + name, + enabled, + sources, + actions, + }; + + const idx = state.tasksList.findIndex(t => t.id === updated.id); + if (idx >= 0) { + state.tasksList[idx] = updated; + } else { + state.tasksList.push(updated); + } + renderTasksList(); + setDirty(true); + closeRuleModal(); +} +function openToolModal(type) { + const modal = UI.qs('#ruleModal'); + const body = UI.qs('#ruleModalBody'); + const title = UI.qs('#ruleModalTitle'); + if (!modal || !body || !title) return; + state.ruleEditId = null; + state.ruleEditType = null; + state.toolEditType = type; + title.textContent = t('settings.tools.modal_title', 'Tool'); + const current = toolPathByType(type); + body.innerHTML = ` +
+ + +
+ `; + modal.style.display = 'flex'; +} + +function normalizePluginConfig() { + if (!state.pluginConfig) state.pluginConfig = { metadata: {}, exports: {}, sources: {} }; + const meta = state.pluginConfig.metadata || {}; + const exportsCfg = state.pluginConfig.exports || {}; + const sourcesCfg = state.pluginConfig.sources || {}; + + if (typeof meta.enabled !== 'boolean') meta.enabled = false; + if (!Array.isArray(meta.languages)) meta.languages = ['de','ru','en']; + if (!Array.isArray(meta.provider_priority)) meta.provider_priority = ['tvdb','omdb']; + if (!meta.providers) meta.providers = {}; + if (!meta.providers.omdb) meta.providers.omdb = { enabled: false, api_key: '', base_url: 'https://www.omdbapi.com/' }; + if (!meta.providers.tvdb) meta.providers.tvdb = { enabled: false, api_key: '', pin: '' }; + + if (!exportsCfg.kodi) exportsCfg.kodi = { enabled: false }; + if (!exportsCfg.jellyfin) exportsCfg.jellyfin = { enabled: false }; + + if (!sourcesCfg.transmission) { + sourcesCfg.transmission = { enabled: false, last_test_ok: false, last_test_at: null, protocol: 'http', host: '', port: 9091, path: '/transmission/rpc', username: '', password: '', display_fields: [] }; + } + if (typeof sourcesCfg.transmission.last_test_ok !== 'boolean') { + sourcesCfg.transmission.last_test_ok = false; + } + if (!Array.isArray(sourcesCfg.transmission.display_fields)) { + sourcesCfg.transmission.display_fields = []; + } + + state.pluginConfig.metadata = meta; + state.pluginConfig.exports = exportsCfg; + state.pluginConfig.sources = sourcesCfg; +} + +function renderPluginRow(tbody, p) { + const tr = document.createElement('tr'); + tr.className = `plugin-row${p.enabled ? '' : ' is-off'}`; + const tdName = document.createElement('td'); + tdName.textContent = p.label; + const tdType = document.createElement('td'); + tdType.textContent = p.kindLabel; + const tdStatus = document.createElement('td'); + tdStatus.textContent = p.enabled === null ? t('rules.status.on', 'On') : (p.enabled ? t('rules.status.on', 'On') : t('rules.status.off', 'Off')); + const tdActions = document.createElement('td'); + + const btnEdit = document.createElement('button'); + btnEdit.className = 'btn'; + btnEdit.textContent = t('common.edit', 'Edit'); + btnEdit.addEventListener('click', () => openPluginModal(p.type)); + tdActions.appendChild(btnEdit); + + if (p.enabled !== null) { + const btnToggle = document.createElement('button'); + btnToggle.className = 'btn'; + btnToggle.textContent = p.enabled ? t('rules.disable', 'Disable') : t('rules.enable', 'Enable'); + btnToggle.addEventListener('click', () => { + setPluginEnabled(p.type, !p.enabled); + renderPluginsList(); + setDirty(true); + }); + tdActions.appendChild(btnToggle); + } + + tr.appendChild(tdName); + tr.appendChild(tdType); + tr.appendChild(tdStatus); + tr.appendChild(tdActions); + tbody.appendChild(tr); +} + +function renderPluginsList() { + const table = state.tables.plugins; + if (table) { + table.reload(); + return; + } + const tbody = UI.qs('#pluginsTable tbody'); + if (!tbody) return; + tbody.innerHTML = ''; + + const items = buildPluginsList(); + items.forEach(p => renderPluginRow(tbody, p)); +} + +function buildPluginsList() { + const meta = state.pluginConfig?.metadata || {}; + const providers = meta.providers || {}; + const exportsCfg = state.pluginConfig?.exports || {}; + const sourcesCfg = state.pluginConfig?.sources || {}; + + return [ + { type: 'meta_settings', label: t('settings.plugins.meta_settings', 'Metadata settings'), kindLabel: t('settings.plugins.kind.meta', 'Metadata'), enabled: !!meta.enabled }, + { type: 'omdb', label: t('settings.plugins.omdb_label', 'IMDb (OMDb)'), kindLabel: t('settings.plugins.kind.meta', 'Metadata'), enabled: !!providers.omdb?.enabled && !!meta.enabled }, + { type: 'tvdb', label: t('settings.plugins.tvdb_label', 'TVDB'), kindLabel: t('settings.plugins.kind.meta', 'Metadata'), enabled: !!providers.tvdb?.enabled && !!meta.enabled }, + { type: 'kodi', label: t('settings.plugins.kodi_label', 'Kodi'), kindLabel: t('settings.plugins.kind.export', 'Export'), enabled: !!exportsCfg.kodi?.enabled }, + { type: 'jellyfin', label: t('settings.plugins.jellyfin_label', 'Jellyfin'), kindLabel: t('settings.plugins.kind.export', 'Export'), enabled: !!exportsCfg.jellyfin?.enabled }, + { type: 'transmission', label: t('settings.plugins.transmission_label', 'Transmission'), kindLabel: t('settings.plugins.kind.source', 'Source'), enabled: !!sourcesCfg.transmission?.enabled }, + ]; +} + +function ensureTransmissionRule() { + const existing = state.rulesList.find(r => r.type === 'source_filter' && r.config?.source === 'transmission'); + if (existing) { + if (!existing.enabled) existing.enabled = true; + return; + } + const rule = normalizeRule({ + type: 'source_filter', + name: 'Transmission (all)', + enabled: true, + config: { + source: 'transmission', + status: '', + label: '', + min_size: 0, + name_regex: '', + path_regex: '', + }, + }); + state.rulesList.push(rule); +} + +function setPluginEnabled(type, enabled) { + normalizePluginConfig(); + if ((type === 'omdb' || type === 'tvdb') && !state.pluginConfig.metadata.enabled && enabled) { + const hint = UI.qs('#pluginsHint'); + if (hint) hint.textContent = t('settings.plugins.requires_meta', 'Enable metadata settings first'); + return; + } + if (type === 'transmission' && enabled && !state.pluginConfig.sources.transmission.last_test_ok) { + const hint = UI.qs('#pluginsHint'); + if (hint) hint.textContent = t('settings.plugins.requires_test', 'Test connection first'); + return; + } + if (type === 'omdb') state.pluginConfig.metadata.providers.omdb.enabled = enabled; + if (type === 'tvdb') state.pluginConfig.metadata.providers.tvdb.enabled = enabled; + if (type === 'meta_settings') state.pluginConfig.metadata.enabled = enabled; + if (type === 'kodi') state.pluginConfig.exports.kodi.enabled = enabled; + if (type === 'jellyfin') state.pluginConfig.exports.jellyfin.enabled = enabled; + if (type === 'transmission') { + state.pluginConfig.sources.transmission.enabled = enabled; + if (enabled) { + ensureTransmissionRule(); + renderRulesList(); + setDirty(true); + } + } +} + +function initPluginsUi() { + const btnAdd = UI.qs('#btnAddPlugin'); + const fileInput = UI.qs('#pluginFileInput'); + if (btnAdd && fileInput) { + btnAdd.addEventListener('click', (e) => { + e.preventDefault(); + fileInput.click(); + }); + fileInput.addEventListener('change', () => { + // Placeholder only: no install yet + fileInput.value = ''; + const hint = UI.qs('#pluginsHint'); + if (hint) hint.textContent = t('settings.plugins.install_placeholder', 'Installer coming soon'); + }); + } +} + +function openPluginModal(type) { + const modal = UI.qs('#ruleModal'); + const body = UI.qs('#ruleModalBody'); + const title = UI.qs('#ruleModalTitle'); + if (!modal || !body || !title) return; + state.ruleEditId = null; + state.ruleEditType = null; + state.toolEditType = null; + state.rootEditId = null; + + state.pluginEditType = type; + title.textContent = t('settings.plugins.modal_title', 'Plugin'); + body.innerHTML = renderPluginForm(type); + applyPluginFormValues(body, type); + modal.style.display = 'flex'; +} + +function renderPluginForm(type) { + const meta = state.pluginConfig?.metadata || {}; + const providers = meta.providers || {}; + const exportsCfg = state.pluginConfig?.exports || {}; + const sourcesCfg = state.pluginConfig?.sources || {}; + const tr = sourcesCfg.transmission || {}; + + if (type === 'meta_settings') { + return ` +
+ + + +
+ `; + } + + if (type === 'omdb') { + return ` +
+ + +
+ `; + } + + if (type === 'tvdb') { + return ` +
+ + + +
+ `; + } + + if (type === 'kodi' || type === 'jellyfin') { + const enabled = (type === 'kodi') ? exportsCfg.kodi?.enabled : exportsCfg.jellyfin?.enabled; + return ` +
+ +
${type === 'kodi' ? t('settings.plugins.kodi_hint','Writes movie.nfo / tvshow.nfo near files') : t('settings.plugins.jellyfin_hint','Writes movie.nfo / tvshow.nfo near files')}
+
+ `; + } + + if (type === 'transmission') { + return ` +
+ + + + + + + + +
+
+ +
+
+ `; + } + + return ''; +} + +function applyPluginFormValues(body, type) { + normalizePluginConfig(); + const meta = state.pluginConfig.metadata; + const providers = meta.providers || {}; + const exportsCfg = state.pluginConfig.exports; + const sourcesCfg = state.pluginConfig.sources; + + const setVal = (field, value) => { + const el = body.querySelector(`[data-field="${field}"]`); + if (el) el.value = value ?? ''; + }; + + if (type === 'meta_settings') { + setVal('enabled', meta.enabled ? '1' : '0'); + setVal('meta_languages', (meta.languages || []).join(',')); + setVal('meta_priority', (meta.provider_priority || []).join(',')); + } else if (type === 'omdb') { + setVal('enabled', providers.omdb?.enabled ? '1' : '0'); + setVal('api_key', providers.omdb?.api_key || ''); + } else if (type === 'tvdb') { + setVal('enabled', providers.tvdb?.enabled ? '1' : '0'); + setVal('api_key', providers.tvdb?.api_key || ''); + setVal('pin', providers.tvdb?.pin || ''); + } else if (type === 'kodi') { + setVal('enabled', exportsCfg.kodi?.enabled ? '1' : '0'); + } else if (type === 'jellyfin') { + setVal('enabled', exportsCfg.jellyfin?.enabled ? '1' : '0'); + } else if (type === 'transmission') { + const tr = sourcesCfg.transmission || {}; + setVal('enabled', tr.enabled ? '1' : '0'); + setVal('protocol', tr.protocol || 'http'); + setVal('host', tr.host || ''); + setVal('port', String(tr.port ?? 9091)); + setVal('path', tr.path || '/transmission/rpc'); + setVal('username', tr.username || ''); + setVal('password', tr.password || ''); + setVal('display_fields', (tr.display_fields || []).join(',')); + const btn = body.querySelector('#btnPluginTest'); + if (btn) { + btn.addEventListener('click', async () => { + const hint = body.querySelector('#pluginTestHint'); + if (hint) hint.textContent = t('common.testing', 'Testing…'); + clearFieldErrors(body, ['host','port','path']); + const payload = { transmission: readTransmissionFields(body) }; + const missing = []; + if (!payload.transmission.host) missing.push('host'); + if (!payload.transmission.port) missing.push('port'); + if (!payload.transmission.path) missing.push('path'); + if (missing.length > 0) { + markFieldErrors(body, missing); + if (hint) hint.textContent = t('settings.plugins.transmission_missing', 'Fill required fields'); + return; + } + try { + await api('/api/sources/test', 'POST', payload); + state.pluginConfig.sources.transmission.last_test_ok = true; + state.pluginConfig.sources.transmission.last_test_at = new Date().toISOString(); + renderPluginsList(); + setDirty(true); + if (hint) hint.textContent = t('settings.plugins.transmission_ok', 'OK'); + } catch (e) { + state.pluginConfig.sources.transmission.last_test_ok = false; + state.pluginConfig.sources.transmission.last_test_at = new Date().toISOString(); + renderPluginsList(); + setDirty(true); + const msg = normalizeTransmissionErrorMessage(e.message); + if (hint) hint.textContent = `${t('common.error','Error')}: ${msg}`; + } + }); + } + } +} + +function normalizeTransmissionErrorMessage(message) { + if (!message) return t('settings.plugins.transmission_rpc_failed', 'RPC failed. Check address or auth.'); + if (message === 'unauthorized') { + return t('settings.plugins.transmission_unauthorized', 'Unauthorized. Check RPC username/password.'); + } + if (message === 'forbidden') { + return t('settings.plugins.transmission_forbidden', 'Access denied. Check whitelist or credentials.'); + } + if (message === 'rpc failed') { + return t('settings.plugins.transmission_rpc_failed', 'RPC failed. Check address or auth.'); + } + return message; +} + +function isTaskModalOpen() { + return state.taskEditId !== null; +} + +function savePluginModal(body) { + normalizePluginConfig(); + const type = state.pluginEditType; + if (!type) return; + const meta = state.pluginConfig.metadata; + const providers = meta.providers || {}; + const exportsCfg = state.pluginConfig.exports; + const sourcesCfg = state.pluginConfig.sources; + + const getVal = (field) => body.querySelector(`[data-field="${field}"]`)?.value ?? ''; + + if (type === 'meta_settings') { + meta.enabled = getVal('enabled') === '1'; + meta.languages = commaToList(getVal('meta_languages')); + meta.provider_priority = commaToList(getVal('meta_priority')); + } else if (type === 'omdb') { + providers.omdb = providers.omdb || {}; + providers.omdb.enabled = getVal('enabled') === '1'; + providers.omdb.api_key = getVal('api_key').trim(); + providers.omdb.base_url = providers.omdb.base_url || 'https://www.omdbapi.com/'; + } else if (type === 'tvdb') { + providers.tvdb = providers.tvdb || {}; + providers.tvdb.enabled = getVal('enabled') === '1'; + providers.tvdb.api_key = getVal('api_key').trim(); + providers.tvdb.pin = getVal('pin').trim(); + } else if (type === 'kodi') { + exportsCfg.kodi.enabled = getVal('enabled') === '1'; + } else if (type === 'jellyfin') { + exportsCfg.jellyfin.enabled = getVal('enabled') === '1'; + } else if (type === 'transmission') { + sourcesCfg.transmission = readTransmissionFields(body); + if (sourcesCfg.transmission.enabled && !sourcesCfg.transmission.last_test_ok) { + sourcesCfg.transmission.enabled = false; + const hint = UI.qs('#pluginsHint'); + if (hint) hint.textContent = t('settings.plugins.requires_test', 'Test connection first'); + } + } + + state.pluginConfig.metadata = meta; + state.pluginConfig.exports = exportsCfg; + state.pluginConfig.sources = sourcesCfg; + renderPluginsList(); +} + +function readTransmissionFields(body) { + return { + enabled: body.querySelector('[data-field="enabled"]')?.value === '1', + last_test_ok: state.pluginConfig?.sources?.transmission?.last_test_ok ?? false, + last_test_at: state.pluginConfig?.sources?.transmission?.last_test_at ?? null, + protocol: body.querySelector('[data-field="protocol"]')?.value || 'http', + host: body.querySelector('[data-field="host"]')?.value?.trim() || '', + port: Number(body.querySelector('[data-field="port"]')?.value || 9091), + path: body.querySelector('[data-field="path"]')?.value?.trim() || '/transmission/rpc', + username: body.querySelector('[data-field="username"]')?.value?.trim() || '', + password: body.querySelector('[data-field="password"]')?.value ?? '', + display_fields: commaToList(body.querySelector('[data-field="display_fields"]')?.value ?? ''), + }; +} + +function markFieldErrors(body, fields) { + fields.forEach(f => { + const el = body.querySelector(`[data-field="${f}"]`); + if (el) el.classList.add('input-error'); + }); +} + +function clearFieldErrors(body, fields) { + fields.forEach(f => { + const el = body.querySelector(`[data-field="${f}"]`); + if (el) el.classList.remove('input-error'); + }); +} + +function buildRootsList(paths) { + const roots = Array.isArray(paths.roots) ? paths.roots : []; + if (roots.length > 0) { + return roots.map(r => normalizeRoot(r)); + } + const out = []; + if (paths.movies_root) out.push(normalizeRoot({ type: 'movie', path: paths.movies_root, enabled: true })); + if (paths.series_root) out.push(normalizeRoot({ type: 'series', path: paths.series_root, enabled: true })); + if (paths.staging_root) out.push(normalizeRoot({ type: 'staging', path: paths.staging_root, enabled: true })); + return out; +} + +function normalizeRoot(r) { + return { + id: r?.id || `root_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`, + type: r?.type || 'movie', + path: r?.path || '', + enabled: r?.enabled !== false, + }; +} + +function renderRootRow(tbody, r) { + const tr = document.createElement('tr'); + const tdType = document.createElement('td'); + tdType.textContent = rootTypeLabel(r.type); + const tdPath = document.createElement('td'); + tdPath.textContent = r.path || ''; + const tdStatus = document.createElement('td'); + tdStatus.textContent = r.enabled ? t('rules.status.on', 'On') : t('rules.status.off', 'Off'); + const tdActions = document.createElement('td'); + const btnEdit = document.createElement('button'); + btnEdit.className = 'btn'; + btnEdit.textContent = t('common.edit', 'Edit'); + btnEdit.addEventListener('click', () => openRootModal(r.id)); + const btnTest = document.createElement('button'); + btnTest.className = 'btn'; + btnTest.textContent = t('common.test', 'Test'); + btnTest.addEventListener('click', () => testRootPath(r)); + const btnDel = document.createElement('button'); + btnDel.className = 'btn'; + btnDel.textContent = t('common.delete', 'Delete'); + btnDel.addEventListener('click', () => { + if (!confirm(t('settings.library_layout.confirm_delete', 'Delete root?'))) return; + state.rootsList = state.rootsList.filter(x => x.id !== r.id); + renderRootsList(); + setDirty(true); + }); + tdActions.appendChild(btnEdit); + tdActions.appendChild(btnTest); + tdActions.appendChild(btnDel); + + tr.appendChild(tdType); + tr.appendChild(tdPath); + tr.appendChild(tdStatus); + tr.appendChild(tdActions); + tbody.appendChild(tr); +} + +function renderRootsList() { + const table = state.tables.roots; + if (table) { + table.reload(); + return; + } + const tbody = UI.qs('#rootsTable tbody'); + if (!tbody) return; + tbody.innerHTML = ''; + state.rootsList.forEach(r => renderRootRow(tbody, r)); +} + +function rootTypeLabel(type) { + if (type === 'movie') return t('root.type.movie', 'Movie'); + if (type === 'series') return t('root.type.series', 'Series'); + if (type === 'staging') return t('root.type.staging', 'Staging'); + return type || ''; +} + +function openRootModal(id = null) { + const modal = UI.qs('#ruleModal'); + const body = UI.qs('#ruleModalBody'); + const title = UI.qs('#ruleModalTitle'); + if (!modal || !body || !title) return; + state.ruleEditId = null; + state.ruleEditType = null; + state.toolEditType = null; + + const root = id ? state.rootsList.find(r => r.id === id) : null; + const data = root ? { ...root } : normalizeRoot({}); + state.rootEditId = data.id; + + title.textContent = t('settings.library_layout.modal_title', 'Root'); + body.innerHTML = ` +
+ + + +
+ `; + const typeSel = body.querySelector('[data-field="root_type"]'); + const enabledSel = body.querySelector('[data-field="root_enabled"]'); + if (typeSel) typeSel.value = data.type; + if (enabledSel) enabledSel.value = data.enabled ? '1' : '0'; + modal.style.display = 'flex'; +} + +function buildPathsPayload() { + const roots = state.rootsList || []; + const movie = roots.find(r => r.type === 'movie' && r.enabled); + const series = roots.find(r => r.type === 'series' && r.enabled); + const staging = roots.find(r => r.type === 'staging' && r.enabled); + return { + movies_root: movie?.path || '', + series_root: series?.path || '', + staging_root: staging?.path || '', + roots, + }; +} + +async function testRootPath(root) { + const hint = UI.qs('#rootsHint'); + if (hint) hint.textContent = t('common.testing', 'Testing…'); + try { + const data = await api('/api/tools/test-path', 'POST', { path: root.path, checks: ['exists','read','write','rename'] }); + const r = data.results || {}; + const txt = `${t('common.exists','exists')}=${r.exists} ${t('common.read','read')}=${r.read} ${t('common.write','write')}=${r.write} ${t('common.rename','rename')}=${r.rename} ${(data.notes || []).join('; ')}`; + if (hint) hint.textContent = txt; + } catch (e) { + if (hint) hint.textContent = `${t('common.error','Error')}: ${e.message}`; + } +} diff --git a/public/assets/js/sse.js b/public/assets/js/sse.js new file mode 100644 index 0000000..b9dddaa --- /dev/null +++ b/public/assets/js/sse.js @@ -0,0 +1,209 @@ +// public/assets/sse.js +/* English comments: shared SSE client with lease + cache */ + +(function () { + const SSE_LEASE_KEY = 'scmedia_sse_lease'; + const SSE_LAST = 'scmedia_sse_last'; + const SSE_LAST_TYPE = 'scmedia_sse_last_type'; + const SSE_CONNECTED = 'scmedia_sse_connected'; + const SSE_RECONNECTS = 'scmedia_sse_reconnects'; + const SSE_KEY_EXP = 'scmedia_sse_key_exp'; + + let client = null; + let retryMs = 5000; + let tabId = ''; + let leaseTimer = null; + let opening = false; + const listeners = {}; + + function emit(type, payload) { + const list = listeners[type] || []; + list.forEach((cb) => { + try { + cb(payload); + } catch (e) { + // ignore + } + }); + } + + function on(type, cb) { + if (!type || typeof cb !== 'function') return; + listeners[type] = listeners[type] || []; + listeners[type].push(cb); + } + + function loadKeyExp() { + return Number(sessionStorage.getItem(SSE_KEY_EXP) || 0); + } + + function cacheKeyExp(ttlSeconds) { + const exp = Date.now() + Math.max(10, ttlSeconds) * 1000; + sessionStorage.setItem(SSE_KEY_EXP, String(exp)); + return exp; + } + + function isKeyFresh() { + const exp = loadKeyExp(); + return exp > Date.now() + 1000; + } + + function setConnected(ok) { + localStorage.setItem(SSE_CONNECTED, ok ? '1' : '0'); + if (ok) { + localStorage.setItem(SSE_LAST, String(Date.now())); + } + } + + function noteEvent(type) { + setConnected(true); + localStorage.setItem(SSE_LAST, String(Date.now())); + if (type) { + localStorage.setItem(SSE_LAST_TYPE, String(type)); + } + refreshLease(); + } + + function claimLease() { + if (!tabId) { + const existing = sessionStorage.getItem('scmedia_sse_tab_id'); + tabId = existing || Math.random().toString(36).slice(2); + sessionStorage.setItem('scmedia_sse_tab_id', tabId); + } + const now = Date.now(); + const ttlMs = 15000; + const raw = localStorage.getItem(SSE_LEASE_KEY) || ''; + let lease = null; + try { + lease = raw ? JSON.parse(raw) : null; + } catch (e) { + lease = null; + } + if (lease && lease.ts && (now - lease.ts) < ttlMs && lease.id !== tabId) { + return false; + } + localStorage.setItem(SSE_LEASE_KEY, JSON.stringify({ ts: now, id: tabId })); + return true; + } + + function refreshLease() { + localStorage.setItem(SSE_LEASE_KEY, JSON.stringify({ ts: Date.now(), id: tabId })); + } + + function releaseLease() { + const raw = localStorage.getItem(SSE_LEASE_KEY) || ''; + try { + const lease = raw ? JSON.parse(raw) : null; + if (lease && lease.id && lease.id !== tabId) return; + } catch (e) { + // ignore + } + localStorage.removeItem(SSE_LEASE_KEY); + } + + async function open() { + if (opening) return; + opening = true; + if (!claimLease()) { + opening = false; + return; + } + if (window.Auth?.isAccessExpired?.() && window.Auth?.refreshTokens) { + await window.Auth.refreshTokens(); + } + const token = window.Auth?.getAccessToken?.(); + if (!token) { + opening = false; + return; + } + + if (!isKeyFresh()) { + const res = await fetch('/api/auth/sse-key', { + method: 'POST', + headers: { Authorization: `Bearer ${token}` }, + }); + const data = await res.json().catch(() => null); + const key = data?.data?.key || ''; + const ttl = Number(data?.data?.expires_in || 60); + if (!data?.ok || !key) { + releaseLease(); + opening = false; + return; + } + cacheKeyExp(ttl); + await new Promise((r) => setTimeout(r, 50)); + } + + const es = new EventSource('/api/events', { withCredentials: true }); + client = es; + es.addEventListener('open', () => { + retryMs = 5000; + setConnected(true); + refreshLease(); + if (leaseTimer) clearInterval(leaseTimer); + leaseTimer = setInterval(refreshLease, 5000); + emit('open'); + }); + const handle = (type) => { + noteEvent(type); + emit(type); + }; + es.addEventListener('message', () => handle('message')); + es.addEventListener('tick', () => handle('tick')); + es.addEventListener('sources', (e) => { + noteEvent('sources'); + let payload = null; + try { payload = JSON.parse(e.data); } catch (e2) { payload = null; } + emit('sources', payload); + }); + es.addEventListener('jobs', (e) => { + noteEvent('jobs'); + let payload = null; + try { payload = JSON.parse(e.data); } catch (e2) { payload = null; } + emit('jobs', payload); + }); + es.addEventListener('error', () => { + if (client) { + client.close(); + client = null; + } + if (leaseTimer) { + clearInterval(leaseTimer); + leaseTimer = null; + } + const prev = Number(localStorage.getItem(SSE_RECONNECTS) || 0); + localStorage.setItem(SSE_RECONNECTS, String(prev + 1)); + releaseLease(); + opening = false; + const delay = retryMs; + retryMs = Math.min(retryMs * 2, 60000); + setTimeout(open, delay); + }); + opening = false; + } + + function start() { + if (!window.EventSource) return; + if (client) return; + open().catch(() => {}); + } + + function stop() { + if (client) { + client.close(); + client = null; + } + if (leaseTimer) { + clearInterval(leaseTimer); + leaseTimer = null; + } + localStorage.removeItem(SSE_CONNECTED); + localStorage.removeItem(SSE_LAST); + localStorage.removeItem(SSE_LAST_TYPE); + localStorage.removeItem(SSE_LEASE_KEY); + sessionStorage.removeItem(SSE_KEY_EXP); + document.cookie = 'sse_key=; path=/; max-age=0'; + } + + window.Sse = { start, stop, on }; +})(); diff --git a/public/assets/js/table.js b/public/assets/js/table.js new file mode 100644 index 0000000..aa9b251 --- /dev/null +++ b/public/assets/js/table.js @@ -0,0 +1,835 @@ +// public/assets/table.js +// Shared table controller for pagination/infinite mode + +class TableController { + constructor(opts) { + this.table = opts.table; + this.tbody = this.table.querySelector('tbody'); + this.wrap = this.table.closest('.table-wrap'); + this.footer = this.wrap?.querySelector('[data-table-footer]'); + this.metaEl = this.wrap?.querySelector('[data-table-meta]'); + this.pageEl = this.wrap?.querySelector('[data-table-page]'); + this.prevBtn = this.wrap?.querySelector('[data-table-prev]'); + this.nextBtn = this.wrap?.querySelector('[data-table-next]'); + this.renderRow = opts.renderRow; + this.fetchPage = opts.fetchPage; + this.mode = opts.mode || 'pagination'; + this.pageSize = Number(opts.pageSize || 50); + this.page = 1; + this.total = 0; + this.sort = opts.sort || ''; + this.dir = opts.dir || 'asc'; + this.onSortChange = opts.onSortChange || null; + this.params = opts.params || {}; + this.filters = Array.isArray(opts.filters) ? opts.filters : []; + this.loading = false; + + this.attachSortHandlers(); + this.attachPagerHandlers(); + this.initFilters(); + this.initViewEditor(); + this.defaultColumns = this.buildColumnsFromHeaders([]); + const tableId = this.getTableId(); + if (tableId && window.UserPrefs?.getTable) { + const prefs = window.UserPrefs.getTable(tableId); + if (prefs && prefs.columns) { + this.applyColumnPrefs(prefs); + } + } + } + + setMode(mode) { + this.mode = mode === 'infinite' ? 'infinite' : 'pagination'; + } + + setPageSize(size) { + this.pageSize = Math.max(1, Number(size || 50)); + } + + setParams(params) { + this.params = params || {}; + } + + setFilters(filters) { + this.filters = Array.isArray(filters) ? filters : []; + this.syncFilterInputs(); + } + + setSort(sort, dir) { + this.sort = sort || ''; + this.dir = dir === 'desc' ? 'desc' : 'asc'; + } + + attachSortHandlers() { + const headers = this.table.querySelectorAll('thead th[data-sort]'); + headers.forEach(th => { + th.classList.add('sortable'); + th.addEventListener('click', () => { + const key = th.dataset.sort || ''; + if (!key) return; + if (this.sort === key) { + this.dir = (this.dir === 'asc') ? 'desc' : 'asc'; + } else { + this.sort = key; + this.dir = 'asc'; + } + if (typeof this.onSortChange === 'function') { + this.onSortChange(this.sort, this.dir); + } + this.load(1, false); + }); + }); + } + + attachPagerHandlers() { + if (this.prevBtn) { + this.prevBtn.addEventListener('click', () => { + if (this.page > 1) this.load(this.page - 1, false); + }); + } + if (this.nextBtn) { + this.nextBtn.addEventListener('click', () => { + const totalPages = this.totalPages(); + if (this.page < totalPages) this.load(this.page + 1, false); + }); + } + + const handleScroll = () => { + if (this.mode !== 'infinite') return; + if (this.loading) return; + if (this.page >= this.totalPages()) return; + if (this.isWrapScrollable()) { + const nearBottom = this.wrap.scrollTop + this.wrap.clientHeight >= this.wrap.scrollHeight - 80; + if (nearBottom) this.load(this.page + 1, true); + } else { + const doc = document.documentElement; + const nearBottom = window.scrollY + window.innerHeight >= doc.scrollHeight - 120; + if (nearBottom) this.load(this.page + 1, true); + } + }; + + if (this.wrap) { + this.wrap.addEventListener('scroll', handleScroll); + } + window.addEventListener('scroll', handleScroll); + } + + initFilters() { + const headRow = this.table?.querySelector('thead tr'); + if (!headRow) return; + const filtersEnabled = this.table?.dataset?.filtersEnabled; + if (filtersEnabled === '0') { + const tools = this.wrap?.querySelector('[data-table-tools]'); + if (tools) tools.classList.add('is-hidden'); + return; + } + const ths = Array.from(headRow.querySelectorAll('th')); + const hasFilters = ths.some(th => th.dataset.filter); + const tools = this.wrap?.querySelector('[data-table-tools]'); + const toggleBtn = this.wrap?.querySelector('[data-table-filters-toggle]'); + const summaryEl = this.wrap?.querySelector('[data-table-filters-summary]'); + + if (!hasFilters) { + if (tools) tools.classList.add('is-hidden'); + return; + } + if (tools) tools.classList.remove('is-hidden'); + + const ensureIndicator = (th) => { + if (!th.classList.contains('has-filter')) { + th.classList.add('has-filter'); + } + if (!th.querySelector('.filter-indicator')) { + const dot = document.createElement('span'); + dot.className = 'filter-indicator'; + dot.setAttribute('aria-hidden', 'true'); + th.appendChild(dot); + } + }; + + ths.forEach((th) => { + if (th.dataset.filter) { + ensureIndicator(th); + } + }); + + let row = this.table.querySelector('thead tr[data-filter-row]'); + if (!row) { + row = document.createElement('tr'); + row.className = 'table-filter-row'; + row.dataset.filterRow = '1'; + headRow.insertAdjacentElement('afterend', row); + ths.forEach((th) => { + const td = document.createElement('td'); + const key = th.dataset.key || ''; + if (key) td.dataset.key = key; + row.appendChild(td); + }); + } + this.filterRow = row; + this.filterThs = ths; + this.filterSummaryEl = summaryEl; + + const parseFilter = (value) => { + if (!value) return null; + try { + const obj = JSON.parse(value); + if (obj && typeof obj === 'object') return obj; + } catch (e) { + return null; + } + return null; + }; + + const defaultOp = (meta, type) => { + if (Array.isArray(meta?.ops) && meta.ops.length > 0) return meta.ops[0]; + if (type === 'text') return 'like'; + return 'eq'; + }; + + const buildInput = (meta, key) => { + const type = meta?.type || 'text'; + const control = meta?.control || ''; + const isSelect = type === 'select' || control === 'select' || Array.isArray(meta?.options); + const ops = Array.isArray(meta?.ops) ? meta.ops : []; + const op = defaultOp(meta, type); + if (isSelect) { + const dict = window.I18N || {}; + const t = (i18nKey, fallback) => { + if (i18nKey && Object.prototype.hasOwnProperty.call(dict, i18nKey)) { + const v = dict[i18nKey]; + if (typeof v === 'string' && v.length) return v; + } + return fallback; + }; + const select = document.createElement('select'); + select.dataset.filterKey = key; + select.dataset.filterOp = op; + const optAny = document.createElement('option'); + optAny.value = ''; + optAny.textContent = t('filters.all', 'All'); + select.appendChild(optAny); + const options = Array.isArray(meta?.options) ? meta.options : []; + options.forEach((value) => { + const opt = document.createElement('option'); + if (value && typeof value === 'object') { + opt.value = String(value.value ?? ''); + opt.textContent = t(value.i18n || '', String(value.label ?? value.value ?? '')); + } else { + opt.value = String(value); + opt.textContent = String(value); + } + select.appendChild(opt); + }); + return select; + } + if (type === 'boolean') { + const select = document.createElement('select'); + select.dataset.filterKey = key; + select.dataset.filterOp = op; + const optAny = document.createElement('option'); + optAny.value = ''; + optAny.textContent = 'All'; + select.appendChild(optAny); + const optTrue = document.createElement('option'); + optTrue.value = 'true'; + optTrue.textContent = 'Yes'; + select.appendChild(optTrue); + const optFalse = document.createElement('option'); + optFalse.value = 'false'; + optFalse.textContent = 'No'; + select.appendChild(optFalse); + return select; + } + if ((type === 'number' || type === 'date') && ops.includes('between')) { + const wrap = document.createElement('div'); + wrap.className = 'table-filter-range'; + const inputFrom = document.createElement('input'); + const inputTo = document.createElement('input'); + inputFrom.type = type === 'date' ? 'date' : 'number'; + inputTo.type = type === 'date' ? 'date' : 'number'; + inputFrom.dataset.filterKey = key; + inputFrom.dataset.filterOp = 'between'; + inputFrom.dataset.filterRange = 'from'; + inputTo.dataset.filterKey = key; + inputTo.dataset.filterOp = 'between'; + inputTo.dataset.filterRange = 'to'; + wrap.appendChild(inputFrom); + wrap.appendChild(inputTo); + return wrap; + } + const input = document.createElement('input'); + input.type = type === 'number' ? 'number' : (type === 'date' ? 'date' : 'text'); + input.dataset.filterKey = key; + input.dataset.filterOp = op; + return input; + }; + + const cells = Array.from(row.children); + ths.forEach((th, idx) => { + const meta = parseFilter(th.dataset.filter || ''); + const key = th.dataset.key || ''; + const cell = cells[idx]; + if (!cell) return; + cell.innerHTML = ''; + if (!meta || key === '') return; + const control = buildInput(meta, key); + cell.appendChild(control); + }); + + let debounceId = null; + const readFilters = () => { + const filters = []; + const inputs = row.querySelectorAll('[data-filter-key]'); + const rangeMap = new Map(); + inputs.forEach((el) => { + const key = el.dataset.filterKey || ''; + const op = el.dataset.filterOp || 'eq'; + if (!key) return; + if (el.dataset.filterRange) { + const entry = rangeMap.get(key) || { from: '', to: '', op }; + if (el.dataset.filterRange === 'from') entry.from = el.value || ''; + if (el.dataset.filterRange === 'to') entry.to = el.value || ''; + rangeMap.set(key, entry); + return; + } + const value = el.value; + if (value === '' || value === null || value === undefined) return; + filters.push({ key, op, value }); + }); + rangeMap.forEach((entry, key) => { + if (entry.from && entry.to) { + filters.push({ key, op: 'between', value: [entry.from, entry.to] }); + } + }); + return filters; + }; + + const updateIndicators = (filters) => { + const active = new Set(filters.map(f => f.key)); + ths.forEach((th) => { + if (!th.dataset.filter) return; + const key = th.dataset.key || ''; + th.classList.toggle('filter-active', key !== '' && active.has(key)); + }); + if (summaryEl) { + summaryEl.textContent = filters.length ? `Filters: ${filters.length}` : ''; + } + }; + + const applyFilters = () => { + const filters = readFilters(); + this.setFilters(filters); + updateIndicators(filters); + this.load(1, false); + }; + + const handleInput = (e) => { + const target = e.target; + if (!target || !target.dataset.filterKey) return; + if (target.tagName === 'INPUT' && target.type === 'text') { + if (debounceId) clearTimeout(debounceId); + debounceId = setTimeout(applyFilters, 350); + return; + } + applyFilters(); + }; + + row.addEventListener('input', handleInput); + row.addEventListener('change', handleInput); + + if (toggleBtn && !toggleBtn.dataset.filtersInit) { + toggleBtn.dataset.filtersInit = '1'; + toggleBtn.addEventListener('click', () => { + if (!this.wrap) return; + this.wrap.classList.toggle('filters-open'); + }); + } + updateIndicators(this.filters); + } + + initViewEditor() { + const dialog = document.getElementById('dlg-table-view'); + const tools = this.wrap?.querySelector('[data-table-tools]'); + const viewBtn = this.wrap?.querySelector('[data-table-view-toggle]'); + if (!dialog || !viewBtn) return; + const hasConfig = this.table?.dataset?.viewConfig === '1'; + if (!hasConfig) { + if (viewBtn) viewBtn.classList.add('is-hidden'); + if (tools && !this.table?.querySelector('thead th[data-filter]')) { + tools.classList.add('is-hidden'); + } + return; + } + viewBtn.classList.remove('is-hidden'); + if (viewBtn.dataset.viewInit === '1') return; + viewBtn.dataset.viewInit = '1'; + + viewBtn.addEventListener('click', () => { + this.openViewEditor(dialog); + }); + } + + openViewEditor(dialog) { + if (!dialog) return; + const body = dialog.querySelector('[data-table-view-body]'); + if (!body) return; + const tableId = this.getTableId(); + const prefs = window.UserPrefs?.getTable?.(tableId) || {}; + const columns = this.buildColumnsFromHeaders(prefs.columns || []); + + body.innerHTML = ''; + columns.forEach((col, idx) => { + const tr = document.createElement('tr'); + tr.className = 'table-view-row'; + tr.dataset.key = col.key; + + const tdOn = document.createElement('td'); + const chk = document.createElement('input'); + chk.type = 'checkbox'; + chk.checked = col.visible !== false; + tdOn.appendChild(chk); + + const tdLabel = document.createElement('td'); + tdLabel.textContent = col.label; + + const tdWidth = document.createElement('td'); + const sel = document.createElement('select'); + const optAuto = document.createElement('option'); + optAuto.value = 'auto'; + optAuto.textContent = 'Auto'; + const optManual = document.createElement('option'); + optManual.value = 'manual'; + optManual.textContent = 'Manual'; + sel.appendChild(optAuto); + sel.appendChild(optManual); + const widthInput = document.createElement('input'); + widthInput.type = 'number'; + widthInput.min = '40'; + widthInput.max = '800'; + widthInput.value = col.width ? String(col.width) : ''; + const widthMode = col.width ? 'manual' : 'auto'; + sel.value = widthMode; + widthInput.disabled = widthMode !== 'manual'; + sel.addEventListener('change', () => { + widthInput.disabled = sel.value !== 'manual'; + }); + tdWidth.appendChild(sel); + tdWidth.appendChild(widthInput); + + const tdHeadAlign = document.createElement('td'); + const headAlign = document.createElement('select'); + ['left', 'center', 'right'].forEach((val) => { + const opt = document.createElement('option'); + opt.value = val; + opt.textContent = val; + headAlign.appendChild(opt); + }); + headAlign.value = col.headAlign || 'left'; + tdHeadAlign.appendChild(headAlign); + + const tdCellAlign = document.createElement('td'); + const cellAlign = document.createElement('select'); + ['left', 'center', 'right'].forEach((val) => { + const opt = document.createElement('option'); + opt.value = val; + opt.textContent = val; + cellAlign.appendChild(opt); + }); + cellAlign.value = col.cellAlign || 'left'; + tdCellAlign.appendChild(cellAlign); + + const tdOrder = document.createElement('td'); + const upBtn = document.createElement('button'); + upBtn.type = 'button'; + upBtn.className = 'btn'; + upBtn.textContent = '↑'; + const downBtn = document.createElement('button'); + downBtn.type = 'button'; + downBtn.className = 'btn'; + downBtn.textContent = '↓'; + upBtn.addEventListener('click', () => { + const prev = tr.previousElementSibling; + if (prev) prev.before(tr); + }); + downBtn.addEventListener('click', () => { + const next = tr.nextElementSibling; + if (next) next.after(tr); + }); + tdOrder.appendChild(upBtn); + tdOrder.appendChild(downBtn); + + tr.appendChild(tdOn); + tr.appendChild(tdLabel); + tr.appendChild(tdWidth); + tr.appendChild(tdHeadAlign); + tr.appendChild(tdCellAlign); + tr.appendChild(tdOrder); + body.appendChild(tr); + }); + + const applyBtn = dialog.querySelector('[data-table-view-apply]'); + const resetBtn = dialog.querySelector('[data-table-view-reset]'); + if (applyBtn && applyBtn.dataset.bound !== '1') { + applyBtn.dataset.bound = '1'; + applyBtn.addEventListener('click', () => { + const rows = Array.from(body.querySelectorAll('tr.table-view-row')); + const cols = rows.map((row) => { + const key = row.dataset.key || ''; + const inputs = row.querySelectorAll('input, select'); + const chk = inputs[0]; + const mode = inputs[1]; + const widthInput = inputs[2]; + const headAlign = inputs[3]; + const cellAlign = inputs[4]; + const width = mode && mode.value === 'manual' ? Number(widthInput.value || 0) : 0; + return { + key, + visible: chk?.checked !== false, + width: width > 0 ? width : 0, + headAlign: headAlign?.value || 'left', + cellAlign: cellAlign?.value || 'left', + }; + }).filter(c => c.key !== ''); + window.UserPrefs?.setTable?.(tableId, { columns: cols }); + this.applyColumnPrefs({ columns: cols }); + dialog.close(); + }); + } + if (resetBtn && resetBtn.dataset.bound !== '1') { + resetBtn.dataset.bound = '1'; + resetBtn.addEventListener('click', () => { + window.UserPrefs?.setTable?.(tableId, { columns: [] }); + this.applyColumnPrefs({ columns: [] }); + dialog.close(); + }); + } + dialog.showModal(); + } + + buildColumnsFromHeaders(saved) { + const headRow = this.table?.querySelector('thead tr'); + if (!headRow) return []; + const ths = Array.from(headRow.querySelectorAll('th')); + const base = ths.map((th) => ({ + key: th.dataset.key || '', + label: th.textContent?.trim() || '', + visible: true, + width: 0, + headAlign: th.classList.contains('align-right') ? 'right' : (th.classList.contains('align-center') ? 'center' : 'left'), + cellAlign: th.classList.contains('align-right') ? 'right' : (th.classList.contains('align-center') ? 'center' : 'left'), + })).filter(c => c.key !== ''); + + if (!Array.isArray(saved) || saved.length === 0) return base; + const map = new Map(saved.map(c => [c.key, c])); + const ordered = []; + saved.forEach((c) => { + const baseCol = base.find(b => b.key === c.key); + if (!baseCol) return; + ordered.push({ + ...baseCol, + visible: c.visible !== false, + width: Number(c.width || 0), + headAlign: c.headAlign || baseCol.headAlign || 'left', + cellAlign: c.cellAlign || baseCol.cellAlign || 'left', + }); + }); + base.forEach((c) => { + if (!map.has(c.key)) ordered.push(c); + }); + return ordered; + } + + getTableId() { + return this.table?.dataset?.tableId || this.table?.id || ''; + } + + applyColumnPrefs(prefs) { + let columns = Array.isArray(prefs?.columns) ? prefs.columns : []; + if (columns.length === 0 && Array.isArray(this.defaultColumns)) { + columns = this.defaultColumns.map(c => ({ ...c })); + } + if (columns.length === 0) return; + this.columnPrefs = columns; + const headRow = this.table?.querySelector('thead tr'); + if (!headRow) return; + const ths = Array.from(headRow.querySelectorAll('th')); + const keyToIndex = new Map(); + ths.forEach((th, idx) => { + const key = th.dataset.key || ''; + if (key) keyToIndex.set(key, idx); + }); + const order = columns.map(c => c.key).filter(k => keyToIndex.has(k)); + const used = new Set(order); + ths.forEach((th) => { + const key = th.dataset.key || ''; + if (key && !used.has(key)) order.push(key); + }); + this.columnOrder = order; + this.reorderColumns(order, ths.length, keyToIndex); + this.applyColumnStyles(); + } + + reorderColumns(order, count, keyToIndex) { + if (!this.table) return; + const rows = Array.from(this.table.querySelectorAll('tr')); + rows.forEach((row) => { + const cells = Array.from(row.children); + if (cells.length !== count) return; + const cellByKey = new Map(); + let hasKeys = false; + cells.forEach((cell) => { + const key = cell.dataset?.key || ''; + if (key) { + cellByKey.set(key, cell); + hasKeys = true; + } + }); + if (hasKeys) { + const newCells = []; + const used = new Set(); + order.forEach((key) => { + const cell = cellByKey.get(key); + if (cell) { + newCells.push(cell); + used.add(cell); + } + }); + cells.forEach((cell) => { + if (!used.has(cell)) newCells.push(cell); + }); + if (newCells.length !== cells.length) return; + newCells.forEach((cell) => row.appendChild(cell)); + return; + } + const newCells = []; + order.forEach((key) => { + const idx = keyToIndex.get(key); + if (idx >= 0 && cells[idx]) newCells.push(cells[idx]); + }); + if (newCells.length !== count) return; + newCells.forEach((cell) => row.appendChild(cell)); + }); + } + + applyColumnVisibility(columns, order) { + if (!this.table) return; + const visibility = new Map(columns.map(c => [c.key, c.visible !== false])); + const rows = Array.from(this.table.querySelectorAll('tr')); + rows.forEach((row) => { + const cells = Array.from(row.children); + if (cells.length !== order.length) return; + order.forEach((key, idx) => { + const visible = visibility.get(key); + if (visible === undefined) return; + cells[idx].classList.toggle('is-hidden', !visible); + }); + }); + } + + applyFilterVisibility(columns, order) { + const row = this.filterRow; + if (!row) return; + const visibility = new Map(columns.map(c => [c.key, c.visible !== false])); + const visibleKeys = new Set(columns.filter(c => c.visible !== false).map(c => c.key)); + const cells = Array.from(row.children); + cells.forEach((cell, idx) => { + const key = cell.dataset?.key || order[idx] || ''; + if (!key) return; + const visible = visibility.get(key); + if (visible === undefined) return; + cell.classList.toggle('is-hidden', !visible); + const inputs = cell.querySelectorAll('input, select, textarea, button'); + inputs.forEach((el) => { + el.disabled = !visible; + if (!visible && 'value' in el) el.value = ''; + }); + }); + + const before = Array.isArray(this.filters) ? this.filters : []; + const next = before.filter(f => visibleKeys.has(f.key)); + if (next.length !== before.length) { + this.filters = next; + this.syncFilterInputs(); + } + } + + applyColumnWidths(columns, order) { + if (!this.table) return; + const widths = new Map(columns.map(c => [c.key, Number(c.width || 0)])); + const rows = Array.from(this.table.querySelectorAll('tr')); + rows.forEach((row) => { + const cells = Array.from(row.children); + if (cells.length !== order.length) return; + order.forEach((key, idx) => { + const width = widths.get(key) || 0; + if (width > 0) { + cells[idx].style.width = `${width}px`; + } else { + cells[idx].style.width = ''; + } + }); + }); + this.table.style.tableLayout = 'fixed'; + } + + applyColumnStyles() { + const columns = Array.isArray(this.columnPrefs) ? this.columnPrefs : []; + const order = Array.isArray(this.columnOrder) ? this.columnOrder : []; + if (columns.length === 0 || order.length === 0) return; + const headRow = this.table?.querySelector('thead tr'); + if (headRow) { + const ths = Array.from(headRow.querySelectorAll('th')); + const keyToIndex = new Map(); + ths.forEach((th, idx) => { + const key = th.dataset.key || ''; + if (key) keyToIndex.set(key, idx); + }); + this.reorderColumns(order, ths.length, keyToIndex); + } + this.applyColumnVisibility(columns, order); + this.applyFilterVisibility(columns, order); + this.applyColumnWidths(columns, order); + this.applyColumnAlign(columns, order); + } + + applyColumnAlign(columns, order) { + if (!this.table) return; + const headAlign = new Map(columns.map(c => [c.key, c.headAlign || 'left'])); + const cellAlign = new Map(columns.map(c => [c.key, c.cellAlign || 'left'])); + const rows = Array.from(this.table.querySelectorAll('tr')); + rows.forEach((row) => { + const isHead = row.parentElement?.tagName === 'THEAD'; + const cells = Array.from(row.children); + if (cells.length !== order.length) return; + order.forEach((key, idx) => { + const align = (isHead ? headAlign.get(key) : cellAlign.get(key)) || 'left'; + const cell = cells[idx]; + if (!cell) return; + cell.classList.remove('align-left', 'align-center', 'align-right'); + cell.classList.add(`align-${align}`); + }); + }); + } + + syncFilterInputs() { + const row = this.filterRow; + if (!row) return; + const inputs = row.querySelectorAll('[data-filter-key]'); + const rangeMap = new Map(); + inputs.forEach((el) => { + if (el.dataset.filterRange) { + const key = el.dataset.filterKey || ''; + if (!key) return; + const entry = rangeMap.get(key) || { fromEl: null, toEl: null }; + if (el.dataset.filterRange === 'from') entry.fromEl = el; + if (el.dataset.filterRange === 'to') entry.toEl = el; + rangeMap.set(key, entry); + return; + } + el.value = ''; + }); + rangeMap.forEach((entry) => { + if (entry.fromEl) entry.fromEl.value = ''; + if (entry.toEl) entry.toEl.value = ''; + }); + const filters = Array.isArray(this.filters) ? this.filters : []; + filters.forEach((f) => { + const key = f?.key || ''; + if (!key) return; + if (f.op === 'between' && Array.isArray(f.value)) { + const entry = rangeMap.get(key); + if (entry?.fromEl) entry.fromEl.value = String(f.value[0] ?? ''); + if (entry?.toEl) entry.toEl.value = String(f.value[1] ?? ''); + return; + } + inputs.forEach((el) => { + if (el.dataset.filterKey !== key) return; + if (el.dataset.filterRange) return; + el.value = f.value ?? ''; + }); + }); + if (this.filterThs) { + const active = new Set(filters.map(f => f.key)); + this.filterThs.forEach((th) => { + if (!th.dataset.filter) return; + const key = th.dataset.key || ''; + th.classList.toggle('filter-active', key !== '' && active.has(key)); + }); + } + if (this.filterSummaryEl) { + this.filterSummaryEl.textContent = filters.length ? `Filters: ${filters.length}` : ''; + } + } + + isWrapScrollable() { + if (!this.wrap) return false; + return this.wrap.scrollHeight > this.wrap.clientHeight + 4; + } + + totalPages() { + return Math.max(1, Math.ceil((this.total || 0) / this.pageSize)); + } + + async load(page = 1, append = false) { + if (!this.fetchPage || !this.renderRow || !this.tbody) return; + if (this.loading) return; + this.loading = true; + + const payload = { + page, + per_page: this.pageSize, + sort: this.sort, + dir: this.dir, + filters: this.filters, + params: this.params, + }; + + try { + const res = await this.fetchPage(payload); + const items = res.items || []; + this.total = Number(res.total || 0); + this.page = Number(res.page || page); + if (!append) { + this.tbody.innerHTML = ''; + } + items.forEach(item => this.renderRow(this.tbody, item)); + this.applyColumnStyles(); + this.updateFooter(); + } finally { + this.loading = false; + } + } + + reload() { + return this.load(this.page, false); + } + + updateFooter() { + if (!this.footer) return; + if (this.mode === 'infinite') { + if (this.prevBtn) this.prevBtn.disabled = true; + if (this.nextBtn) this.nextBtn.disabled = true; + } else { + const totalPages = this.totalPages(); + if (this.prevBtn) this.prevBtn.disabled = this.page <= 1; + if (this.nextBtn) this.nextBtn.disabled = this.page >= totalPages; + } + + if (this.pageEl) { + const totalPages = this.totalPages(); + this.pageEl.textContent = `${this.page} / ${totalPages}`; + } + if (this.metaEl) { + const start = (this.page - 1) * this.pageSize + 1; + const end = Math.min(this.total, this.page * this.pageSize); + if (this.total === 0) { + this.metaEl.textContent = ''; + } else { + this.metaEl.textContent = `${start}-${end} / ${this.total}`; + } + } + } +} + +window.TableController = TableController; diff --git a/public/assets/js/ui.js b/public/assets/js/ui.js new file mode 100644 index 0000000..c222b87 --- /dev/null +++ b/public/assets/js/ui.js @@ -0,0 +1,343 @@ +// public/assets/ui.js +/* English comments: shared DOM + UI helpers */ + +(function () { + const LS_THEME = 'scmedia_theme'; + let themeToggleReady = false; + let queueState = { active: [], recent: [] }; + let sseOpening = false; + + function qs(selOrId) { + if (typeof selOrId !== 'string') return null; + const s = selOrId.trim(); + if (s === '') return null; + if (s[0] === '#' || s[0] === '.' || s[0] === '[' || s.includes(' ') || s.includes('>')) { + return document.querySelector(s); + } + return document.getElementById(s); + } + + function qsa(selector) { + return Array.from(document.querySelectorAll(selector)); + } + + function setTheme(theme) { + const mode = theme === 'light' ? 'light' : 'dark'; + document.documentElement.setAttribute('data-theme', mode); + localStorage.setItem(LS_THEME, mode); + } + + + function initThemeToggle() { + const btn = qs('themeToggle'); + const saved = localStorage.getItem(LS_THEME) || 'dark'; + setTheme(saved); + if (!btn || themeToggleReady) return; + btn.addEventListener('click', () => { + const current = document.documentElement.getAttribute('data-theme') || 'dark'; + setTheme(current === 'dark' ? 'light' : 'dark'); + }); + themeToggleReady = true; + } + + function formatBytes(bytes) { + const value = Number(bytes || 0); + if (!Number.isFinite(value) || value <= 0) return '0 B'; + const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']; + let idx = 0; + let n = value; + while (n >= 1024 && idx < units.length - 1) { + n /= 1024; + idx += 1; + } + return `${n.toFixed(n >= 10 || idx === 0 ? 0 : 1)} ${units[idx]}`; + } + + window.UI = { + qs, + qsa, + setTheme, + initThemeToggle, + formatBytes, + }; + + window.UI.bindThemePreference = function (onChange) { + const btn = qs('themeToggle'); + if (!btn || btn.dataset.themePrefBind === '1') return; + btn.dataset.themePrefBind = '1'; + btn.addEventListener('click', () => { + const current = document.documentElement.getAttribute('data-theme') || 'dark'; + window.UserPrefs?.setUi?.('theme', current); + if (typeof onChange === 'function') { + onChange(current); + } + }); + }; + + window.UI.updateSseIndicator = function (status) { + const items = document.querySelectorAll('[data-sse-indicator]'); + items.forEach((el) => { + el.classList.remove('sse-ok', 'sse-idle', 'sse-offline'); + if (status === 'ok') el.classList.add('sse-ok'); + else if (status === 'idle') el.classList.add('sse-idle'); + else if (status === 'offline') el.classList.add('sse-offline'); + }); + }; + + window.UI.blinkSseIndicator = function () { + const items = document.querySelectorAll('[data-sse-indicator]'); + items.forEach((el) => { + el.classList.add('sse-blink'); + setTimeout(() => el.classList.remove('sse-blink'), 250); + }); + }; + + window.UI.startSseIndicatorPolling = function () { + const updateFromStorage = () => { + const last = Number(localStorage.getItem('scmedia_sse_last') || 0); + const connectedRaw = localStorage.getItem('scmedia_sse_connected'); + const connected = connectedRaw === '1'; + if (!last && !connectedRaw) { + const items = document.querySelectorAll('[data-sse-indicator]'); + items.forEach((el) => { + el.classList.remove('sse-ok', 'sse-idle', 'sse-offline'); + }); + return; + } + const recent = last > 0 && (Date.now() - last) <= 15000; + if (recent) { + window.UI.updateSseIndicator('ok'); + return; + } + if (connected) { + window.UI.updateSseIndicator('idle'); + return; + } + window.UI.updateSseIndicator('offline'); + }; + updateFromStorage(); + setInterval(updateFromStorage, 5000); + }; + window.UI.startSseClient = function () { + window.Sse?.start?.(); + }; + + window.UI.stopSseClient = function () { + window.Sse?.stop?.(); + }; + + window.UI.getSseStats = function () { + const connected = localStorage.getItem('scmedia_sse_connected') === '1'; + const last = Number(localStorage.getItem('scmedia_sse_last') || 0); + const lastType = localStorage.getItem('scmedia_sse_last_type') || '—'; + const reconnects = Number(localStorage.getItem('scmedia_sse_reconnects') || 0); + return { connected, last, lastType, reconnects }; + }; + + window.UI.initQueuePanel = function () { + const summary = qs('queueSummary'); + const menu = qs('queueMenu'); + if (!summary || !menu) return; + if (summary.dataset.queueInit === '1') return; + summary.dataset.queueInit = '1'; + + const t = (key, fallback) => { + const dict = window.I18N || {}; + const v = dict && Object.prototype.hasOwnProperty.call(dict, key) ? dict[key] : null; + return (typeof v === 'string' && v.length) ? v : fallback; + }; + + const updateQueueSummary = (data) => { + const activeEl = summary.querySelector('[data-queue-active]'); + const errorsEl = summary.querySelector('[data-queue-errors]'); + const dividerEl = summary.querySelector('[data-queue-divider]'); + if (activeEl || errorsEl) { + const activeLabel = activeEl?.dataset.queueActiveLabel || t('queue.active', 'Active'); + const errorsLabel = errorsEl?.dataset.queueErrorsLabel || t('queue.errors', 'Errors'); + const activeCount = Number(data.running || 0); + const errorsCount = Number(data.errors || 0); + if (activeEl) activeEl.textContent = `${activeLabel}: ${activeCount}`; + if (errorsEl) { + errorsEl.textContent = `${errorsLabel}: ${errorsCount}`; + errorsEl.classList.toggle('is-hidden', errorsCount <= 0); + } + if (dividerEl) dividerEl.classList.toggle('is-hidden', errorsCount <= 0); + } + }; + + const updateJobIndicator = (job) => { + const wrap = qs('job-indicator'); + const prog = qs('job-indicator-progress'); + if (!wrap || !prog) return; + if (!job) { + wrap.classList.add('hidden'); + return; + } + wrap.classList.remove('hidden'); + const total = Number(job.progress_total || 0); + const cur = Number(job.progress || 0); + const pct = total > 0 ? Math.floor((cur / total) * 100) : 0; + prog.max = 100; + prog.value = pct; + }; + + const isMenuOpen = () => !menu.classList.contains('is-hidden'); + + const cancelJobById = async (id) => { + if (!id) return; + if (!confirm(t('job.cancel_confirm', 'Cancel job?'))) return; + try { + await apiJson('/api/jobs/cancel', { + method: 'POST', + body: JSON.stringify({ id }), + headers: { 'Content-Type': 'application/json' }, + }); + } catch (e) { + // ignore + } + }; + + const renderQueueMenu = () => { + const activeWrap = qs('queueMenuActive'); + const finishedWrap = qs('queueMenuFinished'); + if (!activeWrap || !finishedWrap) return; + activeWrap.innerHTML = ''; + finishedWrap.innerHTML = ''; + + if (queueState.active.length === 0) { + const empty = document.createElement('div'); + empty.className = 'queue-item-status'; + empty.textContent = t('queue.none_active', 'No active tasks'); + activeWrap.appendChild(empty); + } else { + queueState.active.forEach(j => { + const row = document.createElement('div'); + row.className = 'queue-item'; + const title = document.createElement('div'); + const pct = j.progress_total > 0 ? Math.floor((j.progress / j.progress_total) * 100) : 0; + title.textContent = `${j.title || ''} (${pct}%)`; + const actions = document.createElement('div'); + actions.className = 'queue-item-actions'; + const btn = document.createElement('button'); + btn.className = 'btn'; + btn.textContent = t('queue.cancel', 'Cancel'); + btn.addEventListener('click', () => cancelJobById(j.id)); + actions.appendChild(btn); + row.appendChild(title); + row.appendChild(actions); + activeWrap.appendChild(row); + }); + } + + if (queueState.recent.length === 0) { + const empty = document.createElement('div'); + empty.className = 'queue-item-status'; + empty.textContent = t('queue.none_finished', 'No finished tasks'); + finishedWrap.appendChild(empty); + } else { + queueState.recent.forEach(j => { + const row = document.createElement('div'); + row.className = 'queue-item'; + const title = document.createElement('div'); + title.textContent = j.title || ''; + const status = document.createElement('div'); + status.className = 'queue-item-status'; + status.textContent = j.status || ''; + row.appendChild(title); + row.appendChild(status); + finishedWrap.appendChild(row); + }); + } + updateSseStats(); + }; + + const updateSseStats = () => { + const wrap = qs('queueSseStats'); + const stats = qs('queueSseStats')?.querySelector('.queue-stats'); + if (!wrap || !stats) return; + const enabled = window.DEBUG_TOOLS_ENABLED === true; + wrap.classList.toggle('is-hidden', !enabled); + if (!enabled) return; + const sse = window.UI.getSseStats(); + const lastAt = sse.last > 0 ? new Date(sse.last).toLocaleTimeString() : '—'; + stats.textContent = `last: ${lastAt} | type: ${sse.lastType} | reconnects: ${sse.reconnects}`; + }; + + const apiJson = async (path, opts = {}) => { + if (window.Api?.request) { + const res = await window.Api.request(path, opts); + return res?.data || res || null; + } + const token = window.Auth?.getAccessToken?.(); + const headers = { ...(opts.headers || {}) }; + if (token) headers.Authorization = `Bearer ${token}`; + const res = await fetch(path, { ...opts, headers }); + const json = await res.json().catch(() => null); + return json?.data || null; + }; + + const loadRecent = async () => { + // disabled: SSE-only mode + }; + + summary.addEventListener('click', () => { + menu.classList.toggle('is-hidden'); + if (!menu.classList.contains('is-hidden')) { + renderQueueMenu(); + } + }); + document.addEventListener('click', (e) => { + if (summary.contains(e.target) || menu.contains(e.target)) return; + menu.classList.add('is-hidden'); + }); + + updateQueueSummary({ running: 0, errors: 0 }); + updateSseStats(); + + if (window.Sse?.on) { + window.Sse.on('jobs', (payload) => { + if (!payload) return; + updateQueueSummary(payload); + updateJobIndicator(payload.active || null); + queueState.active = Array.isArray(payload.active_list) ? payload.active_list : []; + if (isMenuOpen()) renderQueueMenu(); + }); + window.Sse.on('tick', () => updateSseStats()); + } + }; + + window.UI.initHeader = function () { + if (window.Auth?.initHeaderControls) { + window.Auth.initHeaderControls(); + } + if (window.Auth?.initSessionRefresh) { + window.Auth.initSessionRefresh(); + } + window.UI.initThemeToggle(); + window.UI.startSseIndicatorPolling(); + window.UI.initQueuePanel(); + window.UI.startSseClient(); + const menu = document.querySelector('.topbar-menu'); + if (menu && menu.dataset.outsideClose !== '1') { + menu.dataset.outsideClose = '1'; + document.addEventListener('click', (e) => { + if (!menu.hasAttribute('open')) return; + const target = e.target; + if (target && menu.contains(target)) return; + menu.removeAttribute('open'); + }); + document.addEventListener('keydown', (e) => { + if (e.key === 'Escape' && menu.hasAttribute('open')) { + menu.removeAttribute('open'); + } + }); + } + if (window.Sse?.on && window.UI?.blinkSseIndicator) { + const blink = () => window.UI.blinkSseIndicator(); + window.Sse.on('message', blink); + window.Sse.on('jobs', blink); + window.Sse.on('sources', blink); + window.Sse.on('tick', blink); + } + }; +})(); diff --git a/public/index.php b/public/index.php new file mode 100644 index 0000000..d3c8e26 --- /dev/null +++ b/public/index.php @@ -0,0 +1,10 @@ +run(); +$app = null; diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..20765c1 --- /dev/null +++ b/readme.md @@ -0,0 +1,19 @@ +# mediaprep (mvp) + +A minimal Jellyfin pre-processor for CephFS-based libraries. + +## Features (MVP) +- Scan profiles with configurable roots and filters +- Items table with status, structure, and counts +- Background scan jobs with logs/progress + +## Setup +1) Configure `.env` and prepare the database +2) Run scan: + php cli/scan.php +3) Run worker: + php cli/worker.php +4) Serve `public/` via nginx/apache and open in browser + +## Notes +- Worker executes scan jobs and updates progress/logs. diff --git a/sql/schema.sql b/sql/schema.sql new file mode 100644 index 0000000..e67a28e --- /dev/null +++ b/sql/schema.sql @@ -0,0 +1,461 @@ +SET NAMES utf8mb4; +SET time_zone = '+00:00'; + +-- ----------------------- +-- settings +-- ----------------------- +CREATE TABLE IF NOT EXISTS settings ( + `key` VARCHAR(64) NOT NULL, + value_json LONGTEXT NOT NULL, + updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`key`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ----------------------- +-- settings_snapshots +-- ----------------------- +CREATE TABLE IF NOT EXISTS settings_snapshots ( + id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + label VARCHAR(255) NULL, + data_json LONGTEXT NOT NULL, + created_by BIGINT UNSIGNED NULL, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (id), + KEY idx_created_at (created_at) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ----------------------- +-- scan_profiles +-- ----------------------- +CREATE TABLE IF NOT EXISTS scan_profiles ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT, + sort_order INT NOT NULL DEFAULT 1000, + profile_type ENUM('scan','analyze') NOT NULL DEFAULT 'scan', + enabled TINYINT(1) NOT NULL DEFAULT 1, + name VARCHAR(128) NOT NULL, + root_path VARCHAR(1024) NOT NULL, + max_depth TINYINT UNSIGNED NOT NULL DEFAULT 3, + exclude_patterns_json LONGTEXT NOT NULL DEFAULT '[]', + include_ext_mode ENUM('default','custom') NOT NULL DEFAULT 'default', + include_ext_json LONGTEXT NULL, + last_scan_at DATETIME NULL, + last_result ENUM('ok','error','never') NOT NULL DEFAULT 'never', + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (id), + KEY idx_sort (sort_order), + KEY idx_enabled (enabled), + KEY idx_root_path (root_path(255)) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ----------------------- +-- items +-- ----------------------- +CREATE TABLE IF NOT EXISTS items ( + id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + + scan_profile_id INT UNSIGNED NOT NULL, + abs_path VARCHAR(2048) NOT NULL, + rel_path VARCHAR(2048) NULL, + + display_name VARCHAR(512) NOT NULL, + kind ENUM('auto','movie','series') NOT NULL DEFAULT 'auto', + year SMALLINT UNSIGNED NULL, + + structure ENUM('file','folder','dvd','bluray') NOT NULL DEFAULT 'folder', + confidence TINYINT UNSIGNED NOT NULL DEFAULT 0, + + video_count INT UNSIGNED NOT NULL DEFAULT 0, + file_count INT UNSIGNED NOT NULL DEFAULT 0, + + status ENUM('active','gone','ignored') NOT NULL DEFAULT 'active', + last_seen_at DATETIME NULL, + + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + + PRIMARY KEY (id), + UNIQUE KEY uq_profile_path (scan_profile_id, abs_path(255)), + KEY idx_kind (kind), + KEY idx_status (status), + KEY idx_last_seen (last_seen_at), + CONSTRAINT fk_items_profile + FOREIGN KEY (scan_profile_id) REFERENCES scan_profiles(id) + ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ----------------------- +-- jobs +-- ----------------------- +CREATE TABLE IF NOT EXISTS jobs ( + id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + type ENUM('scan','apply','db_reset','clear_index','task') NOT NULL, + status ENUM('queued','running','done','error','canceled') NOT NULL DEFAULT 'queued', + + title VARCHAR(255) NOT NULL, + payload_json LONGTEXT NULL, + + progress_current BIGINT UNSIGNED NOT NULL DEFAULT 0, + progress_total BIGINT UNSIGNED NOT NULL DEFAULT 0, + progress_pct TINYINT UNSIGNED NOT NULL DEFAULT 0, + + cancel_requested TINYINT(1) NOT NULL DEFAULT 0, + last_heartbeat DATETIME NULL, + + error_message TEXT NULL, + + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + started_at DATETIME NULL, + finished_at DATETIME NULL, + updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + + PRIMARY KEY (id), + KEY idx_type (type), + KEY idx_status (status), + KEY idx_created (created_at) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ----------------------- +-- job_logs +-- ----------------------- +CREATE TABLE IF NOT EXISTS job_logs ( + id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + job_id BIGINT UNSIGNED NOT NULL, + ts DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + level ENUM('info','warn','error','debug') NOT NULL DEFAULT 'info', + message TEXT NOT NULL, + PRIMARY KEY (id), + KEY idx_job_ts (job_id, ts), + CONSTRAINT fk_job_logs_job + FOREIGN KEY (job_id) REFERENCES jobs(id) + ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ----------------------- +-- app_logs +-- ----------------------- +CREATE TABLE IF NOT EXISTS app_logs ( + id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + ts DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + level ENUM('info','warn','error','debug') NOT NULL DEFAULT 'info', + message TEXT NOT NULL, + context_json LONGTEXT NULL, + PRIMARY KEY (id), + KEY idx_app_logs_ts (ts), + KEY idx_app_logs_level (level) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ----------------------- +-- media_file_meta +-- ----------------------- +CREATE TABLE IF NOT EXISTS media_file_meta ( + id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + abs_path VARCHAR(2048) NOT NULL, + size_bytes BIGINT UNSIGNED NOT NULL, + mtime INT UNSIGNED NOT NULL, + inode BIGINT UNSIGNED NOT NULL DEFAULT 0, + info_json LONGTEXT NULL, + last_scanned_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (id), + UNIQUE KEY uq_media_path (abs_path(255)), + KEY idx_media_mtime (mtime) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ----------------------- +-- media_files +-- ----------------------- +CREATE TABLE IF NOT EXISTS media_files ( + id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + scan_profile_id INT UNSIGNED NOT NULL, + abs_path VARCHAR(2048) NOT NULL, + rel_path VARCHAR(2048) NOT NULL, + name VARCHAR(512) NOT NULL, + ext VARCHAR(16) NOT NULL, + size_bytes BIGINT UNSIGNED NOT NULL, + mtime INT UNSIGNED NOT NULL, + is_mkv TINYINT(1) NOT NULL DEFAULT 0, + kind ENUM('movie','series','unknown') NOT NULL DEFAULT 'unknown', + series_key VARCHAR(512) NULL, + container VARCHAR(64) NULL, + duration_ms BIGINT UNSIGNED NULL, + last_analyzed_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (id), + UNIQUE KEY uq_media_files_path (abs_path(255)), + KEY idx_media_files_profile (scan_profile_id), + KEY idx_media_files_kind (kind), + KEY idx_media_files_series (series_key(255)), + CONSTRAINT fk_media_files_profile + FOREIGN KEY (scan_profile_id) REFERENCES scan_profiles(id) + ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ----------------------- +-- media_metadata +-- ----------------------- +CREATE TABLE IF NOT EXISTS media_metadata ( + id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + subject_kind ENUM('movie','series') NOT NULL, + subject_key VARCHAR(2048) NOT NULL, + provider VARCHAR(64) NULL, + provider_id VARCHAR(128) NULL, + title_map_json LONGTEXT NULL, + original_title VARCHAR(512) NULL, + year SMALLINT UNSIGNED NULL, + manual_title VARCHAR(512) NULL, + manual_year SMALLINT UNSIGNED NULL, + source ENUM('auto','manual') NOT NULL DEFAULT 'auto', + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (id), + UNIQUE KEY uq_media_meta_subject (subject_kind, subject_key(255)), + KEY idx_media_meta_provider (provider, provider_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ----------------------- +-- auth: users and roles +-- ----------------------- +CREATE TABLE IF NOT EXISTS users ( + id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + email VARCHAR(255) NOT NULL, + password_hash VARCHAR(255) NOT NULL, + status ENUM('active','disabled') NOT NULL DEFAULT 'active', + token_version INT UNSIGNED NOT NULL DEFAULT 1, + last_login_at DATETIME NULL, + password_changed_at DATETIME NULL, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (id), + UNIQUE KEY uq_users_email (email) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS user_profiles ( + user_id BIGINT UNSIGNED NOT NULL, + nickname VARCHAR(128) NULL, + avatar_blob MEDIUMBLOB NULL, + avatar_mime VARCHAR(64) NULL, + ui_prefs_json LONGTEXT NULL, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (user_id), + CONSTRAINT fk_user_profiles_user + FOREIGN KEY (user_id) REFERENCES users(id) + ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS roles ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT, + name VARCHAR(64) NOT NULL, + description VARCHAR(255) NULL, + PRIMARY KEY (id), + UNIQUE KEY uq_roles_name (name) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS permissions ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT, + `key` VARCHAR(128) NOT NULL, + description VARCHAR(255) NULL, + PRIMARY KEY (id), + UNIQUE KEY uq_permissions_key (`key`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS role_permissions ( + role_id INT UNSIGNED NOT NULL, + permission_id INT UNSIGNED NOT NULL, + PRIMARY KEY (role_id, permission_id), + CONSTRAINT fk_role_permissions_role + FOREIGN KEY (role_id) REFERENCES roles(id) + ON DELETE CASCADE, + CONSTRAINT fk_role_permissions_permission + FOREIGN KEY (permission_id) REFERENCES permissions(id) + ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS user_roles ( + user_id BIGINT UNSIGNED NOT NULL, + role_id INT UNSIGNED NOT NULL, + PRIMARY KEY (user_id, role_id), + CONSTRAINT fk_user_roles_user + FOREIGN KEY (user_id) REFERENCES users(id) + ON DELETE CASCADE, + CONSTRAINT fk_user_roles_role + FOREIGN KEY (role_id) REFERENCES roles(id) + ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS refresh_tokens ( + id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + user_id BIGINT UNSIGNED NOT NULL, + device_id VARCHAR(64) NOT NULL, + token_hash CHAR(64) NOT NULL, + user_agent VARCHAR(255) NULL, + ip_addr VARCHAR(64) NULL, + expires_at DATETIME NOT NULL, + revoked_at DATETIME NULL, + rotated_from_id BIGINT UNSIGNED NULL, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (id), + UNIQUE KEY uq_refresh_token_hash (token_hash), + KEY idx_refresh_user (user_id), + KEY idx_refresh_expires (expires_at), + CONSTRAINT fk_refresh_user + FOREIGN KEY (user_id) REFERENCES users(id) + ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS auth_challenges ( + id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + user_id BIGINT UNSIGNED NOT NULL, + token_hash CHAR(64) NOT NULL, + expires_at DATETIME NOT NULL, + used_at DATETIME NULL, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (id), + UNIQUE KEY uq_auth_challenge_hash (token_hash), + KEY idx_auth_challenge_user (user_id), + KEY idx_auth_challenge_expires (expires_at), + CONSTRAINT fk_auth_challenge_user + FOREIGN KEY (user_id) REFERENCES users(id) + ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS auth_rate_limits ( + id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + ip_addr VARCHAR(64) NOT NULL, + action VARCHAR(32) NOT NULL, + failed_count INT UNSIGNED NOT NULL DEFAULT 0, + window_started_at DATETIME NOT NULL, + blocked_until DATETIME NULL, + updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (id), + UNIQUE KEY uq_auth_rate_key (ip_addr, action), + KEY idx_auth_rate_blocked (blocked_until) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS auth_sse_keys ( + id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + user_id BIGINT UNSIGNED NOT NULL, + key_hash CHAR(64) NOT NULL, + expires_at DATETIME NOT NULL, + used_at DATETIME NULL, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (id), + UNIQUE KEY uq_sse_key_hash (key_hash), + KEY idx_sse_user (user_id), + KEY idx_sse_expires (expires_at), + CONSTRAINT fk_sse_user + FOREIGN KEY (user_id) REFERENCES users(id) + ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS auth_sse_sessions ( + user_id BIGINT UNSIGNED NOT NULL, + session_token CHAR(64) NOT NULL, + updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (user_id), + KEY idx_sse_session_updated (updated_at), + CONSTRAINT fk_sse_session_user + FOREIGN KEY (user_id) REFERENCES users(id) + ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS mfa_methods ( + id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + user_id BIGINT UNSIGNED NOT NULL, + type ENUM('totp') NOT NULL DEFAULT 'totp', + secret_enc VARCHAR(255) NOT NULL, + enabled_at DATETIME NULL, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (id), + KEY idx_mfa_user (user_id), + CONSTRAINT fk_mfa_user + FOREIGN KEY (user_id) REFERENCES users(id) + ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS mfa_backup_codes ( + id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + user_id BIGINT UNSIGNED NOT NULL, + code_hash CHAR(64) NOT NULL, + used_at DATETIME NULL, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (id), + KEY idx_mfa_backup_user (user_id), + CONSTRAINT fk_mfa_backup_user + FOREIGN KEY (user_id) REFERENCES users(id) + ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS password_resets ( + id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + user_id BIGINT UNSIGNED NOT NULL, + token_hash CHAR(64) NOT NULL, + expires_at DATETIME NOT NULL, + used_at DATETIME NULL, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (id), + UNIQUE KEY uq_password_reset_hash (token_hash), + KEY idx_password_reset_user (user_id), + KEY idx_password_reset_expires (expires_at), + CONSTRAINT fk_password_reset_user + FOREIGN KEY (user_id) REFERENCES users(id) + ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE IF NOT EXISTS audit_log ( + id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, + actor_user_id BIGINT UNSIGNED NULL, + action VARCHAR(64) NOT NULL, + target_type VARCHAR(64) NULL, + target_id BIGINT UNSIGNED NULL, + ip_addr VARCHAR(64) NULL, + user_agent VARCHAR(255) NULL, + meta_json LONGTEXT NULL, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (id), + KEY idx_audit_actor (actor_user_id), + KEY idx_audit_action (action), + CONSTRAINT fk_audit_actor + FOREIGN KEY (actor_user_id) REFERENCES users(id) + ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ----------------------- +-- Seed settings (minimal) +-- ----------------------- +INSERT IGNORE INTO settings (`key`, value_json) VALUES +('general', '{"timezone":"Europe/Berlin","language":"ru","safe_mode":false,"auto_refresh_seconds":0,"date_format":"YYYY-MM-DD"}'), +('scanner_defaults', '{"video_ext":["mkv","mp4","avi","mov","m4v","ts","m2ts","wmv"],"max_depth_default":3,"max_files_per_item":3000,"max_items_per_scan":0}'), +('paths', '{"movies_root":"","series_root":"","staging_root":""}'), +('tools', '{"mkvmerge_path":"","mkvpropedit_path":"","ffmpeg_path":""}'), +('logs', '{"retention_days":7,"level":"info"}'), +('layout', '{"movies":{"strategy":"prefix","params":{"n":2},"template":null},"series":{"strategy":"first_letter","params":{},"template":null,"season_naming":"season_2digit"},"normalization":{"ignore_articles":true,"transliterate_non_latin":true,"uppercase_shards":true,"replace_unsafe_chars":true,"trim_dots_spaces":true,"ignore_words":[]},"collision_policy":"stop"}'), +('media_rules', '{"name_map":[],"delete_rules":[],"language_priority":["ru","en"],"audio_type_priority":["dub","voiceover","original","commentary","unknown"],"require_audio_type":true,"series_order_threshold":0.7}'), +('rules', '[]'), +('sources', '{"transmission":{"enabled":false,"last_test_ok":false,"last_test_at":null,"protocol":"http","host":"","port":9091,"path":"/transmission/rpc","username":"","password":""}}'), +('metadata', '{"enabled":false,"languages":["de","ru","en"],"provider_priority":["tvdb","omdb"],"providers":{"omdb":{"enabled":false,"api_key":"","base_url":"https://www.omdbapi.com/"},"tvdb":{"enabled":false,"api_key":"","pin":""}}}'), +('exports', '{"kodi":{"enabled":false},"jellyfin":{"enabled":false}}'), +('background', '{"mode":"light","max_parallel_jobs":1,"max_network_jobs":1,"max_io_jobs":1,"batch_sleep_ms":500,"watchdog_minutes":10,"sse_session_ttl_seconds":20,"paused":false}'), +('ui', '{"sse_tick_seconds":10}'), +('safety', '{"max_depth":10,"max_files_per_item":200000,"max_items_per_scan":1000000}'), +('_system', '{"settings_revision":1,"first_run_completed":false}'); + +-- ----------------------- +-- Seed roles +-- ----------------------- +INSERT IGNORE INTO roles (id, name, description) VALUES +(1, 'admin', 'Full access'), +(2, 'manager', 'Manager access'), +(3, 'user', 'User access'); + +-- ----------------------- +-- Seed admin user +-- ----------------------- +INSERT IGNORE INTO users (id, email, password_hash, status, token_version, created_at, updated_at) +VALUES (1, 'admin@admin.local', '$2y$12$2op4ztskqxDR376xnZ6sR.Ccbi.zyPu3KRwJsDAPmeNf5B.ZjEcfC', 'active', 1, NOW(), NOW()); + +INSERT IGNORE INTO user_roles (user_id, role_id) +VALUES (1, 1);