From f73b82bdd575ce04a73c1e3be5f161be8c603bbb Mon Sep 17 00:00:00 2001 From: Varun Patil Date: Sun, 9 Apr 2023 23:24:59 -0700 Subject: [PATCH] admin: add settings section Signed-off-by: Varun Patil --- appinfo/info.xml | 4 + appinfo/routes.php | 2 + img/app-dark.svg | 85 +++++++ lib/Controller/OtherController.php | 53 ++++ lib/Settings/Admin.php | 48 ++++ lib/Settings/AdminSection.php | 56 +++++ lib/Util.php | 64 ++++- src/Admin.vue | 384 +++++++++++++++++++++++++++++ src/main.ts | 23 +- src/services/API.ts | 6 + src/services/Utils.ts | 17 +- templates/admin.php | 1 + 12 files changed, 731 insertions(+), 12 deletions(-) create mode 100644 img/app-dark.svg create mode 100644 lib/Settings/Admin.php create mode 100644 lib/Settings/AdminSection.php create mode 100644 src/Admin.vue create mode 100644 templates/admin.php diff --git a/appinfo/info.xml b/appinfo/info.xml index 6cebf03b..ce40bd90 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -47,6 +47,10 @@ Memories is a *batteries-included* photo management solution for Nextcloud with OCA\Memories\Command\PlacesSetup OCA\Memories\Command\MigrateGoogleTakeout + + OCA\Memories\Settings\Admin + OCA\Memories\Settings\AdminSection + Memories diff --git a/appinfo/routes.php b/appinfo/routes.php index b70dfd14..4c13704d 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -83,6 +83,8 @@ return [ // Config API ['name' => 'Other#setUserConfig', 'url' => '/api/config/{key}', 'verb' => 'PUT'], + ['name' => 'Other#getSystemConfig', 'url' => '/api/system-config', 'verb' => 'GET'], + ['name' => 'Other#setSystemConfig', 'url' => '/api/system-config/{key}', 'verb' => 'PUT'], // Service worker ['name' => 'Other#serviceWorker', 'url' => '/service-worker.js', 'verb' => 'GET'], diff --git a/img/app-dark.svg b/img/app-dark.svg new file mode 100644 index 00000000..4a4a7256 --- /dev/null +++ b/img/app-dark.svg @@ -0,0 +1,85 @@ + + + + + + Camera + + + + + + + + + + + + Camera + + + + diff --git a/lib/Controller/OtherController.php b/lib/Controller/OtherController.php index 0ee5f9ea..d1a4e4cc 100644 --- a/lib/Controller/OtherController.php +++ b/lib/Controller/OtherController.php @@ -56,6 +56,59 @@ class OtherController extends GenericApiController }); } + /** + * @AdminRequired + * + * @NoCSRFRequired + */ + public function getSystemConfig(): Http\Response + { + return Util::guardEx(function () { + $config = []; + foreach (Util::systemConfigDefaults() as $key => $default) { + $config[$key] = $this->config->getSystemValue($key, $default); + } + + return new JSONResponse($config, Http::STATUS_OK); + }); + } + + /** + * @AdminRequired + * + * @NoCSRFRequired + * + * @param mixed $value + */ + public function setSystemConfig(string $key, $value): Http\Response + { + return Util::guardEx(function () use ($key, $value) { + // Make sure not running in read-only mode + if ($this->config->getSystemValue('memories.readonly', false)) { + throw Exceptions::Forbidden('Cannot change settings in readonly mode'); + } + + // Make sure the key is valid + $defaults = Util::systemConfigDefaults(); + if (!\array_key_exists($key, $defaults)) { + throw Exceptions::BadRequest('Invalid key'); + } + + // Make sure the value has the same type as the default value + if (\gettype($value) !== \gettype($defaults[$key])) { + throw Exceptions::BadRequest('Invalid value type'); + } + + if ($value === $defaults[$key]) { + $this->config->deleteSystemValue($key); + } else { + $this->config->setSystemValue($key, $value); + } + + return new JSONResponse([], Http::STATUS_OK); + }); + } + /** * @NoAdminRequired * diff --git a/lib/Settings/Admin.php b/lib/Settings/Admin.php new file mode 100644 index 00000000..9387d321 --- /dev/null +++ b/lib/Settings/Admin.php @@ -0,0 +1,48 @@ +config = $config; + $this->l = $l; + } + + /** + * @return TemplateResponse + */ + public function getForm() + { + $parameters = [ + ]; + + \OCP\Util::addScript('memories', 'memories-main'); + + return new TemplateResponse('memories', 'admin', $parameters); + } + + public function getSection() + { + return 'memories'; + } + + public function getPriority() + { + return 50; + } +} diff --git a/lib/Settings/AdminSection.php b/lib/Settings/AdminSection.php new file mode 100644 index 00000000..028293f0 --- /dev/null +++ b/lib/Settings/AdminSection.php @@ -0,0 +1,56 @@ +l = $l; + $this->urlGenerator = $urlGenerator; + } + + /** + * @return TemplateResponse + */ + public function getForm() + { + $parameters = [ + ]; + + return new TemplateResponse('memories', 'admin', $parameters); + } + + public function getID() + { + return 'memories'; + } + + public function getName() + { + return $this->l->t('Memories'); + } + + public function getPriority() + { + return 75; + } + + public function getIcon() + { + return $this->urlGenerator->imagePath('memories', 'app-dark.svg'); + } +} diff --git a/lib/Util.php b/lib/Util.php index d4d81a28..3de5537a 100644 --- a/lib/Util.php +++ b/lib/Util.php @@ -279,7 +279,69 @@ class Util */ public static function placesGISType(): int { - return (int) \OC::$server->get(\OCP\IConfig::class)->getSystemValue('memories.gis_type', -1); + return self::getSystemConfig('memories.gis_type'); + } + + /** + * Get a system config key with the correct default. + * + * @param null|mixed $default + */ + public static function getSystemConfig(string $key, $default = null) + { + $config = \OC::$server->get(\OCP\IConfig::class); + + return $config->getSystemValue($key, $default ?? self::systemConfigDefaults()[$key]); + } + + /** Get list of defaults for all system config keys. */ + public static function systemConfigDefaults(): array + { + return [ + // Places database type identifier + 'memories.gis_type' => -1, + + // Disable transcoding + 'memories.vod.disable' => true, + + // VA-API configuration options + 'memories.vod.vaapi' => false, // Transcode with VA-API + 'memories.vod.vaapi.low_power' => false, // Use low_power mode for VA-API + + // NVENC configuration options + 'memories.vod.nvenc' => false, // Transcode with NVIDIA NVENC + 'memories.vod.nvenc.temporal_aq' => false, + 'memories.vod.nvenc.scale' => 'npp', // npp or cuda + + // Paths to ffmpeg and ffprobe binaries + 'memories.vod.ffmpeg' => '', + 'memories.vod.ffprobe' => '', + + // Path to go-vod binary + 'memories.vod.path' => '', + + // Path to use for transcoded files (/tmp/go-vod/instanceid) + // Make sure this has plenty of space + 'memories.vod.tempdir' => '', + + // Bind address to use when starting the transcoding server + 'memories.vod.bind' => '127.0.0.1:47788', + + // Address used to connect to the transcoding server + // If not specified, the bind address above will be used + 'memories.vod.connect' => '127.0.0.1:47788', + + // Mark go-vod as external. If true, Memories will not attempt to + // start go-vod if it is not running already. + 'memories.vod.external' => false, + + // Set the default video quality for a first time user + // 0 => Auto (default) + // -1 => Original (max quality with transcoding) + // -2 => Direct (disable transcoding) + // 1080 => 1080p (and so on) + 'memories.video_default_quality' => '0', + ]; } /** diff --git a/src/Admin.vue b/src/Admin.vue new file mode 100644 index 00000000..b5ed9a2c --- /dev/null +++ b/src/Admin.vue @@ -0,0 +1,384 @@ + + + + + diff --git a/src/main.ts b/src/main.ts index dd527c0c..105c1bd5 100644 --- a/src/main.ts +++ b/src/main.ts @@ -8,6 +8,7 @@ import XImg from "./components/frame/XImg.vue"; import GlobalMixin from "./mixins/GlobalMixin"; import App from "./App.vue"; +import Admin from "./Admin.vue"; import router from "./router"; import { Route } from "vue-router"; import { generateFilePath } from "@nextcloud/router"; @@ -103,8 +104,20 @@ window.addEventListener("DOMContentLoaded", () => { ); }); -export default new Vue({ - el: "#content", - router, - render: (h) => h(App), -}); +let app = null; + +const adminSection = document.getElementById("memories-admin-content"); +if (adminSection) { + app = new Vue({ + el: "#memories-admin-content", + render: (h) => h(Admin), + }); +} else { + app = new Vue({ + el: "#content", + router, + render: (h) => h(App), + }); +} + +export default app; diff --git a/src/services/API.ts b/src/services/API.ts index 1b672629..59d3250e 100644 --- a/src/services/API.ts +++ b/src/services/API.ts @@ -184,6 +184,12 @@ export class API { return gen(`${BASE}/config/{setting}`, { setting }); } + static SYSTEM_CONFIG(setting: string | null) { + return setting + ? gen(`${BASE}/system-config/{setting}`, { setting }) + : gen(`${BASE}/system-config`); + } + static MAP_CLUSTERS() { return tok(gen(`${BASE}/map/clusters`)); } diff --git a/src/services/Utils.ts b/src/services/Utils.ts index 973f6cbb..0053073b 100644 --- a/src/services/Utils.ts +++ b/src/services/Utils.ts @@ -297,12 +297,17 @@ export const constants = { /** Cache store */ let staticCache: Cache | null = null; -const cacheName = `memories-${loadState("memories", "version")}-${ - getCurrentUser()?.uid -}`; -openCache().then((cache) => { - staticCache = cache; -}); +let cacheName: string; +let memoriesVersion: string; + +try { + memoriesVersion = loadState("memories", "version"); + const uid = getCurrentUser()?.uid; + cacheName = `memories-${memoriesVersion}-${uid}`; + openCache().then((cache) => (staticCache = cache)); +} catch (e) { + console.warn("Failed to open cache"); +} // Clear all caches except the current one window.caches?.keys().then((keys) => { diff --git a/templates/admin.php b/templates/admin.php new file mode 100644 index 00000000..37f68dd3 --- /dev/null +++ b/templates/admin.php @@ -0,0 +1 @@ +
\ No newline at end of file