✨ Removed pow, alertModal and fixed storage
This commit is contained in:
@@ -204,7 +204,6 @@ def extract_image_ids_from_quiz(quiz: Quiz) -> list[str | uuid.UUID]:
|
||||
quiz_images.append(quiz.background_image)
|
||||
if quiz.cover_image is not None:
|
||||
quiz_images.append(quiz.cover_image)
|
||||
|
||||
for question in quiz.questions:
|
||||
if question["image"] is None:
|
||||
continue
|
||||
|
||||
+11
-21
@@ -13,13 +13,13 @@ from fastapi import APIRouter, HTTPException, Depends
|
||||
from pydantic import BaseModel
|
||||
|
||||
from classquiz.config import settings, redis, storage, meilisearch, ALLOWED_TAGS_FOR_QUIZ, arq
|
||||
from classquiz.db.models import Quiz, QuizInput, User, QuizQuestionType
|
||||
from classquiz.db.models import Quiz, QuizInput, User, QuizQuestionType, StorageItem
|
||||
from classquiz.auth import get_current_user
|
||||
import os
|
||||
from datetime import datetime
|
||||
from uuid import UUID
|
||||
|
||||
from classquiz.helpers import get_meili_data, check_image_string
|
||||
from classquiz.helpers import get_meili_data, check_image_string, extract_image_ids_from_quiz
|
||||
from classquiz.storage.errors import DeletionFailedError
|
||||
|
||||
settings = settings()
|
||||
@@ -111,19 +111,6 @@ async def finish_edit(edit_id: str, quiz_input: QuizInput):
|
||||
|
||||
images_to_delete = []
|
||||
old_quiz_data: Quiz = await Quiz.objects.get_or_none(id=session_data.quiz_id, user_id=session_data.user_id)
|
||||
print(old_quiz_data)
|
||||
|
||||
def mark_image_for_deletion(new: str | None, index: int, old_quiz: Quiz | None):
|
||||
if old_quiz is None:
|
||||
return
|
||||
try:
|
||||
# Why does this work or not throw an error (TODO)
|
||||
if new == old_quiz.questions[index]["image"]:
|
||||
return
|
||||
else:
|
||||
images_to_delete.append(old_quiz.questions[index]["image"])
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
for i, question in enumerate(quiz_input.questions):
|
||||
image = question.image
|
||||
@@ -132,11 +119,7 @@ async def finish_edit(edit_id: str, quiz_input: QuizInput):
|
||||
)
|
||||
if image == "":
|
||||
question.image = None
|
||||
if image is None:
|
||||
mark_image_for_deletion(question.image, i, old_quiz_data)
|
||||
elif check_image_string(question.image)[0]:
|
||||
mark_image_for_deletion(question.image, i, old_quiz_data)
|
||||
else:
|
||||
if image is not None and not check_image_string(image)[0]:
|
||||
raise HTTPException(status_code=400, detail="Image URL(s) aren't valid!")
|
||||
|
||||
if quiz_input.cover_image == "":
|
||||
@@ -186,6 +169,7 @@ async def finish_edit(edit_id: str, quiz_input: QuizInput):
|
||||
created_at=datetime.now(),
|
||||
updated_at=datetime.now(),
|
||||
)
|
||||
|
||||
await redis.delete("global_quiz_count")
|
||||
if quiz_input.public:
|
||||
meilisearch.index(settings.meilisearch_index).add_documents([await get_meili_data(quiz)])
|
||||
@@ -193,6 +177,12 @@ async def finish_edit(edit_id: str, quiz_input: QuizInput):
|
||||
await redis.srem("edit_sessions", edit_id)
|
||||
await redis.delete(f"edit_session:{edit_id}")
|
||||
await redis.delete(f"edit_session:{edit_id}:images")
|
||||
return await quiz.save()
|
||||
await quiz.save()
|
||||
except asyncpg.exceptions.UniqueViolationError:
|
||||
raise HTTPException(status_code=400, detail="The quiz already exists")
|
||||
new_images = extract_image_ids_from_quiz(quiz)
|
||||
for image in new_images:
|
||||
item = await StorageItem.objects.get_or_none(id=uuid.UUID(image))
|
||||
if item is None:
|
||||
continue
|
||||
await quiz.storageitems.add(item)
|
||||
|
||||
@@ -17,8 +17,6 @@ settings = settings()
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
file_regex = r"^[a-z0-9]{8}-[a-z0-9-]{27}--[a-z0-9-]{36}$"
|
||||
|
||||
|
||||
@router.get("/download/{file_name}")
|
||||
async def download_file(file_name: str):
|
||||
|
||||
@@ -54,14 +54,16 @@
|
||||
);
|
||||
}
|
||||
if (res.status !== 200) {
|
||||
alertModal.set({
|
||||
/* alertModal.set({
|
||||
open: true,
|
||||
title: 'Start failed',
|
||||
body: `Failed to start game, ${await res.text()}`
|
||||
});
|
||||
alertModal.subscribe((_) => {
|
||||
});*/
|
||||
/*alertModal.subscribe((_) => {
|
||||
window.location.assign('/account/login?returnTo=/dashboard');
|
||||
});
|
||||
});*/
|
||||
alert('Starting game failed');
|
||||
window.location.assign('/account/login?returnTo=/dashboard');
|
||||
} else {
|
||||
const data = await res.json();
|
||||
// eslint-disable-next-line no-undef
|
||||
|
||||
@@ -22,22 +22,6 @@
|
||||
export let quiz_id: string | null;
|
||||
let selected_question = -1;
|
||||
let imgur_links_valid = false;
|
||||
let pow_salt;
|
||||
|
||||
const computePOW = async (salt: string) => {
|
||||
if (pow_salt === undefined) {
|
||||
return;
|
||||
}
|
||||
console.log('Computing POW');
|
||||
pow_data = await mint(salt, 16, '', 8, false);
|
||||
pow_salt = undefined;
|
||||
return;
|
||||
};
|
||||
|
||||
$: {
|
||||
pow_salt;
|
||||
computePOW(pow_salt);
|
||||
}
|
||||
|
||||
const validateInput = async (data: EditorData) => {
|
||||
// console.log("input", data)
|
||||
@@ -72,7 +56,6 @@
|
||||
$: imgur_links_valid = checkIfAllQuestionImagesComplyWithRegex(data.questions);
|
||||
let edit_id;
|
||||
let confirm_to_leave = true;
|
||||
let pow_data;
|
||||
|
||||
const getEditID = async () => {
|
||||
let res;
|
||||
@@ -88,7 +71,6 @@
|
||||
if (res.status === 200) {
|
||||
const json = await res.json();
|
||||
edit_id = json.token;
|
||||
setPOWdata();
|
||||
} else {
|
||||
alert('Error!');
|
||||
}
|
||||
@@ -123,13 +105,6 @@
|
||||
alert('Error');
|
||||
}
|
||||
};
|
||||
const setPOWdata = async () => {
|
||||
const res = await fetch(`/api/v1/editor/pow?edit_id=${edit_id}`);
|
||||
const data = (await res.json()).data;
|
||||
console.log(data);
|
||||
pow_data = await mint(data, 16);
|
||||
console.log(pow_data);
|
||||
};
|
||||
</script>
|
||||
|
||||
<svelte:window on:beforeunload={confirmUnload} />
|
||||
@@ -177,15 +152,9 @@
|
||||
</div>
|
||||
<div class="w-full h-full">
|
||||
{#if selected_question === -1}
|
||||
<SettingsCard bind:data bind:pow_salt bind:edit_id bind:pow_data />
|
||||
<SettingsCard bind:data bind:edit_id />
|
||||
{:else}
|
||||
<QuizCard
|
||||
bind:data
|
||||
bind:selected_question
|
||||
bind:edit_id
|
||||
bind:pow_data
|
||||
bind:pow_salt
|
||||
/>
|
||||
<QuizCard bind:data bind:selected_question bind:edit_id />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
export let data: EditorData;
|
||||
export let selected_question: number;
|
||||
export let edit_id: string;
|
||||
export let pow_data;
|
||||
export let pow_salt: string;
|
||||
|
||||
let uppyOpen = false;
|
||||
let unique = {};
|
||||
@@ -136,15 +134,6 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{:else if pow_data === undefined}
|
||||
<a
|
||||
href="/docs/pow"
|
||||
target="_blank"
|
||||
use:tippy={{ content: "Click to learn why it's loading so long." }}
|
||||
class="cursor-help"
|
||||
>
|
||||
<Spinner my_20={false} />
|
||||
</a>
|
||||
{:else}
|
||||
{#await import('$lib/editor/uploader.svelte')}
|
||||
<Spinner my_20={false} />
|
||||
@@ -155,8 +144,6 @@
|
||||
bind:edit_id
|
||||
bind:data
|
||||
bind:selected_question
|
||||
bind:pow_data
|
||||
bind:pow_salt
|
||||
/>
|
||||
{/await}
|
||||
{/if}
|
||||
|
||||
@@ -8,9 +8,6 @@
|
||||
import { getLocalization } from '$lib/i18n';
|
||||
import Spinner from '$lib/Spinner.svelte';
|
||||
|
||||
export let pow_data;
|
||||
export let pow_salt;
|
||||
|
||||
const { t } = getLocalization();
|
||||
|
||||
let uppyOpen = false;
|
||||
@@ -76,10 +73,6 @@
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{:else if pow_data === undefined}
|
||||
<a href="/docs/pow" target="_blank" class="cursor-help">
|
||||
<Spinner my_20={false} />
|
||||
</a>
|
||||
{:else}
|
||||
{#await import('$lib/editor/uploader.svelte')}
|
||||
<Spinner my_20={false} />
|
||||
@@ -89,8 +82,6 @@
|
||||
bind:modalOpen={uppyOpen}
|
||||
bind:edit_id
|
||||
bind:data
|
||||
bind:pow_data
|
||||
bind:pow_salt
|
||||
/>
|
||||
{/await}
|
||||
{/if}
|
||||
@@ -191,10 +182,6 @@
|
||||
class="mt-10 bg-red-500 p-2 rounded-lg border-2 border-black transition hover:bg-red-400"
|
||||
>Remove Background-Image</button
|
||||
>
|
||||
{:else if pow_data === undefined}
|
||||
<a href="/docs/pow" target="_blank" class="cursor-help pt-10">
|
||||
<Spinner my_20={false} />
|
||||
</a>
|
||||
{:else}
|
||||
{#await import('$lib/editor/uploader.svelte')}
|
||||
<div class="pt-10">
|
||||
@@ -207,8 +194,6 @@
|
||||
bind:edit_id
|
||||
bind:data
|
||||
selected_question={-1}
|
||||
bind:pow_data
|
||||
bind:pow_salt
|
||||
/>
|
||||
{/await}
|
||||
{/if}
|
||||
|
||||
@@ -28,10 +28,7 @@
|
||||
export let edit_id: string;
|
||||
export let data: EditorData;
|
||||
export let selected_question: number;
|
||||
export let pow_data;
|
||||
export let pow_salt: string;
|
||||
|
||||
console.log(pow_data);
|
||||
const uppy = new Uppy()
|
||||
.use(DropTarget, {
|
||||
target: document.body
|
||||
@@ -58,10 +55,8 @@
|
||||
let image_id;
|
||||
uppy.on('upload-success', (file, response) => {
|
||||
image_id = response.body.id;
|
||||
pow_data = undefined;
|
||||
});
|
||||
uppy.on('complete', (_) => {
|
||||
console.log(pow_data);
|
||||
if (selected_question === undefined) {
|
||||
data.cover_image = image_id;
|
||||
} else if (selected_question === -1) {
|
||||
|
||||
@@ -72,20 +72,22 @@
|
||||
custom_field = json.custom_field;
|
||||
}
|
||||
if (res.status === 404) {
|
||||
alertModal.set({
|
||||
/* alertModal.set({
|
||||
open: true,
|
||||
title: 'Game not found',
|
||||
body: 'The game pin you entered seems invalid.'
|
||||
});
|
||||
});*/
|
||||
alert('Game not found');
|
||||
game_pin = '';
|
||||
return;
|
||||
}
|
||||
if (res.status !== 200) {
|
||||
alertModal.set({
|
||||
/* alertModal.set({
|
||||
open: true,
|
||||
body: `Unknown error with response-code ${res.status}`,
|
||||
title: 'Unknown Error'
|
||||
});
|
||||
});*/
|
||||
alert('Unknown error');
|
||||
return;
|
||||
}
|
||||
};
|
||||
@@ -122,16 +124,13 @@
|
||||
if (import.meta.env.VITE_SENTRY !== null) {
|
||||
Sentry.captureException(e);
|
||||
}
|
||||
alertModal.set({
|
||||
/* alertModal.set({
|
||||
open: true,
|
||||
body: "The captcha failed, which is normal, but most of the time it's fixed by reloading!",
|
||||
title: 'Captcha failed'
|
||||
});
|
||||
alertModal.subscribe((data) => {
|
||||
if (!data.open) {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
});*/
|
||||
alert('Captcha failed!');
|
||||
window.location.reload();
|
||||
}
|
||||
} else if (import.meta.env.VITE_RECAPTCHA) {
|
||||
// eslint-disable-next-line no-undef
|
||||
|
||||
@@ -91,7 +91,8 @@
|
||||
{:else}
|
||||
<slot />
|
||||
{/if}
|
||||
{#if $alertModal.open ?? false}
|
||||
|
||||
<!--{#if $alertModal.open ?? false}
|
||||
<div
|
||||
class="fixed inset-0 h-screen w-screen bg-black z-30 bg-opacity-60 items-center justify-center content-center"
|
||||
class:hidden={!$alertModal.open}
|
||||
@@ -104,7 +105,7 @@
|
||||
bind:open={$alertModal.open}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}-->
|
||||
|
||||
<style lang="scss">
|
||||
:global(html:not(.dark)) {
|
||||
|
||||
@@ -37,19 +37,16 @@
|
||||
try {
|
||||
data = await res.json();
|
||||
} catch {
|
||||
alertModal.set({
|
||||
open: true,
|
||||
body: "This shouldn't happen. Please try again.",
|
||||
title: 'Unknown error'
|
||||
});
|
||||
alert("This shouldn't happen");
|
||||
window.location.reload();
|
||||
}
|
||||
if (data.detail === 'wrong credentials') {
|
||||
alertModal.set({
|
||||
/* alertModal.set({
|
||||
open: true,
|
||||
body: 'Please try again. Your email and or password were incorrect.',
|
||||
title: 'Wrong Credentials'
|
||||
});
|
||||
});*/
|
||||
alert('Wrong credentials');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -44,19 +44,21 @@
|
||||
try {
|
||||
data = await res.json();
|
||||
} catch {
|
||||
alertModal.set({
|
||||
/* alertModal.set({
|
||||
open: true,
|
||||
body: "This shouldn't happen. Please try again.",
|
||||
title: 'Unknown error'
|
||||
});
|
||||
});*/
|
||||
alert('Unknown error');
|
||||
window.location.reload();
|
||||
}
|
||||
if (data.detail === 'totp wrong') {
|
||||
alertModal.set({
|
||||
/* alertModal.set({
|
||||
open: true,
|
||||
body: 'Wrong Totp-Code. please try again.',
|
||||
title: 'Totp Error'
|
||||
});
|
||||
});*/
|
||||
alert('TOTP code was incorrect');
|
||||
totp = '';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,11 +24,12 @@
|
||||
asseResp = await startAuthentication(data);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
alertModal.set({
|
||||
/* alertModal.set({
|
||||
open: true,
|
||||
body: e,
|
||||
title: 'Unknown error'
|
||||
});
|
||||
});*/
|
||||
alert('Unknown error');
|
||||
isLoading = false;
|
||||
}
|
||||
const res = await fetch(
|
||||
@@ -51,19 +52,21 @@
|
||||
try {
|
||||
data = await res.json();
|
||||
} catch {
|
||||
alertModal.set({
|
||||
/* alertModal.set({
|
||||
open: true,
|
||||
body: "This shouldn't happen. Please try again.",
|
||||
title: 'Unknown error'
|
||||
});
|
||||
});*/
|
||||
alert('Unknown error');
|
||||
window.location.reload();
|
||||
}
|
||||
if (data.detail === 'webauthn failed') {
|
||||
alertModal.set({
|
||||
/* alertModal.set({
|
||||
open: true,
|
||||
body: 'Webauthn failed. Please try again.',
|
||||
title: 'Webauthn Error'
|
||||
});
|
||||
});*/
|
||||
alert('Webauthn failed');
|
||||
}
|
||||
}
|
||||
isLoading = false;
|
||||
|
||||
@@ -35,17 +35,19 @@
|
||||
if (res.status === 200) {
|
||||
window.location.href = '/dashboard';
|
||||
} else if (res.status === 400) {
|
||||
alertModal.set({
|
||||
/* alertModal.set({
|
||||
open: true,
|
||||
title: 'Import failed',
|
||||
body: "This quiz isn't (yet) supported!"
|
||||
});
|
||||
});*/
|
||||
alert("This quiz isn't (yet) supported!");
|
||||
} else {
|
||||
alertModal.set({
|
||||
/* alertModal.set({
|
||||
open: true,
|
||||
title: 'Import failed',
|
||||
body: 'Unknown error while importing the quiz!'
|
||||
});
|
||||
});*/
|
||||
alert('Import failed with unknown reason');
|
||||
}
|
||||
is_loading = false;
|
||||
};
|
||||
@@ -61,11 +63,12 @@
|
||||
if (res.status === 200) {
|
||||
window.location.href = '/dashboard';
|
||||
} else {
|
||||
alertModal.set({
|
||||
/* alertModal.set({
|
||||
open: true,
|
||||
title: 'Import failed',
|
||||
body: 'Something went wrong!'
|
||||
});
|
||||
});*/
|
||||
alert('Something went wrong!');
|
||||
}
|
||||
is_loading = false;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user