Add status of tasks to control panel

This commit is contained in:
Georges-Antoine Assi
2023-08-26 23:21:42 -04:00
parent a5f0942672
commit ed010944fa
9 changed files with 186 additions and 12 deletions

View File

@@ -4,8 +4,8 @@ from datetime import datetime
from pathlib import Path
from config import LOGS_BASE_PATH
from logger.stdout_formatter import StdoutFormatter
from logger.file_formatter import FileFormatter
from .stdout_formatter import StdoutFormatter
from .file_formatter import FileFormatter
# Create logs folder if not exists
Path(LOGS_BASE_PATH).mkdir(parents=True, exist_ok=True)

View File

@@ -8,7 +8,18 @@ from fastapi_pagination import add_pagination
from starlette.middleware.authentication import AuthenticationMiddleware
from starlette.middleware.sessions import SessionMiddleware
from config import DEV_PORT, DEV_HOST, ROMM_AUTH_SECRET_KEY, ROMM_AUTH_ENABLED
from config import (
DEV_PORT,
DEV_HOST,
ROMM_AUTH_SECRET_KEY,
ROMM_AUTH_ENABLED,
ENABLE_RESCAN_ON_FILESYSTEM_CHANGE,
RESCAN_ON_FILESYSTEM_CHANGE_DELAY,
ENABLE_SCHEDULED_RESCAN,
SCHEDULED_RESCAN_CRON,
ENABLE_SCHEDULED_UPDATE_SWITCH_TITLEDB,
SCHEDULED_UPDATE_SWITCH_TITLEDB_CRON,
)
from endpoints import search, platform, rom, identity, oauth, scan # noqa
from handler import dbh
from utils.socket import socket_app
@@ -63,7 +74,15 @@ app.mount("/ws", socket_app)
# Endpoint to set the CSRF token in cache
@app.get("/heartbeat")
def heartbeat():
return {"ROMM_AUTH_ENABLED": ROMM_AUTH_ENABLED}
return {
"ROMM_AUTH_ENABLED": ROMM_AUTH_ENABLED,
"ENABLE_RESCAN_ON_FILESYSTEM_CHANGE": ENABLE_RESCAN_ON_FILESYSTEM_CHANGE,
"RESCAN_ON_FILESYSTEM_CHANGE_DELAY": RESCAN_ON_FILESYSTEM_CHANGE_DELAY,
"ENABLE_SCHEDULED_RESCAN": ENABLE_SCHEDULED_RESCAN,
"SCHEDULED_RESCAN_CRON": SCHEDULED_RESCAN_CRON,
"ENABLE_SCHEDULED_UPDATE_SWITCH_TITLEDB": ENABLE_SCHEDULED_UPDATE_SWITCH_TITLEDB, # noqa
"SCHEDULED_UPDATE_SWITCH_TITLEDB_CRON": SCHEDULED_UPDATE_SWITCH_TITLEDB_CRON,
}
@app.on_event("startup")

View File

@@ -2,6 +2,7 @@ import sys
from config import ENABLE_EXPERIMENTAL_REDIS
from tasks.utils import tasks_scheduler
from logger.logger import log
from tasks.scan_library import scan_library_task
from tasks.update_switch_titledb import update_switch_titledb_task
@@ -13,5 +14,7 @@ if __name__ == "__main__":
scan_library_task.init()
update_switch_titledb_task.init()
log.info("Starting scheduler")
# Start the scheduler
tasks_scheduler.run()

View File

@@ -71,6 +71,8 @@ if __name__ == "__main__":
observer.schedule(EventHandler(), path, recursive=True)
observer.start()
log.info(f"Watching {path} for changes")
try:
while observer.is_alive():
observer.join(1)

View File

@@ -11,7 +11,7 @@ STEAMGRIDDB_API_KEY=
# Database driver (mariadb, sqlite)
ROMM_DB_DRIVER=
# Database config (only for mariadb)
# Database config (mariadb only)
DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=romm
@@ -20,11 +20,22 @@ DB_PASSWD=
DB_ROOT_PASSWD=
# Redis config (optional)
ENABLE_EXPERIMENTAL_REDIS=true
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
# Authentication
ROMM_AUTH_SECRET_KEY=
# Authentication (optional)
ROMM_AUTH_ENABLED=true
ROMM_AUTH_USERNAME=admin
ROMM_AUTH_PASSWORD=admin
ROMM_AUTH_SECRET_KEY=
# Filesystem watcher (optional)
ENABLE_RESCAN_ON_FILESYSTEM_CHANGE=true
RESCAN_ON_FILESYSTEM_CHANGE_DELAY=5
# Periodic Tasks (optional)
ENABLE_SCHEDULED_RESCAN=true
SCHEDULED_RESCAN_CRON=0 3 * * *
ENABLE_SCHEDULED_UPDATE_SWITCH_TITLEDB=true
SCHEDULED_UPDATE_SWITCH_TITLEDB_CRON=0 4 * * *

View File

@@ -11,6 +11,7 @@
"@mdi/font": "7.0.96",
"axios": "^1.3.4",
"core-js": "^3.8.3",
"cronstrue": "^2.31.0",
"file-saver": "^2.0.5",
"js-cookie": "^3.0.5",
"jszip": "^3.10.1",
@@ -2796,6 +2797,14 @@
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
},
"node_modules/cronstrue": {
"version": "2.31.0",
"resolved": "https://registry.npmjs.org/cronstrue/-/cronstrue-2.31.0.tgz",
"integrity": "sha512-A1cyfGyLSRdvT9MNn/pggoCTlvxnJyiCUItU9XHSXk89ZyK2YY9q9q7Rf4j8NhV9YwN1BjB0wimZlvKYb/9Bwg==",
"bin": {
"cronstrue": "bin/cli.js"
}
},
"node_modules/cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",

View File

@@ -12,6 +12,7 @@
"@mdi/font": "7.0.96",
"axios": "^1.3.4",
"core-js": "^3.8.3",
"cronstrue": "^2.31.0",
"file-saver": "^2.0.5",
"js-cookie": "^3.0.5",
"jszip": "^3.10.1",

View File

@@ -3,7 +3,7 @@ import { onBeforeMount } from "vue";
import cookie from "js-cookie";
import storeAuth from "@/stores/auth";
import Notification from "@/components/Notification.vue";
import { api } from "./services/api";
import { api } from "@/services/api";
// Props
const auth = storeAuth();

View File

@@ -1,14 +1,24 @@
<script setup>
import { ref } from "vue";
import { ref, onBeforeMount } from "vue";
import { useTheme } from "vuetify";
import cronstrue from "cronstrue";
import { themes, autoThemeKey } from "@/styles/themes";
import ThemeOption from "@/views/Settings/General/ThemeOption.vue";
import { api } from "@/services/api";
// Props
const theme = useTheme();
const selectedTheme = ref(
parseInt(localStorage.getItem("settings.theme")) || autoThemeKey
);
const heartbeat = ref({
ENABLE_RESCAN_ON_FILESYSTEM_CHANGE: false,
RESCAN_ON_FILESYSTEM_CHANGE_DELAY: 5,
ENABLE_SCHEDULED_RESCAN: false,
SCHEDULED_RESCAN_CRON: "at 03:00 AM, every day",
ENABLE_SCHEDULED_UPDATE_SWITCH_TITLEDB: false,
SCHEDULED_UPDATE_SWITCH_TITLEDB_CRON: "at 03:00 AM, every day",
});
const storedTheme = parseInt(localStorage.getItem("settings.theme"));
const selectedTheme = ref(isNaN(storedTheme) ? autoThemeKey : storedTheme);
// Functions
function toggleTheme() {
@@ -21,6 +31,27 @@ function toggleTheme() {
theme.global.name.value = themes[selectedTheme.value];
}
}
onBeforeMount(async () => {
const { data } = await api.get("/heartbeat");
let rescan = cronstrue.toString(data.SCHEDULED_RESCAN_CRON, {
verbose: true,
});
rescan = rescan.charAt(0).toLocaleLowerCase() + rescan.substr(1);
let switchUpdate = cronstrue.toString(
data.SCHEDULED_UPDATE_SWITCH_TITLEDB_CRON,
{ verbose: true }
);
switchUpdate =
switchUpdate.charAt(0).toLocaleLowerCase() + switchUpdate.substr(1);
heartbeat.value = {
...data,
SCHEDULED_RESCAN_CRON: rescan,
SCHEDULED_UPDATE_SWITCH_TITLEDB_CRON: switchUpdate,
};
});
</script>
<template>
<v-card rounded="0">
@@ -55,4 +86,102 @@ function toggleTheme() {
</v-item-group>
</v-card-text>
</v-card>
<v-card rounded="0" class="mt-2">
<v-toolbar class="bg-terciary" density="compact">
<v-toolbar-title class="text-button">
<v-icon class="mr-3">mdi-pulse</v-icon>
Task Status
</v-toolbar-title>
</v-toolbar>
<v-divider class="border-opacity-25" />
<v-card-text>
<v-row>
<v-col
cols="12"
md="4"
sm="6"
:class="{
'status-item d-flex': true,
disabled: !heartbeat.ENABLE_RESCAN_ON_FILESYSTEM_CHANGE,
}"
>
<v-icon
:icon="
heartbeat.ENABLE_RESCAN_ON_FILESYSTEM_CHANGE
? 'mdi-file-check-outline'
: 'mdi-file-remove-outline'
"
/>
<div class="ml-3">
<v-label class="font-weight-bold"
>Rescan on filesystem change</v-label
>
<p class="mt-1">
Runs a scan when a change is detected in the library path, with a
{{ heartbeat.RESCAN_ON_FILESYSTEM_CHANGE_DELAY }} minutes delay
</p>
</div>
</v-col>
<v-col
cols="12"
md="4"
sm="6"
:class="{
'status-item d-flex': true,
disabled: !heartbeat.ENABLE_SCHEDULED_RESCAN,
}"
>
<v-icon
:icon="
heartbeat.ENABLE_SCHEDULED_RESCAN
? 'mdi-clock-check-outline'
: 'mdi-clock-remove-outline'
"
/>
<div class="ml-3">
<v-label class="font-weight-bold">Scheduled rescan</v-label>
<p class="mt-1">
Rescans the entire library
{{ heartbeat.SCHEDULED_RESCAN_CRON }}
</p>
</div>
</v-col>
<v-col
cols="12"
md="4"
sm="6"
:class="{
'status-item d-flex': true,
disabled: !heartbeat.ENABLE_SCHEDULED_UPDATE_SWITCH_TITLEDB,
}"
>
<v-icon
:icon="
heartbeat.ENABLE_SCHEDULED_UPDATE_SWITCH_TITLEDB
? 'mdi-clock-check-outline'
: 'mdi-clock-remove-outline'
"
/>
<div class="ml-3">
<v-label class="font-weight-bold">
Scheduled Switch TitleDB update
</v-label>
<p class="mt-1">
Updates the Nintedo Switch TitleDB file
{{ heartbeat.SCHEDULED_UPDATE_SWITCH_TITLEDB_CRON }}
</p>
</div>
</v-col>
</v-row>
</v-card-text>
</v-card>
</template>
<style scoped>
.status-item.disabled {
opacity: 0.5;
}
</style>