mirror of
https://github.com/rommapp/romm.git
synced 2026-06-28 06:46:00 +00:00
Add status of tasks to control panel
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
17
env.template
17
env.template
@@ -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 * * *
|
||||
|
||||
9
frontend/package-lock.json
generated
9
frontend/package-lock.json
generated
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user