Compare commits

..

No commits in common. "d2a9dbe4a423f7e22809cf173383968804d32d55" and "eb1eed852bf1d9eb5471246df272b719862cf0e7" have entirely different histories.

131 changed files with 114 additions and 2439 deletions

View File

@ -1,12 +1,12 @@
from collections import defaultdict from django.http.request import HttpRequest
from django.http import HttpRequest
from ninja import Router from ninja import Router
from collections import defaultdict
from accounts.models import CustomUser from accounts.models import CustomUser
from animations.schemas import RankingSchema from animations.schemas import RankingSchema
from submissions.models import PuzzleResponse, SteamCollectionItem from submissions.models import PuzzleResponse, SteamCollectionItem
router = Router() router = Router()
@ -26,9 +26,7 @@ def results(request: HttpRequest) -> dict:
ranking = {} ranking = {}
for puzzle_id, responses in responses_by_puzzleid.items(): for puzzle_id, responses in responses_by_puzzleid.items():
ranking[puzzle_id] = sorted( ranking[puzzle_id] = sorted(responses, key=lambda x: x.rank_points)
responses, key=lambda x: (x.rank_points is None, x.rank_points or 0)
)
return { return {
"users": CustomUser.objects.filter(pk__in=responses_by_userid.keys()), "users": CustomUser.objects.filter(pk__in=responses_by_userid.keys()),

View File

@ -14,8 +14,8 @@ class PuzzleResponseRankingOut(ModelSchema):
"updated_at", "updated_at",
] ]
points: int | None = None points: int
rank_points: int | None = None rank_points: int
puzzle_user_rank: int puzzle_user_rank: int
user_response_rank: int user_response_rank: int
@ -30,13 +30,8 @@ class PuzzleResponseRankingOut(ModelSchema):
return obj.submission.user.id return obj.submission.user.id
class UserDisplayOut(Schema):
id: int
username: str
class RankingSchema(Schema): class RankingSchema(Schema):
users: list[UserDisplayOut] users: list[UserInfoOut]
puzzles: list[SteamCollectionItemOut] puzzles: list[SteamCollectionItemOut]
responses_by_userid: dict[int, list[PuzzleResponseRankingOut]] responses_by_userid: dict[int, list[PuzzleResponseRankingOut]]
ranking_by_puzzle: dict[int, list[PuzzleResponseRankingOut]] ranking_by_puzzle: dict[int, list[PuzzleResponseRankingOut]]

View File

@ -7,7 +7,7 @@ import sys
def main(): def main():
"""Run administrative tasks.""" """Run administrative tasks."""
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "polylan_submitter.settings") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "opus_submitter.settings")
try: try:
from django.core.management import execute_from_command_line from django.core.management import execute_from_command_line
except ImportError as exc: except ImportError as exc:

View File

@ -2,18 +2,15 @@ from ninja import NinjaAPI
from submissions.api import router as submissions_router from submissions.api import router as submissions_router
from submissions.schemas import UserInfoOut from submissions.schemas import UserInfoOut
from animations.api import router as results_router from animations.api import router as results_router
from noita.api import router as noita_router
# Create the main API instance # Create the main API instance
api = NinjaAPI( api = NinjaAPI(
title="PolyLAN Submission API", title="Opus Magnum Submission API",
version="1.0.0", version="1.0.0",
description="""API for managing Opus Magnum puzzle submissions, and Noita runs. description="""API for managing Opus Magnum puzzle submissions.
The Opus Magnum Submission API allows clients to upload, manage, validate, and review puzzle solution submissions for the Opus Magnum puzzle game community. The Opus Magnum Submission API allows clients to upload, manage, validate, and review puzzle solution submissions for the Opus Magnum puzzle game community.
It provides features for user authentication, puzzle listing, submission uploads, automated and manual OCR validation, and administrative workflows. It provides features for user authentication, puzzle listing, submission uploads, automated and manual OCR validation, and administrative workflows.
The Noita Submission API allows clients to upload the result of the log file of the PolyLAN noita mod. It parses the output, and store each objectiv made by the user.
""", """,
openapi_extra={ openapi_extra={
"info": { "info": {
@ -31,14 +28,30 @@ The Noita Submission API allows clients to upload the result of the log file of
# Include the submissions router # Include the submissions router
api.add_router("/submissions/", submissions_router, tags=["submissions"]) api.add_router("/submissions/", submissions_router, tags=["submissions"])
api.add_router("/results/", results_router, tags=["results"]) api.add_router("/results/", results_router, tags=["results"])
api.add_router("/noita/", noita_router, tags=["noita"])
# Health check endpoint # Health check endpoint
@api.get("/health") @api.get("/health")
def health_check(request): def health_check(request):
"""Health check endpoint""" """Health check endpoint"""
return {"status": "healthy", "service": "polylan-submitter-api"} return {"status": "healthy", "service": "opus-magnum-api"}
# API info endpoint
@api.get("/info")
def api_info(request):
"""Get API information"""
return {
"name": "Opus Magnum Submission API",
"version": "1.0.0",
"description": "API for managing puzzle submissions with OCR validation",
"features": [
"Multi-puzzle submissions",
"OCR validation",
"Manual validation workflow",
"Admin validation tools",
],
}
# User info endpoint # User info endpoint

View File

@ -1,5 +1,5 @@
""" """
ASGI config for polylan_submitter project. ASGI config for opus_submitter project.
It exposes the ASGI callable as a module-level variable named ``application``. It exposes the ASGI callable as a module-level variable named ``application``.
@ -11,6 +11,6 @@ import os
from django.core.asgi import get_asgi_application from django.core.asgi import get_asgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "polylan_submitter.settings") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "opus_submitter.settings")
application = get_asgi_application() application = get_asgi_application()

View File

@ -1,5 +1,5 @@
""" """
Django settings for polylan_submitter project. Django settings for opus_submitter project.
Generated by 'django-admin startproject' using Django 5.2.7. Generated by 'django-admin startproject' using Django 5.2.7.
@ -42,7 +42,6 @@ INSTALLED_APPS = [
"accounts", "accounts",
"animations", "animations",
"submissions", "submissions",
"noita",
] ]
MIDDLEWARE = [ MIDDLEWARE = [
@ -56,7 +55,7 @@ MIDDLEWARE = [
"django.middleware.clickjacking.XFrameOptionsMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware",
] ]
ROOT_URLCONF = "polylan_submitter.urls" ROOT_URLCONF = "opus_submitter.urls"
TEMPLATES = [ TEMPLATES = [
{ {
@ -73,7 +72,7 @@ TEMPLATES = [
}, },
] ]
WSGI_APPLICATION = "polylan_submitter.wsgi.application" WSGI_APPLICATION = "opus_submitter.wsgi.application"
# Database # Database
@ -178,4 +177,4 @@ STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static_source/vite"), os.path.join(BASE_DIR, "static_source/vite"),
] ]
from polylan_submitter.settingsLocal import * # noqa from opus_submitter.settingsLocal import * # noqa

View File

@ -1,5 +1,5 @@
""" """
URL configuration for polylan_submitter project. URL configuration for opus_submitter project.
The `urlpatterns` list routes URLs to views. For more information please see: The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/5.2/topics/http/urls/ https://docs.djangoproject.com/en/5.2/topics/http/urls/
@ -28,34 +28,22 @@ from .api import api
@login_required @login_required
def home(request: HttpRequest): def home(request: HttpRequest):
return render(request, "home.html", {})
@login_required
def opus_magnum_home(request: HttpRequest):
from submissions.models import SteamCollection from submissions.models import SteamCollection
return render( return render(
request, request,
"opus-magnum.html", "index.html",
{ {
"collection": SteamCollection.objects.filter(is_active=True).last(), "collection": SteamCollection.objects.filter(is_active=True).last(),
}, },
) )
@login_required
def noita_home(request: HttpRequest):
return render(request, "noita.html", {})
urlpatterns = [ urlpatterns = [
path("admin/", admin.site.urls), path("admin/", admin.site.urls),
path("cas/login/", SimpleCASLoginView.as_view(), name="cas_ng_login"), path("cas/login/", SimpleCASLoginView.as_view(), name="cas_ng_login"),
path("cas/logout/", SimpleCASLogoutView.as_view(), name="cas_ng_logout"), path("cas/logout/", SimpleCASLogoutView.as_view(), name="cas_ng_logout"),
path("api/", api.urls), path("api/", api.urls),
path("opus-magnum", opus_magnum_home, name="opus-magnum.home"),
path("noita", noita_home, name="noita.home"),
path("", home, name="home"), path("", home, name="home"),
] ]

View File

@ -1,5 +1,5 @@
""" """
WSGI config for polylan_submitter project. WSGI config for opus_submitter project.
It exposes the WSGI callable as a module-level variable named ``application``. It exposes the WSGI callable as a module-level variable named ``application``.
@ -11,6 +11,6 @@ import os
from django.core.wsgi import get_wsgi_application from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "polylan_submitter.settings") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "opus_submitter.settings")
application = get_wsgi_application() application = get_wsgi_application()

View File

@ -1,5 +1,5 @@
{ {
"name": "polylan_submitter", "name": "opus_submitter",
"private": true, "private": true,
"version": "0.0.0", "version": "0.0.0",
"type": "module", "type": "module",

View File

@ -10,7 +10,7 @@ importers:
dependencies: dependencies:
'@tailwindcss/vite': '@tailwindcss/vite':
specifier: ^4.1.16 specifier: ^4.1.16
version: 4.1.16(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.4)) version: 4.1.16(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2))
'@tanstack/vue-table': '@tanstack/vue-table':
specifier: ^8.21.3 specifier: ^8.21.3
version: 8.21.3(vue@3.5.22(typescript@5.9.3)) version: 8.21.3(vue@3.5.22(typescript@5.9.3))
@ -41,7 +41,7 @@ importers:
version: 24.9.2 version: 24.9.2
'@vitejs/plugin-vue': '@vitejs/plugin-vue':
specifier: ^6.0.1 specifier: ^6.0.1
version: 6.0.1(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.4))(vue@3.5.22(typescript@5.9.3)) version: 6.0.1(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.22(typescript@5.9.3))
'@vue/tsconfig': '@vue/tsconfig':
specifier: ^0.8.1 specifier: ^0.8.1
version: 0.8.1(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3)) version: 0.8.1(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))
@ -53,7 +53,7 @@ importers:
version: 5.9.3 version: 5.9.3
vite: vite:
specifier: ^7.1.7 specifier: ^7.1.7
version: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.4) version: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)
vue-tsc: vue-tsc:
specifier: ^3.1.0 specifier: ^3.1.0
version: 3.1.2(typescript@5.9.3) version: 3.1.2(typescript@5.9.3)
@ -880,11 +880,6 @@ packages:
whatwg-url@5.0.0: whatwg-url@5.0.0:
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
yaml@2.8.4:
resolution: {integrity: sha512-ml/JPOj9fOQK8RNnWojA67GbZ0ApXAUlN2UQclwv2eVgTgn7O9gg9o7paZWKMp4g0H3nTLtS9LVzhkpOFIKzog==}
engines: {node: '>= 14.6'}
hasBin: true
zlibjs@0.3.1: zlibjs@0.3.1:
resolution: {integrity: sha512-+J9RrgTKOmlxFSDHo0pI1xM6BLVUv+o0ZT9ANtCxGkjIVCCUdx9alUF8Gm+dGLKbkkkidWIHFDZHDMpfITt4+w==} resolution: {integrity: sha512-+J9RrgTKOmlxFSDHo0pI1xM6BLVUv+o0ZT9ANtCxGkjIVCCUdx9alUF8Gm+dGLKbkkkidWIHFDZHDMpfITt4+w==}
@ -1131,12 +1126,12 @@ snapshots:
'@tailwindcss/oxide-win32-arm64-msvc': 4.1.16 '@tailwindcss/oxide-win32-arm64-msvc': 4.1.16
'@tailwindcss/oxide-win32-x64-msvc': 4.1.16 '@tailwindcss/oxide-win32-x64-msvc': 4.1.16
'@tailwindcss/vite@4.1.16(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.4))': '@tailwindcss/vite@4.1.16(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2))':
dependencies: dependencies:
'@tailwindcss/node': 4.1.16 '@tailwindcss/node': 4.1.16
'@tailwindcss/oxide': 4.1.16 '@tailwindcss/oxide': 4.1.16
tailwindcss: 4.1.16 tailwindcss: 4.1.16
vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.4) vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)
'@tanstack/table-core@8.21.3': {} '@tanstack/table-core@8.21.3': {}
@ -1153,10 +1148,10 @@ snapshots:
'@types/web-bluetooth@0.0.21': {} '@types/web-bluetooth@0.0.21': {}
'@vitejs/plugin-vue@6.0.1(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.4))(vue@3.5.22(typescript@5.9.3))': '@vitejs/plugin-vue@6.0.1(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.22(typescript@5.9.3))':
dependencies: dependencies:
'@rolldown/pluginutils': 1.0.0-beta.29 '@rolldown/pluginutils': 1.0.0-beta.29
vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.4) vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)
vue: 3.5.22(typescript@5.9.3) vue: 3.5.22(typescript@5.9.3)
'@volar/language-core@2.4.23': '@volar/language-core@2.4.23':
@ -1508,7 +1503,7 @@ snapshots:
undici-types@7.16.0: {} undici-types@7.16.0: {}
vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.4): vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2):
dependencies: dependencies:
esbuild: 0.25.11 esbuild: 0.25.11
fdir: 6.5.0(picomatch@4.0.3) fdir: 6.5.0(picomatch@4.0.3)
@ -1521,7 +1516,6 @@ snapshots:
fsevents: 2.3.3 fsevents: 2.3.3
jiti: 2.6.1 jiti: 2.6.1
lightningcss: 1.30.2 lightningcss: 1.30.2
yaml: 2.8.4
vscode-uri@3.1.0: {} vscode-uri@3.1.0: {}
@ -1550,7 +1544,4 @@ snapshots:
tr46: 0.0.3 tr46: 0.0.3
webidl-conversions: 3.0.1 webidl-conversions: 3.0.1
yaml@2.8.4:
optional: true
zlibjs@0.3.1: {} zlibjs@0.3.1: {}

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -108,24 +108,17 @@ const findPuzzleByName = (ocrPuzzleName: string) => {
const reloadPage = () => { const reloadPage = () => {
window.location.reload(); window.location.reload();
}; };
const goHome = () => {
window.location.href = "/";
};
</script> </script>
<template> <template>
<div class="min-h-screen bg-base-200"> <div class="min-h-screen bg-base-200">
<!-- Header --> <!-- Header -->
<div class="navbar bg-base-100 shadow-lg"> <div class="navbar bg-base-100 shadow-lg">
<div class="container mx-auto w-full flex items-center gap-4"> <div class="container mx-auto">
<button @click="goHome" class="btn btn-primary btn-sm"> <div class="flex-1">
<i class="mdi mdi-arrow-left"></i>
Back
</button>
<h1 class="text-xl font-bold">Opus Magnum Puzzle Submitter</h1> <h1 class="text-xl font-bold">Opus Magnum Puzzle Submitter</h1>
<div class="flex-1"></div> </div>
<div class="flex items-center gap-4"> <div class="flex items-start justify-between">
<div <div
v-if="userInfo?.is_authenticated" v-if="userInfo?.is_authenticated"
class="flex items-center gap-2" class="flex items-center gap-2"
@ -140,11 +133,15 @@ const goHome = () => {
</div> </div>
</div> </div>
<div v-else class="text-sm text-base-content/70">Not logged in</div> <div v-else class="text-sm text-base-content/70">Not logged in</div>
<div class="flex flex-col items-end gap-2">
<a href="/api/docs" class="btn btn-xs">API docs</a> <a href="/api/docs" class="btn btn-xs">API docs</a>
</div>
<div class="flex flex-col items-end gap-2">
<a href="/admin" class="btn btn-xs btn-warning">Admin panel</a> <a href="/admin" class="btn btn-xs btn-warning">Admin panel</a>
</div> </div>
</div> </div>
</div> </div>
</div>
<!-- Main Content --> <!-- Main Content -->
<div class="container mx-auto px-4 py-8"> <div class="container mx-auto px-4 py-8">

View File

@ -0,0 +1,12 @@
<script setup lang="ts"></script>
<template>
<div class="mb-8">
<div class="card bg-base-100 shadow-lg">
<div class="card-body">
<h2 class="card-title text-2xl">General Results</h2>
<div class="flex flex-wrap gap-4 mt-4">TODO :)</div>
</div>
</div>
</div>
</template>

View File

@ -1,11 +1,11 @@
import { createApp } from 'vue' import { createApp } from 'vue'
import OpusMagnum from '@/OpusMagnum.vue' import App from '@/App.vue'
import { pinia } from '@/stores' import { pinia } from '@/stores'
import '@/style.css' import '@/style.css'
// const app = createApp(App) // const app = createApp(App)
const selector = "#app" const selector = "#app"
const mountData = document.querySelector<HTMLElement>(selector) const mountData = document.querySelector<HTMLElement>(selector)
const app = createApp(OpusMagnum, { ...mountData?.dataset }) const app = createApp(App, { ...mountData?.dataset })
app.use(pinia) app.use(pinia)
app.mount(selector) app.mount(selector)

View File

@ -0,0 +1,33 @@
{
"node_modules/.pnpm/@mdi+font@7.4.47/node_modules/@mdi/font/fonts/materialdesignicons-webfont.eot": {
"file": "assets/materialdesignicons-webfont-CSr8KVlo.eot",
"src": "node_modules/.pnpm/@mdi+font@7.4.47/node_modules/@mdi/font/fonts/materialdesignicons-webfont.eot"
},
"node_modules/.pnpm/@mdi+font@7.4.47/node_modules/@mdi/font/fonts/materialdesignicons-webfont.ttf": {
"file": "assets/materialdesignicons-webfont-B7mPwVP_.ttf",
"src": "node_modules/.pnpm/@mdi+font@7.4.47/node_modules/@mdi/font/fonts/materialdesignicons-webfont.ttf"
},
"node_modules/.pnpm/@mdi+font@7.4.47/node_modules/@mdi/font/fonts/materialdesignicons-webfont.woff": {
"file": "assets/materialdesignicons-webfont-PXm3-2wK.woff",
"src": "node_modules/.pnpm/@mdi+font@7.4.47/node_modules/@mdi/font/fonts/materialdesignicons-webfont.woff"
},
"node_modules/.pnpm/@mdi+font@7.4.47/node_modules/@mdi/font/fonts/materialdesignicons-webfont.woff2": {
"file": "assets/materialdesignicons-webfont-Dp5v-WZN.woff2",
"src": "node_modules/.pnpm/@mdi+font@7.4.47/node_modules/@mdi/font/fonts/materialdesignicons-webfont.woff2"
},
"src/main.ts": {
"file": "assets/main-CNlI4PW6.js",
"name": "main",
"src": "src/main.ts",
"isEntry": true,
"css": [
"assets/main-HDjkw-xK.css"
],
"assets": [
"assets/materialdesignicons-webfont-CSr8KVlo.eot",
"assets/materialdesignicons-webfont-Dp5v-WZN.woff2",
"assets/materialdesignicons-webfont-PXm3-2wK.woff",
"assets/materialdesignicons-webfont-B7mPwVP_.ttf"
]
}
}

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -7,7 +7,7 @@ from django.utils import timezone
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from typing import List from typing import List
from submissions.utils import verify_and_validate_ocr_date_for_submission from opus_submitter.submissions.utils import verify_and_validate_ocr_date_for_submission
from .models import Submission, PuzzleResponse, SubmissionFile, SteamCollectionItem from .models import Submission, PuzzleResponse, SubmissionFile, SteamCollectionItem
from .schemas import ( from .schemas import (

View File

@ -5,13 +5,11 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{% block title %}{% endblock %}</title> <title>Opus Magnum Puzzle Submitter</title>
{% if debug %}{% vite_hmr_client %}{% endif %} {% vite_hmr_client %}
{% block head %} {% vite_asset 'src/main.ts' %}
{% endblock %}
</head> </head>
<body> <body>
{% block content %} <div id="app" data-collection-title="{{ collection.title }}" data-collection-url="{{ collection.url }}" data-collection-description="{{ collection.description }}"></div>
{% endblock %}
</body> </body>
</html> </html>

View File

@ -21,7 +21,7 @@ export default defineConfig({
outDir: resolve("./static_source/vite"), outDir: resolve("./static_source/vite"),
rollupOptions: { rollupOptions: {
input: input:
{ opus_magnum: resolve('./src/opus-magnum.ts') } { main: resolve('./src/main.ts') }
} }
}, },
}) })

Some files were not shown because too many files have changed in this diff Show More