diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d1fda30..f81ce743 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Version 4.1 +* Removed MAL integration, added Anilist Integration +* Now uses WebP cache images when the browser supports it +* Replaces JS minifier with pre-minified scripts (Removes the need for one caching folder, too) +* Updated console command to sync Kitsu and Anilist data + ## Version 4 * Updated to use Kitsu API after discontinuation of Hummingbird * Added streaming links to list entries from the Kitsu API diff --git a/app/appConf/routes.php b/app/appConf/routes.php index 9c33f058..f5c304d0 100644 --- a/app/appConf/routes.php +++ b/app/appConf/routes.php @@ -216,8 +216,8 @@ return [ 'verb' => 'get', ], 'settings-post' => [ - 'path' => '/settings', - 'action' => 'settings', + 'path' => '/settings-save', + 'action' => 'settings_post', 'controller' => DEFAULT_CONTROLLER, 'verb' => 'post', ], diff --git a/app/views/settings.php b/app/views/settings.php index 0269231b..37b53b65 100644 --- a/app/views/settings.php +++ b/app/views/settings.php @@ -6,6 +6,7 @@ if ( ! $auth->isAuthenticated()) } $sectionMapping = [ + 'anilist' => 'Anilist API Integration', 'config' => 'General Settings', 'cache' => 'Caching', 'database' => 'Collection Database Settings', @@ -15,9 +16,7 @@ $hiddenFields = []; $nestedPrefix = 'config'; ?> -
- -
+

diff --git a/index.php b/index.php index 7122ff85..5f269a05 100644 --- a/index.php +++ b/index.php @@ -49,7 +49,13 @@ $baseConfig = require $APPCONF_DIR . '/base_config.php'; $di = require $APP_DIR . '/bootstrap.php'; $config = loadToml($CONF_DIR); -$configArray = array_merge($baseConfig, $config); + +$overrideFile = $CONF_DIR . '/admin-override.toml'; +$overrideConfig = file_exists($overrideFile) + ? loadTomlFile($overrideFile) + : []; + +$configArray = array_merge($baseConfig, $config, $overrideConfig); $checkedConfig = (new ConfigType($configArray))->toArray(); $container = $di($checkedConfig); diff --git a/src/AnimeClient.php b/src/AnimeClient.php index ddba4ed2..c59c4fc2 100644 --- a/src/AnimeClient.php +++ b/src/AnimeClient.php @@ -33,6 +33,11 @@ function loadToml(string $path): array foreach ($files as $file) { $key = str_replace('.toml', '', basename($file)); + if ($key === 'admin-override') + { + continue; + } + $config = Toml::parseFile($file); if ($key === 'config') @@ -71,6 +76,17 @@ function loadTomlByFile(string $path): array return $output; } +/** + * Load config from one specific TOML file + * + * @param string $filename + * @return array + */ +function loadTomlFile(string $filename): array +{ + return Toml::parseFile($filename); +} + /** * Is the array sequential, not associative? * diff --git a/src/Controller/Index.php b/src/Controller/Index.php index d509402a..0c08cc85 100644 --- a/src/Controller/Index.php +++ b/src/Controller/Index.php @@ -39,9 +39,6 @@ final class Index extends BaseController { /** * Purges the API cache * - * @throws \Aviat\Ion\Di\ContainerException - * @throws \Aviat\Ion\Di\NotFoundException - * @throws \InvalidArgumentException * @return void */ public function clearCache() @@ -56,9 +53,6 @@ final class Index extends BaseController { * Show the login form * * @param string $status - * @throws \Aviat\Ion\Di\ContainerException - * @throws \Aviat\Ion\Di\NotFoundException - * @throws \InvalidArgumentException * @return void */ public function login(string $status = '') @@ -109,10 +103,6 @@ final class Index extends BaseController { /** * Attempt login authentication * - * @throws \Aviat\Ion\Di\ContainerException - * @throws \Aviat\Ion\Di\NotFoundException - * @throws \Aura\Router\Exception\RouteNotFound - * @throws \InvalidArgumentException * @return void */ public function loginAction() @@ -133,9 +123,6 @@ final class Index extends BaseController { /** * Deauthorize the current user * - * @throws \Aviat\Ion\Di\ContainerException - * @throws \Aviat\Ion\Di\NotFoundException - * @throws \InvalidArgumentException * @return void */ public function logout() @@ -149,9 +136,6 @@ final class Index extends BaseController { /** * Show the user profile page * - * @throws \Aviat\Ion\Di\ContainerException - * @throws \Aviat\Ion\Di\NotFoundException - * @throws \InvalidArgumentException * @return void */ public function me() @@ -188,14 +172,28 @@ final class Index extends BaseController { ]); } + /** + * Attempt to save the user's settings + * + * @throws \Aura\Router\Exception\RouteNotFound + */ public function settings_post() { - $auth = $this->container->get('auth'); - $this->outputHTML('settings', [ - 'auth' => $auth, - 'config' => $this->config, - 'title' => $this->config->get('whose_list') . "'s Settings", - ]); + $post = $this->request->getParsedBody(); + + // dump($post); + $saved = $this->settingsModel->saveSettingsFile($post); + + if ($saved) + { + $this->setFlashMessage('Saved config settings.', 'success'); + } + else + { + $this->setFlashMessage('Failed to save config file.', 'error'); + } + + $this->redirect($this->url->generate('settings'), 303); } /** @@ -250,7 +248,7 @@ final class Index extends BaseController { $baseSavePath = $this->config->get('img_cache_path'); $filePrefix = "{$baseSavePath}/{$type}/{$id}"; - [$origWidth, $origHeight] = getimagesizefromstring($data); + [$origWidth] = getimagesizefromstring($data); $gdImg = imagecreatefromstring($data); $resizedImg = imagescale($gdImg, $width ?? $origWidth); diff --git a/src/FormGenerator.php b/src/FormGenerator.php index 1a642347..fd91b3fc 100644 --- a/src/FormGenerator.php +++ b/src/FormGenerator.php @@ -83,7 +83,7 @@ final class FormGenerator { $params['attribs']['label'] = $form['description']; $params['attribs']['value'] = TRUE; $params['attribs']['value_unchecked'] = '0'; */ - + $params['type'] = 'radio'; $params['options'] = [ '1' => 'Yes', diff --git a/src/Model/Settings.php b/src/Model/Settings.php index fcb8fab4..c06feade 100644 --- a/src/Model/Settings.php +++ b/src/Model/Settings.php @@ -16,6 +16,9 @@ namespace Aviat\AnimeClient\Model; +use function Aviat\AnimeClient\arrayToToml; +use function Aviat\Ion\_dir; + use Aviat\AnimeClient\Types\{Config, UndefinedPropertyException}; use Aviat\Ion\ConfigInterface; @@ -36,7 +39,12 @@ final class Settings { */ private const SETTINGS_MAP = [ 'anilist' => [ - + 'enabled' => [ + 'type' => 'boolean', + 'title' => 'Enable Anilist Integration', + 'default' => FALSE, + 'description' => 'Enable syncing data between Kitsu and Anilist. Requires appropriate API keys to be set in config', + ], ], 'config' => [ 'kitsu_username' => [ @@ -265,22 +273,88 @@ final class Settings { return $output; } - public function validateSettings(array $settings): bool + public function validateSettings(array $settings) { + $config = (new Config($settings))->toArray(); + + $looseConfig = []; + $keyedConfig = []; + + // Convert 'boolean' values to true and false + // Also order keys so they can be saved properly + foreach ($config as $key => $val) + { + if (is_scalar($val)) + { + if ($val === '1') + { + $looseConfig[$key] = TRUE; + } + elseif ($val === '0') + { + $looseConfig[$key] = FALSE; + } + else + { + $looseConfig[$key] = $val; + } + } + elseif (is_array($val)) + { + foreach($val as $k => $v) + { + if ($v === '1') + { + $keyedConfig[$key][$k] = TRUE; + } + elseif($v === '0') + { + $keyedConfig[$key][$k] = FALSE; + } + else + { + $keyedConfig[$key][$k] = $v; + } + } + } + } + + ksort($looseConfig); + ksort($keyedConfig); + + $output = []; + + foreach($looseConfig as $k => $v) + { + $output[$k] = $v; + } + + foreach($keyedConfig as $k => $v) + { + $output[$k] = $v; + } + + return $output; + } + + public function saveSettingsFile(array $settings): bool + { + $settings = $settings['config']; + try { - new Config($settings); + $settings = $this->validateSettings($settings); } catch (UndefinedPropertyException $e) { return FALSE; } - return TRUE; - } + $savePath = realpath(_dir(__DIR__, '..', '..', 'app', 'config')); + $saveFile = _dir($savePath, 'admin-override.toml'); - public function saveSettingsFile() - { + $saved = file_put_contents($saveFile, arrayToToml($settings)); + return $saved !== FALSE; } } \ No newline at end of file diff --git a/sw.js b/sw.js index 5f1057fb..9113d9bc 100644 --- a/sw.js +++ b/sw.js @@ -61,6 +61,12 @@ self.addEventListener('activate', event => { // Pull css, images, and javascript from cache self.addEventListener('fetch', event => { + // Only cache things with a file extension, + // Ignore other requests + if ( ! event.request.url.includes('/public/')) { + return; + } + fromCache(event.request).then(cached => { if (cached !== undefined) { event.respondWith(cached);