From: PhiTux Date: Thu, 17 Apr 2025 17:28:04 +0000 (+0200) Subject: settings-logic is working X-Git-Url: http://git.99rst.org/?a=commitdiff_plain;h=a63ddf165b79314c96e810bd295eac27b3daf15b;p=DailyTxT.git settings-logic is working --- diff --git a/backend/server/main.py b/backend/server/main.py index 86afc15..c117d0e 100644 --- a/backend/server/main.py +++ b/backend/server/main.py @@ -3,6 +3,7 @@ from .routers import users, logs from fastapi.middleware.cors import CORSMiddleware import logging from sys import stdout +from .utils.settings import settings logger = logging.getLogger("dailytxtLogger") consoleHandler = logging.StreamHandler(stdout) @@ -12,14 +13,7 @@ logger.setLevel(logging.DEBUG) app = FastAPI() -origins = [ - "http://localhost:5173", - "localhost:5173", - "http://192.168.1.35:5173", - "192.168.1.35:5173", - "http://100.100.87.111:5173", - "http://lab:5173" -] +origins = settings.allowed_hosts app.add_middleware( CORSMiddleware, diff --git a/backend/server/routers/users.py b/backend/server/routers/users.py index 36c8b3d..aab3576 100644 --- a/backend/server/routers/users.py +++ b/backend/server/routers/users.py @@ -2,7 +2,7 @@ import asyncio import datetime import json import secrets -from fastapi import APIRouter, Cookie, HTTPException, Response +from fastapi import APIRouter, Cookie, Depends, HTTPException, Response from pydantic import BaseModel from ..utils import fileHandling from ..utils import security @@ -122,6 +122,76 @@ async def register(register: Register): else: return {"success": True} +def get_default_user_settings(): + return { + "autoloadImagesByDefault": False, + "setAutoloadImagesPerDevice": True, + } + +@router.get("/getUserSettings") +async def get_user_settings(cookie = Depends(isLoggedIn)): + user_id = cookie["user_id"] + content_enc = fileHandling.getUserSettings(user_id) + + if len(content_enc) > 0: + # decrypt settings + enc_key = security.get_enc_key(cookie["user_id"], cookie["derived_key"]) + content = json.loads(security.decrypt_text(content_enc, enc_key)) + else: + content = {} + + default = get_default_user_settings() + + for key in default.keys(): + if key not in content.keys(): + content[key] = default[key] + + return content + + +@router.post("/saveUserSettings") +async def save_user_settings(settings: dict, cookie = Depends(isLoggedIn)): + user_id = cookie["user_id"] + content = fileHandling.getUserSettings(user_id) + + enc_key = security.get_enc_key(cookie["user_id"], cookie["derived_key"]) + if len(content) > 0: + # decrypt settings + content = json.loads(security.decrypt_text(content, enc_key)) + else: + content = {} + + # if content is empty dict + if content is None or len(content) == 0: + content = get_default_user_settings() + + # update settings + for key in settings.keys(): + content[key] = settings[key] + + # encrypt settings + content_enc = security.encrypt_text(json.dumps(content), enc_key) + + try: + fileHandling.writeUserSettings(user_id, content_enc) + except Exception as e: + raise HTTPException(status_code=500, detail="Internal Server Error when trying to write users.json") from e + else: + return {"success": True} + + +""" +export const defaultSettings = writable({ + useTrianglify: true, + trianglifyOpacity: 0.4, + trianglifyColor: '', + backgroundColor: '', + autoloadImagesDefault: true, + saveAutoloadImagesPerDevice: true, +}); +""" + + """ { diff --git a/backend/server/utils/fileHandling.py b/backend/server/utils/fileHandling.py index 1873f62..9f78290 100644 --- a/backend/server/utils/fileHandling.py +++ b/backend/server/utils/fileHandling.py @@ -48,7 +48,7 @@ def writeUsers(content): return e else: with f: - f.write(json.dumps(content, indent=4)) + f.write(json.dumps(content, indent=settings.indent)) return True def writeMonth(user_id, year, month, content): @@ -60,7 +60,7 @@ def writeMonth(user_id, year, month, content): return False else: with f: - f.write(json.dumps(content, indent=4)) + f.write(json.dumps(content, indent=settings.indent)) return True def get_years(user_id): @@ -131,5 +131,30 @@ def writeTags(user_id, content): return False else: with f: - f.write(json.dumps(content, indent=4)) + f.write(json.dumps(content, indent=settings.indent)) + return True + +def getUserSettings(user_id): + try: + f = open(os.path.join(settings.data_path, str(user_id), "settings.encrypted"), "r") + except FileNotFoundError: + logger.info(f"{user_id}/settings.encrypted - File not found") + return {} + except Exception as e: + logger.exception(e) + raise HTTPException(status_code=500, detail="Internal Server Error when trying to open settings.json") + else: + with f: + s = f.read() + return s + +def writeUserSettings(user_id, content): + try: + f = open(os.path.join(settings.data_path, str(user_id), "settings.encrypted"), "w") + except Exception as e: + logger.exception(e) + return False + else: + with f: + f.write(content) return True \ No newline at end of file diff --git a/backend/server/utils/settings.py b/backend/server/utils/settings.py index b1e1fc9..5eb1691 100644 --- a/backend/server/utils/settings.py +++ b/backend/server/utils/settings.py @@ -6,5 +6,7 @@ class Settings(BaseSettings): development: bool = False secret_token: str = secrets.token_urlsafe(32) logout_after_days: int = 30 + allowed_hosts: list[str] = ["http://localhost:5173","http://127.0.0.1:5173"] + indent: int | None = None settings = Settings() \ No newline at end of file diff --git a/frontend/src/lib/settingsStore.js b/frontend/src/lib/settingsStore.js index ad8f715..d22cd09 100644 --- a/frontend/src/lib/settingsStore.js +++ b/frontend/src/lib/settingsStore.js @@ -6,15 +6,9 @@ export const useTrianglify = writable(true); export const trianglifyOpacity = writable(0.4); export const trianglifyColor = writable(''); export const backgroundColor = writable(''); -export const autoLoadImages = writable(true); -export const settings = writable({ - useTrianglify: true, - trianglifyOpacity: 0.4, - trianglifyColor: '', - backgroundColor: '', - autoloadImagesDefault: true, - saveAutoloadImagesPerDevice: true, -}); +export const settings = writable({}); -export const tempSettings = writable({}); \ No newline at end of file +export const tempSettings = writable({}); + +export const autoLoadImagesThisDevice = writable(JSON.parse(localStorage.getItem('autoLoadImagesThisDevice'))); \ No newline at end of file diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte index 44afa21..fed0474 100644 --- a/frontend/src/routes/+layout.svelte +++ b/frontend/src/routes/+layout.svelte @@ -7,14 +7,21 @@ import '../scss/styles.scss'; import * as bootstrap from 'bootstrap'; import Fa from 'svelte-fa'; - import { readingMode } from '$lib/settingsStore.js'; + import { + readingMode, + settings, + tempSettings, + autoLoadImagesThisDevice, + useTrianglify, + trianglifyOpacity + } from '$lib/settingsStore.js'; import { page } from '$app/state'; import { API_URL } from '$lib/APIurl.js'; import trianglify from 'trianglify'; - import { useTrianglify, trianglifyOpacity, autoLoadImages } from '$lib/settingsStore.js'; import { tags } from '$lib/tagStore.js'; import TagModal from '$lib/TagModal.svelte'; import { alwaysShowSidenav } from '$lib/helpers.js'; + import { slide } from 'svelte/transition'; import { faRightFromBracket, @@ -75,6 +82,8 @@ let settingsModal; function openSettingsModal() { + $tempSettings = JSON.parse(JSON.stringify($settings)); + settingsModal = new bootstrap.Modal(document.getElementById('settingsModal')); settingsModal.show(); } @@ -107,9 +116,58 @@ calculateResize(); }); + function getUserSettings() { + axios + .get(API_URL + '/users/getUserSettings') + .then((response) => { + $settings = response.data; + }) + .catch((error) => { + console.error(error); + }) + .finally(() => { + if ($autoLoadImagesThisDevice === null || $autoLoadImagesThisDevice === undefined) { + $autoLoadImagesThisDevice = $settings.autoloadImagesByDefault; + } + }); + } + + let isSaving = $state(false); + function saveUserSettings() { + if (isSaving) return; + isSaving = true; + + axios + .post(API_URL + '/users/saveUserSettings', $tempSettings) + .then((response) => { + if (response.data.success) { + $settings = $tempSettings; + + // show toast + const toast = new bootstrap.Toast(document.getElementById('toastSuccessSaveSettings')); + toast.show(); + + settingsModal.hide(); + } else { + throw new Error('Error saving settings'); + } + }) + .catch((error) => { + console.error(error); + + // show toast + const toast = new bootstrap.Toast(document.getElementById('toastErrorSaveSettings')); + toast.show(); + }) + .finally(() => { + isSaving = false; + }); + } + onMount(() => { createBackground(); calculateResize(); + getUserSettings(); document.getElementById('settingsModal').addEventListener('shown.bs.modal', function () { const height = document.getElementById('modal-body').clientHeight; @@ -208,9 +266,17 @@ .finally(() => { isSavingEditedTag = false; editTagModal.close(); - settingsModal.show(); + openSettingsModal(); }); } + + $effect(() => { + if ($autoLoadImagesThisDevice === null || $autoLoadImagesThisDevice === undefined) { + return; + } + + localStorage.setItem('autoLoadImagesThisDevice', $autoLoadImagesThisDevice); + });
@@ -365,6 +431,10 @@

Funktionen

+ {#if $tempSettings.setAutoloadImagesPerDevice !== $settings.setAutoloadImagesPerDevice || $tempSettings.autoloadImagesByDefault !== $settings.autoloadImagesByDefault} +
+ {/if} +
Bilder automatisch laden
  • @@ -377,16 +447,49 @@
    + +
    + +
    + + +
    + +
    +
    @@ -494,7 +597,17 @@
@@ -536,10 +649,53 @@
Fehler beim Löschen des Tags!
+ + + +