Version 5.1 - All the GraphQL #32
@ -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
|
||||
|
@ -216,8 +216,8 @@ return [
|
||||
'verb' => 'get',
|
||||
],
|
||||
'settings-post' => [
|
||||
'path' => '/settings',
|
||||
'action' => 'settings',
|
||||
'path' => '/settings-save',
|
||||
'action' => 'settings_post',
|
||||
'controller' => DEFAULT_CONTROLLER,
|
||||
'verb' => 'post',
|
||||
],
|
||||
|
@ -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';
|
||||
?>
|
||||
|
||||
<pre><?= print_r($_POST, TRUE) ?></pre>
|
||||
|
||||
<form action="<?= $_SERVER['REQUEST_URI'] ?>" method="POST">
|
||||
<form action="<?= $url->generate('settings-post') ?>" method="POST">
|
||||
<main class='form'>
|
||||
<button type="submit">Save Changes</button>
|
||||
<br />
|
||||
|
@ -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);
|
||||
|
@ -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?
|
||||
*
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
6
sw.js
6
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);
|
||||
|
Loading…
Reference in New Issue
Block a user