Remove 'num_scratches' from platform endpoint (#1688)

This commit is contained in:
Mark Street
2025-09-29 09:19:15 +01:00
committed by GitHub
parent 560888d84f
commit 1f0dc00a1d
6 changed files with 81 additions and 20 deletions
+4
View File
@@ -12,6 +12,7 @@ from coreapp.views import (
scratch,
user,
search,
scratch_count,
)
router = DefaultRouter(trailing_slash=False)
@@ -39,6 +40,9 @@ urlpatterns = [
platform.single_platform,
name="platform-detail",
),
path(
"scratch-count", scratch_count.ScratchCountView.as_view(), name="scratch-count"
),
path("stats", stats.StatsDetail.as_view(), name="stats"),
path("user", user.CurrentUser.as_view(), name="current-user"),
path(
+2 -6
View File
@@ -73,15 +73,11 @@ class CompilerDetail(APIView):
}
@staticmethod
def platforms_json(
include_num_scratches: bool = False,
) -> Dict[str, Dict[str, object]]:
def platforms_json() -> Dict[str, Dict[str, object]]:
ret: Dict[str, Dict[str, object]] = {}
for platform in compilers.available_platforms():
ret[platform.id] = platform.to_json(
include_num_scratches=include_num_scratches,
)
ret[platform.id] = platform.to_json()
return ret
+1 -2
View File
@@ -32,7 +32,7 @@ class PlatformDetail(APIView):
@condition(last_modified_func=endpoint_updated)
def get(self, request: Request) -> Response:
return Response(CompilerDetail.platforms_json(include_num_scratches=False))
return Response(CompilerDetail.platforms_json())
@api_view(["GET"])
@@ -48,7 +48,6 @@ def single_platform(request: Request, id: str) -> Response:
return Response(
platform.to_json(
include_compilers=True,
include_num_scratches=True,
)
)
+47
View File
@@ -0,0 +1,47 @@
from django.utils.decorators import method_decorator
from django.utils.http import http_date, parse_http_date_safe
from django.utils.timezone import now
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.views import APIView
from ..decorators.cache import globally_cacheable
from ..models.scratch import Scratch
@method_decorator(
globally_cacheable(max_age=60, stale_while_revalidate=30), name="dispatch"
)
class ScratchCountView(APIView):
def get(self, request: Request) -> Response:
qs = Scratch.objects.all()
platform = request.query_params.get("platform")
compiler = request.query_params.get("compiler")
preset = request.query_params.get("preset")
if platform:
qs = qs.filter(platform=platform)
if compiler:
qs = qs.filter(compiler=compiler)
if preset:
qs = qs.filter(preset_id=preset)
latest_created = (
qs.order_by("-creation_time")
.values_list("creation_time", flat=True)
.first()
)
if latest_created is None:
latest_created = now()
if_modified_since = request.headers.get("If-Modified-Since")
if if_modified_since:
since_ts = parse_http_date_safe(if_modified_since)
if since_ts and latest_created.timestamp() <= since_ts:
return Response(status=304)
resp = Response({"num_scratches": qs.count()})
resp["Last-Modified"] = http_date(latest_created.timestamp())
return resp
@@ -6,13 +6,13 @@ import { PlatformIcon } from "@/components/PlatformSelect/PlatformIcon";
import ScratchList from "@/components/ScratchList";
import { ScratchItemPlatformList } from "@/components/ScratchItem";
import { get } from "@/lib/api/request";
import type { PlatformMetadata } from "@/lib/api/types";
import type { PlatformBase, ScratchCount } from "@/lib/api/types";
export async function generateMetadata(props: {
params: Promise<{ id: number }>;
}): Promise<Metadata> {
const params = await props.params;
let platform: PlatformMetadata;
let platform: PlatformBase;
try {
platform = await get(`/platform/${params.id}`);
@@ -24,13 +24,21 @@ export async function generateMetadata(props: {
return notFound();
}
let scratch_count: ScratchCount;
try {
scratch_count = await get(`/scratch-count?platform=${params.id}`);
} catch (error) {
console.error(error);
}
let description = "There ";
description += platform.num_scratches === 1 ? "is " : "are ";
description += scratch_count.num_scratches === 1 ? "is " : "are ";
description +=
platform.num_scratches === 0
scratch_count.num_scratches === 0
? "currently no "
: `${platform.num_scratches.toLocaleString("en-US")} `;
description += platform.num_scratches === 1 ? "scratch " : "scratches ";
: `${scratch_count.num_scratches.toLocaleString("en-US")} `;
description +=
scratch_count.num_scratches === 1 ? "scratch " : "scratches ";
description += "for this platform.";
return {
@@ -44,7 +52,7 @@ export async function generateMetadata(props: {
export default async function Page(props: { params: Promise<{ id: number }> }) {
const params = await props.params;
let platform: PlatformMetadata;
let platform: PlatformBase;
try {
platform = await get(`/platform/${params.id}`);
} catch (error) {
@@ -55,6 +63,13 @@ export default async function Page(props: { params: Promise<{ id: number }> }) {
return notFound();
}
let scratch_count: ScratchCount;
try {
scratch_count = await get(`/scratch-count?platform=${params.id}`);
} catch (error) {
console.error(error);
}
return (
<main className="mx-auto w-full max-w-3xl p-4">
<div className="flex items-center gap-2 font-medium text-2xl">
@@ -68,7 +83,7 @@ export default async function Page(props: { params: Promise<{ id: number }> }) {
url={`/scratch?platform=${platform.id}&page_size=20`}
item={ScratchItemPlatformList}
isSortable={true}
title={`Scratches (${platform.num_scratches.toLocaleString("en-US")})`}
title={`Scratches (${scratch_count.num_scratches.toLocaleString("en-US")})`}
/>
</section>
</main>
+4 -4
View File
@@ -145,6 +145,10 @@ export type Preset = TersePreset & {
num_scratches: number;
};
export type ScratchCount = {
num_scratches: number;
};
export type CompilerBase = {
id: string;
};
@@ -163,10 +167,6 @@ export interface PlatformBase {
has_decompiler: boolean;
}
export interface PlatformMetadata extends PlatformBase {
num_scratches: number;
}
export interface Platform extends PlatformBase {
compilers: string[];
}