76 lines
2.9 KiB
Python
76 lines
2.9 KiB
Python
from ninja import Router, File, Form, Schema
|
|
from ninja.files import UploadedFile
|
|
from django.shortcuts import get_object_or_404
|
|
from django.conf import settings
|
|
from account.decorators import admin_required, super_required
|
|
from .models import Challenge, Tutorial, TaskAsset
|
|
|
|
router = Router()
|
|
|
|
|
|
class AssetOut(Schema):
|
|
name: str
|
|
url: str
|
|
|
|
|
|
def _asset_url(asset: TaskAsset) -> str:
|
|
return f"{settings.MEDIA_URL}{asset.file.name}"
|
|
|
|
|
|
# ── Challenge assets ──────────────────────────────────────────────────────────
|
|
|
|
@router.get("/challenge/{display}", response=list[AssetOut])
|
|
def list_challenge_assets(request, display: int):
|
|
challenge = get_object_or_404(Challenge, display=display)
|
|
return [AssetOut(name=a.name, url=_asset_url(a)) for a in challenge.assets.all()]
|
|
|
|
|
|
@router.post("/challenge/{display}", response=AssetOut)
|
|
@admin_required
|
|
def upload_challenge_asset(request, display: int, name: Form[str], file: File[UploadedFile]):
|
|
challenge = get_object_or_404(Challenge, display=display)
|
|
asset, _ = TaskAsset.objects.get_or_create(task=challenge.task_ptr, name=name)
|
|
if asset.file:
|
|
asset.file.delete(save=False)
|
|
asset.file.save(name, file, save=True)
|
|
return AssetOut(name=asset.name, url=_asset_url(asset))
|
|
|
|
|
|
@router.delete("/challenge/{display}/{name}")
|
|
@admin_required
|
|
def delete_challenge_asset(request, display: int, name: str):
|
|
challenge = get_object_or_404(Challenge, display=display)
|
|
asset = get_object_or_404(TaskAsset, task=challenge.task_ptr, name=name)
|
|
asset.file.delete(save=False)
|
|
asset.delete()
|
|
return {"message": "删除成功"}
|
|
|
|
|
|
# ── Tutorial assets ───────────────────────────────────────────────────────────
|
|
|
|
@router.get("/tutorial/{display}", response=list[AssetOut])
|
|
def list_tutorial_assets(request, display: int):
|
|
tutorial = get_object_or_404(Tutorial, display=display)
|
|
return [AssetOut(name=a.name, url=_asset_url(a)) for a in tutorial.assets.all()]
|
|
|
|
|
|
@router.post("/tutorial/{display}", response=AssetOut)
|
|
@super_required
|
|
def upload_tutorial_asset(request, display: int, name: Form[str], file: File[UploadedFile]):
|
|
tutorial = get_object_or_404(Tutorial, display=display)
|
|
asset, _ = TaskAsset.objects.get_or_create(task=tutorial.task_ptr, name=name)
|
|
if asset.file:
|
|
asset.file.delete(save=False)
|
|
asset.file.save(name, file, save=True)
|
|
return AssetOut(name=asset.name, url=_asset_url(asset))
|
|
|
|
|
|
@router.delete("/tutorial/{display}/{name}")
|
|
@super_required
|
|
def delete_tutorial_asset(request, display: int, name: str):
|
|
tutorial = get_object_or_404(Tutorial, display=display)
|
|
asset = get_object_or_404(TaskAsset, task=tutorial.task_ptr, name=name)
|
|
asset.file.delete(save=False)
|
|
asset.delete()
|
|
return {"message": "删除成功"}
|