diff --git a/classquiz/__init__.py b/classquiz/__init__.py index 6171ee9..92f44dd 100644 --- a/classquiz/__init__.py +++ b/classquiz/__init__.py @@ -14,7 +14,20 @@ from classquiz.db import database from datetime import timedelta from classquiz.oauth import rememberme_middleware -from classquiz.routers import users, quiz, utils, stats, storage, search, testing_routes, editor, live, eximport, login +from classquiz.routers import ( + users, + quiz, + utils, + stats, + storage, + search, + testing_routes, + editor, + live, + eximport, + login, + sitemap, +) from classquiz.socket_server import sio from classquiz.helpers import meilisearch_init, telemetry_ping, bg_tasks from scheduler.asyncio import Scheduler @@ -82,4 +95,5 @@ app.include_router( ) app.include_router(editor.router, tags=["editor"], prefix="/api/v1/editor", include_in_schema=True) app.include_router(eximport.router, tags=["export", "import"], prefix="/api/v1/eximport", include_in_schema=True) +app.include_router(sitemap.router, tags=["sitemap"], prefix="/api/v1/sitemap", include_in_schema=True) app.mount("/", ASGIApp(sio)) diff --git a/classquiz/routers/sitemap.py b/classquiz/routers/sitemap.py new file mode 100644 index 0000000..f75165f --- /dev/null +++ b/classquiz/routers/sitemap.py @@ -0,0 +1,61 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at https://mozilla.org/MPL/2.0/. +import datetime +import uuid + +from fastapi import APIRouter, Response +from jinja2 import Template +from pydantic import BaseModel +from classquiz.config import redis, settings +from classquiz.db import database + +settings = settings() +router = APIRouter() + + +sitemap_template = """ + +{% for entry in pages -%} + + {{ root_address}}/view/{{ entry.id.hex }} + {%- if entry.updated_at != None -%} + {{ entry.updated_at.strftime("%Y-%m-%d") }} + {% endif %} + + {%- endfor %} +""" + + +sql_statement_metadata = """ +SELECT id, title, description, updated_at from quiz where public ='t' +""" + +sql_statement_id_and_modified_only = """ +SELECT id, updated_at from quiz where public ='t' +""" + +template = Template(sitemap_template, enable_async=True) + + +class SitemapQuiz(BaseModel): + id: uuid.UUID + updated_at: datetime.datetime + + class Config: + orm_mode = True + + +@router.get("/get") +async def get_sitemap(): + redis_cache_resp = await redis.get("sitemap") + if redis_cache_resp is None: + res = await database.fetch_all(sql_statement_id_and_modified_only) + entries = [] + for i in res: + entries.append(SitemapQuiz.from_orm(i)) + rendered_sitemap = await template.render_async({"pages": entries, "root_address": settings.root_address}) + await redis.set("sitemap", rendered_sitemap, ex=86400) + return Response(content=rendered_sitemap, media_type="application/xml") + else: + return Response(content=redis_cache_resp, media_type="application/xml") diff --git a/frontend/src/lib/editor.svelte b/frontend/src/lib/editor.svelte index 574a0a8..a298ebd 100644 --- a/frontend/src/lib/editor.svelte +++ b/frontend/src/lib/editor.svelte @@ -11,8 +11,6 @@ import SettingsCard from '$lib/editor/settings-card.svelte'; import QuizCard from '$lib/editor/card.svelte'; import Spinner from './Spinner.svelte'; - import { elementSelection } from '$lib/stores.js'; - import ElementSelection from '$lib/editor/slides/element_selection.svelte'; let schemaInvalid = false; let yupErrorMessage = ''; @@ -191,7 +189,3 @@ {/await} - -{#if $elementSelection.data === null} - -{/if} diff --git a/frontend/src/lib/editor/card.svelte b/frontend/src/lib/editor/card.svelte index 061b0ff..a79b74f 100644 --- a/frontend/src/lib/editor/card.svelte +++ b/frontend/src/lib/editor/card.svelte @@ -12,7 +12,7 @@ import Spinner from '../Spinner.svelte'; import { createTippy } from 'svelte-tippy'; import { getLocalization } from '$lib/i18n'; - // import Slide from './slide.svelte'; + import Slide from './slide.svelte'; const { t } = getLocalization(); @@ -50,8 +50,6 @@ data.questions[selected_question].type = QuizQuestionType.ABCD; } */ - - $: console.log();
@@ -69,13 +67,7 @@ />
- {#if data.questions[selected_question].type === QuizQuestionType.SLIDE} - {#await import('./slide.svelte')} - - {:then c} - - {/await} - {:else} + {#if data.questions[selected_question].time}
{#await import('$lib/inline-editor.svelte')} @@ -187,6 +179,8 @@ {$t('editor_page.right_click_to_delete')}

+ {:else} + {/if}
diff --git a/frontend/src/lib/quiz_types.ts b/frontend/src/lib/quiz_types.ts index c9e57d1..8bc619e 100644 --- a/frontend/src/lib/quiz_types.ts +++ b/frontend/src/lib/quiz_types.ts @@ -62,7 +62,7 @@ export interface EditorData { public: boolean; title: string; description: string; - questions: (Question | object)[]; + questions: Question[]; cover_image?: string; background_color?: string; } diff --git a/frontend/src/lib/stores.ts b/frontend/src/lib/stores.ts index cb32835..b17548f 100644 --- a/frontend/src/lib/stores.ts +++ b/frontend/src/lib/stores.ts @@ -11,7 +11,6 @@ export const signedIn = writable(false); export const pathname = writable('/'); export const alertModal = writable({ open: false, title: '', body: '' }); -export const elementSelection = writable({ data: undefined }); import { goto } from '$app/navigation'; import { page } from '$app/stores';