Use x-summary endpoint for points
This endpoint includes points from the old tasks in series - resolves #44
This commit is contained in:
parent
d77686e6f0
commit
e2b6bdc319
6 changed files with 36 additions and 58 deletions
|
@ -191,7 +191,7 @@
|
|||
return;
|
||||
}
|
||||
const y = prompt("Který ročník (číslo 26...X)");
|
||||
await refreshTaskStatuses([`${y}-Z1-1`]);
|
||||
await refreshTaskStatuses();
|
||||
const newTasks = Array.from($taskStatuses.values()).filter(
|
||||
(t) =>
|
||||
t.id.startsWith(y + "-") &&
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<script lang="ts">
|
||||
import { isLoggedIn, parseTaskId } from "./ksp-task-grabber";
|
||||
import type { TaskStatus } from "./ksp-task-grabber";
|
||||
import type { TaskSubmitStatus, SubtaskSubmitStatus } from './ksp-submit-api'
|
||||
import type { TaskSubmitStatus, SubtaskSubmitStatus, TaskStatus } from './ksp-submit-api'
|
||||
import * as api from './ksp-submit-api'
|
||||
import { taskStatuses, refresh as refreshTaskStatus } from './task-status-cache'
|
||||
import * as s from 'svelte'
|
||||
|
@ -164,7 +163,7 @@
|
|||
|
||||
async function upload(file: File) {
|
||||
const x = await api.submit(id, uploadSubtaskId!, file)
|
||||
refreshTaskStatus([id])
|
||||
refreshTaskStatus()
|
||||
const subtasks = [...task.subtasks]
|
||||
subtasks[subtasks.findIndex(s => s.id == x.id)] = x
|
||||
task = { ...task, subtasks }
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<script lang="ts">
|
||||
import type { TasksFile } from "./tasks";
|
||||
import { refresh } from './task-status-cache'
|
||||
|
||||
export let promise: Promise<TasksFile>;
|
||||
|
||||
|
@ -9,14 +8,12 @@
|
|||
let err: any | null = null;
|
||||
promise.then(
|
||||
(d) => {
|
||||
refresh(d.tasks.map(t => t.id))
|
||||
data = d;
|
||||
},
|
||||
(e) => {
|
||||
err = e;
|
||||
}
|
||||
)
|
||||
|
||||
</script>
|
||||
|
||||
{#if data == null && err == null}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { fetchHtml } from "./ksp-task-grabber";
|
||||
import { fetchHtml, isLoggedIn } from "./ksp-task-grabber";
|
||||
|
||||
let apitoken : string | null = null
|
||||
|
||||
|
@ -85,3 +85,28 @@ export async function submit(id: string, subtask: string, uploadedData: string |
|
|||
]
|
||||
})
|
||||
}
|
||||
export type TaskStatus = {
|
||||
id: string
|
||||
name: string
|
||||
submitted: boolean
|
||||
solved: boolean
|
||||
points: number
|
||||
maxPoints: number
|
||||
}
|
||||
|
||||
export async function grabTaskSummary(): Promise<Map<string, TaskStatus>> {
|
||||
if (!isLoggedIn()) throw new Error()
|
||||
|
||||
const results = await requestJson(`/api/tasks/x-summary`) as { tasks: TaskSubmitStatus[] }
|
||||
|
||||
function mapId(id: string) {
|
||||
if (id.startsWith("cviciste/"))
|
||||
return id.substr("cviciste/".length)
|
||||
else
|
||||
return id
|
||||
}
|
||||
|
||||
return new Map<string, TaskStatus>(
|
||||
results.tasks.map(r => [mapId(r.id), { id: mapId(r.id), maxPoints: r.max_points, name: r.name, points: r.points, solved: r.points > r.max_points - 0.001, submitted: r.points > 0 }])
|
||||
)
|
||||
}
|
||||
|
|
|
@ -14,16 +14,6 @@ type TaskLocation = {
|
|||
startElement: string
|
||||
}
|
||||
|
||||
export type TaskStatus = {
|
||||
id: string
|
||||
name: string
|
||||
submitted: boolean
|
||||
solved: boolean
|
||||
points: number
|
||||
maxPoints: number
|
||||
type: string
|
||||
}
|
||||
|
||||
function fixAllLinks(e: any) {
|
||||
if (typeof e.src == "string") {
|
||||
e.src = e.src
|
||||
|
@ -150,27 +140,6 @@ function parseTask(startElementId: string, doc: HTMLDocument): TaskAssignmentDat
|
|||
}
|
||||
}
|
||||
|
||||
function parseTaskStatuses(doc: HTMLDocument): TaskStatus[] {
|
||||
const rows = Array.from(doc.querySelectorAll("table.zs-tasklist tr")).slice(1) as HTMLTableRowElement[]
|
||||
return rows.map(r => {
|
||||
const submitted = !r.classList.contains("zs-unsubmitted")
|
||||
const id = r.cells[0].textContent!.trim()
|
||||
const type = r.cells[1].textContent!.trim()
|
||||
const name = r.cells[2].textContent!.trim()
|
||||
const pointsStr = r.cells[4].textContent!.trim()
|
||||
const pointsMatch = /((–|\.|\d)+) *\/ *(\d+)/.exec(pointsStr)
|
||||
if (!pointsMatch) throw new Error()
|
||||
let points = +pointsMatch[1]
|
||||
// points was a dash, means 0
|
||||
if (isNaN(points)) {
|
||||
points = 0
|
||||
}
|
||||
const maxPoints = +pointsMatch[3]
|
||||
const solved = r.classList.contains("zs-submitted")
|
||||
return { id, name, submitted, type, points, maxPoints, solved }
|
||||
})
|
||||
}
|
||||
|
||||
export async function fetchHtml(url: string) {
|
||||
const r = await fetch(url, { headers: { "Accept": "text/html,application/xhtml+xml" } })
|
||||
if (r.status >= 400) {
|
||||
|
@ -196,21 +165,6 @@ export function isLoggedIn(): boolean {
|
|||
return !!document.head.querySelector("meta[name=x-ksp-uid]")
|
||||
}
|
||||
|
||||
export async function grabTaskStates(kspIds: string[]): Promise<Map<string, TaskStatus>> {
|
||||
if (!isLoggedIn()) throw new Error()
|
||||
|
||||
const ids = new Set<string>(kspIds.map(parseTaskId).filter(t => t != null).map(t => t!.rocnik))
|
||||
const results = await Promise.all(Array.from(ids.keys()).map(async (rocnik) => {
|
||||
const html = await fetchHtml(`/cviciste/?year=${rocnik}`)
|
||||
return parseTaskStatuses(html)
|
||||
}))
|
||||
|
||||
return new Map<string, TaskStatus>(
|
||||
([] as TaskStatus[]).concat(...results)
|
||||
.map(r => [r.id, r])
|
||||
)
|
||||
}
|
||||
|
||||
export async function grabAssignment(id: string): Promise<TaskAssignmentData> {
|
||||
return await loadTask(getLocation(id, false))
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { grabTaskStates, isLoggedIn} from "./ksp-task-grabber"
|
||||
import type { TaskStatus } from "./ksp-task-grabber"
|
||||
import { isLoggedIn } from "./ksp-task-grabber"
|
||||
import { grabTaskSummary } from './ksp-submit-api'
|
||||
import type { TaskStatus } from "./ksp-submit-api"
|
||||
import { readable } from 'svelte/store';
|
||||
|
||||
let writeFn: (value: Map<string, TaskStatus>) => void = null!;
|
||||
|
@ -14,12 +15,14 @@ export const taskStatuses = readable(lastVal, write => {
|
|||
writeFn = v => { lastVal = v; write(v); }
|
||||
})
|
||||
|
||||
export function refresh(ids: string[]) {
|
||||
export function refresh() {
|
||||
if (!isLoggedIn()) return;
|
||||
|
||||
return grabTaskStates(ids).then(t => {
|
||||
return grabTaskSummary().then(t => {
|
||||
const tt = Array.from(t.entries())
|
||||
writeFn(new Map(Array.from(lastVal.entries()).concat(tt)))
|
||||
localStorage.setItem("taskStatuses-cache", JSON.stringify(tt))
|
||||
})
|
||||
}
|
||||
|
||||
refresh()
|
||||
|
|
Reference in a new issue