Added cache reload button to admin panel so restarts are needed less often.
This commit is contained in:
6
assets/img/icons/database-refresh.svg
Executable file
6
assets/img/icons/database-refresh.svg
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
<!-- Generated by IcoMoon.io -->
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
|
<path d="M14.422 7.078c-0.786-0.672-1.807-1.078-2.922-1.078-2.202 0-4.035 1.582-4.424 3.672h1.54c0.36-1.253 1.517-2.172 2.884-2.172 0.7 0 1.344 0.241 1.855 0.645l-1.855 1.855h4.5v-4.5l-1.578 1.578z"></path>
|
||||||
|
<path d="M11.5 13.5c-0.7 0-1.344-0.241-1.855-0.645l1.855-1.855h-4.5v4.5l1.578-1.578c0.786 0.672 1.807 1.078 2.922 1.078 2.202 0 4.035-1.582 4.424-3.672h-1.54c-0.36 1.253-1.517 2.172-2.884 2.172z"></path>
|
||||||
|
<path d="M2.158 9.146c-0.762-0.275-1.074-0.562-1.158-0.677v-2.531c0.995 0.643 2.64 1.062 4.5 1.062 0.169 0 0.335-0.004 0.5-0.010v-1.314c-0.165 0.008-0.332 0.012-0.5 0.012-1.152 0-2.252-0.181-3.098-0.51-0.707-0.275-0.996-0.562-1.074-0.677 0.078-0.115 0.367-0.402 1.074-0.677 0.846-0.329 1.946-0.51 3.098-0.51s2.252 0.181 3.098 0.51c0.707 0.275 0.995 0.562 1.074 0.677-0.061 0.090-0.252 0.287-0.674 0.5h1.892c0.072-0.162 0.11-0.329 0.11-0.5 0-1.381-2.462-2.5-5.5-2.5s-5.5 1.119-5.5 2.5v8c0 1.381 2.462 2.5 5.5 2.5 0.169 0 0.335-0.004 0.5-0.010v-1.312c-0.165 0.007-0.332 0.010-0.5 0.010-1.242 0-2.429-0.181-3.342-0.51-0.763-0.275-1.074-0.562-1.158-0.677v-2.594c0.995 0.643 2.64 1.062 4.5 1.062 0.169 0 0.335-0.004 0.5-0.010v-1.312c-0.165 0.007-0.332 0.010-0.5 0.010-1.242 0-2.429-0.181-3.342-0.51z"></path>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
5
assets/img/icons/database-time.svg
Executable file
5
assets/img/icons/database-time.svg
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
<!-- Generated by IcoMoon.io -->
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
|
<path d="M5.5 7c3.038 0 5.5-1.119 5.5-2.5s-2.462-2.5-5.5-2.5-5.5 1.119-5.5 2.5v8c0 1.381 2.462 2.5 5.5 2.5 0.503 0 0.99-0.031 1.452-0.088-0.287-0.381-0.526-0.8-0.711-1.246-0.244 0.014-0.491 0.022-0.741 0.022-1.242 0-2.429-0.181-3.342-0.51-0.763-0.275-1.074-0.562-1.158-0.677v-2.594c0.995 0.643 2.64 1.062 4.5 1.062 0.114 0 0.226-0.002 0.338-0.005 0.043-0.459 0.141-0.902 0.287-1.324-0.206 0.010-0.415 0.016-0.625 0.016-1.242 0-2.429-0.181-3.342-0.51-0.762-0.275-1.074-0.562-1.158-0.677v-2.531c0.995 0.643 2.64 1.062 4.5 1.062zM2.402 3.823c0.846-0.329 1.946-0.51 3.098-0.51s2.252 0.181 3.098 0.51c0.707 0.275 0.995 0.562 1.074 0.677-0.078 0.115-0.367 0.402-1.074 0.677-0.846 0.329-1.946 0.51-3.098 0.51s-2.252-0.181-3.098-0.51c-0.707-0.275-0.996-0.562-1.074-0.677 0.078-0.115 0.367-0.402 1.074-0.677z"></path>
|
||||||
|
<path d="M11.5 7c-2.485 0-4.5 2.015-4.5 4.5s2.015 4.5 4.5 4.5 4.5-2.015 4.5-4.5-2.015-4.5-4.5-4.5zM14 12h-3v-3h1v2h2v1z"></path>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
6
assets/img/icons/database-time2.svg
Executable file
6
assets/img/icons/database-time2.svg
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
<!-- Generated by IcoMoon.io -->
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
|
<path d="M11.5 7c-2.485 0-4.5 2.015-4.5 4.5s2.015 4.5 4.5 4.5c2.485 0 4.5-2.015 4.5-4.5s-2.015-4.5-4.5-4.5zM11.5 14.688c-1.758 0-3.188-1.43-3.188-3.188s1.43-3.188 3.188-3.188 3.188 1.43 3.188 3.188-1.43 3.188-3.188 3.188z"></path>
|
||||||
|
<path d="M12 11v-2h-1v3h3v-1z"></path>
|
||||||
|
<path d="M5.5 7c3.038 0 5.5-1.119 5.5-2.5s-2.462-2.5-5.5-2.5-5.5 1.119-5.5 2.5v8c0 1.381 2.462 2.5 5.5 2.5 0.503 0 0.99-0.031 1.452-0.088-0.287-0.381-0.526-0.8-0.711-1.246-0.244 0.014-0.491 0.022-0.741 0.022-1.242 0-2.429-0.181-3.342-0.51-0.763-0.275-1.074-0.562-1.158-0.677v-2.594c0.995 0.643 2.64 1.062 4.5 1.062 0.114 0 0.226-0.002 0.338-0.005 0.043-0.459 0.141-0.902 0.287-1.324-0.206 0.010-0.415 0.016-0.625 0.016-1.242 0-2.429-0.181-3.342-0.51-0.762-0.275-1.074-0.562-1.158-0.677v-2.531c0.995 0.643 2.64 1.062 4.5 1.062zM2.402 3.823c0.846-0.329 1.946-0.51 3.098-0.51s2.252 0.181 3.098 0.51c0.707 0.275 0.995 0.562 1.074 0.677-0.078 0.115-0.367 0.402-1.074 0.677-0.846 0.329-1.946 0.51-3.098 0.51s-2.252-0.181-3.098-0.51c-0.707-0.275-0.996-0.562-1.074-0.677 0.078-0.115 0.367-0.402 1.074-0.677z"></path>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
5
assets/img/icons/loop3.svg
Executable file
5
assets/img/icons/loop3.svg
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
<!-- Generated by IcoMoon.io -->
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
|
<path d="M13.901 2.599c-1.463-1.597-3.565-2.599-5.901-2.599-4.418 0-8 3.582-8 8h1.5c0-3.59 2.91-6.5 6.5-6.5 1.922 0 3.649 0.835 4.839 2.161l-2.339 2.339h5.5v-5.5l-2.099 2.099z"></path>
|
||||||
|
<path d="M14.5 8c0 3.59-2.91 6.5-6.5 6.5-1.922 0-3.649-0.835-4.839-2.161l2.339-2.339h-5.5v5.5l2.099-2.099c1.463 1.597 3.565 2.599 5.901 2.599 4.418 0 8-3.582 8-8h-1.5z"></path>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 500 B |
4
assets/img/icons/reset.svg
Executable file
4
assets/img/icons/reset.svg
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
<!-- Generated by IcoMoon.io -->
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
|
<path d="M4.126 9c-0.082 0.32-0.126 0.655-0.126 1 0 2.209 1.791 4 4 4s4-1.791 4-4-1.791-4-4-4v3l-5-4 5-4v3c3.314 0 6 2.686 6 6s-2.686 6-6 6-6-2.686-6-6c0-0.341 0.029-0.675 0.084-1h2.043z"></path>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 334 B |
@@ -26,6 +26,11 @@
|
|||||||
>Entity Health</a>
|
>Entity Health</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="button"
|
||||||
|
@click="initCaches"
|
||||||
|
><Icon icon="database-refresh" />Reload caches</button>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
@@ -37,7 +42,17 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { inject } from 'vue';
|
import { inject } from 'vue';
|
||||||
|
|
||||||
|
import { post } from '#/src/api.js';
|
||||||
|
|
||||||
const pageContext = inject('pageContext');
|
const pageContext = inject('pageContext');
|
||||||
|
|
||||||
|
async function initCaches() {
|
||||||
|
await post('/caches', null, {
|
||||||
|
successFeedback: 'Reloaded caches',
|
||||||
|
errorFeedback: 'Failed to reload caches',
|
||||||
|
appendErrorMessage: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@@ -50,6 +65,7 @@ const pageContext = inject('pageContext');
|
|||||||
|
|
||||||
.nav {
|
.nav {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
padding: 1rem 1rem .75rem 1rem;
|
padding: 1rem 1rem .75rem 1rem;
|
||||||
border-bottom: solid 1px var(--shadow-weak-30);
|
border-bottom: solid 1px var(--shadow-weak-30);
|
||||||
margin-bottom: .25rem;
|
margin-bottom: .25rem;
|
||||||
|
|||||||
10
src/app.js
10
src/app.js
@@ -1,14 +1,8 @@
|
|||||||
import initServer from './web/server.js';
|
import initServer from './web/server.js';
|
||||||
import { cacheTagIds } from './tags.js';
|
import { initCaches } from './cache.js';
|
||||||
import { cacheEntityIds } from './entities.js';
|
|
||||||
import { cacheCampaigns } from './campaigns.js';
|
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
await Promise.all([
|
await initCaches();
|
||||||
cacheTagIds(),
|
|
||||||
cacheEntityIds(),
|
|
||||||
cacheCampaigns(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
initServer();
|
initServer();
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/cache.js
12
src/cache.js
@@ -1,5 +1,9 @@
|
|||||||
import redis from './redis.js';
|
import redis from './redis.js';
|
||||||
|
|
||||||
|
import { cacheTagIds } from './tags.js';
|
||||||
|
import { cacheEntityIds } from './entities.js';
|
||||||
|
import { cacheCampaigns } from './campaigns.js';
|
||||||
|
|
||||||
export async function getIdsBySlug(slugs, domain, toMap) {
|
export async function getIdsBySlug(slugs, domain, toMap) {
|
||||||
if (!slugs) {
|
if (!slugs) {
|
||||||
return [];
|
return [];
|
||||||
@@ -25,3 +29,11 @@ export async function getIdsBySlug(slugs, domain, toMap) {
|
|||||||
|
|
||||||
return ids.filter(Boolean);
|
return ids.filter(Boolean);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function initCaches() {
|
||||||
|
await Promise.all([
|
||||||
|
cacheTagIds(),
|
||||||
|
cacheEntityIds(),
|
||||||
|
cacheCampaigns(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export default async function initRestrictionHandler() {
|
|||||||
const reader = await Reader.open('assets/GeoLite2-City.mmdb');
|
const reader = await Reader.open('assets/GeoLite2-City.mmdb');
|
||||||
|
|
||||||
function getRestriction(req) {
|
function getRestriction(req) {
|
||||||
if (req.session.restriction && req.session.country && req.session.restrictionIp === req.userIp) {
|
if (Object.hasOwn(req.session, 'restriction') && Object.hasOwn(req.session, 'country') && req.session.restrictionIp === req.userIp) {
|
||||||
return {
|
return {
|
||||||
restriction: req.session.restriction,
|
restriction: req.session.restriction,
|
||||||
country: req.session.country,
|
country: req.session.country,
|
||||||
@@ -71,6 +71,10 @@ export default async function initRestrictionHandler() {
|
|||||||
req.country = country;
|
req.country = country;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`Failed Maxmind IP lookup for ${req.ip}: ${error.message}`);
|
logger.error(`Failed Maxmind IP lookup for ${req.ip}: ${error.message}`);
|
||||||
|
|
||||||
|
req.session.restrictionIp = req.userIp;
|
||||||
|
req.session.restriction = 0;
|
||||||
|
req.session.country = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ import { router as userRouter } from './users.js';
|
|||||||
import { router as stashesRouter } from './stashes.js';
|
import { router as stashesRouter } from './stashes.js';
|
||||||
import { router as alertsRouter } from './alerts.js';
|
import { router as alertsRouter } from './alerts.js';
|
||||||
|
|
||||||
|
import { initCachesApi } from './system.js';
|
||||||
|
|
||||||
import initLogger from '../logger.js';
|
import initLogger from '../logger.js';
|
||||||
|
|
||||||
const logger = initLogger();
|
const logger = initLogger();
|
||||||
@@ -158,6 +160,8 @@ export default async function initServer() {
|
|||||||
// TAGS
|
// TAGS
|
||||||
router.get('/api/tags', fetchTagsApi);
|
router.get('/api/tags', fetchTagsApi);
|
||||||
|
|
||||||
|
router.post('/api/caches', initCachesApi);
|
||||||
|
|
||||||
if (config.apiAccess.graphqlEnabled) {
|
if (config.apiAccess.graphqlEnabled) {
|
||||||
router.post('/graphql', graphqlApi);
|
router.post('/graphql', graphqlApi);
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/web/system.js
Normal file
12
src/web/system.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { HttpError } from '../errors.js';
|
||||||
|
import { initCaches } from '../cache.js';
|
||||||
|
|
||||||
|
export async function initCachesApi(req, res) {
|
||||||
|
if (req.user?.role !== 'admin') {
|
||||||
|
throw new HttpError('You must be an admin to initialize caches', 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
await initCaches();
|
||||||
|
|
||||||
|
res.status(204).send();
|
||||||
|
}
|
||||||
2
static
2
static
Submodule static updated: 474685693d...217845ef37
Reference in New Issue
Block a user