File size: 1,814 Bytes
1c0c94d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// Single source for all HTTP. Root-relative paths work in dev (Vite proxy) and prod (same origin).

async function getJSON(url) {
  const r = await fetch(url)
  if (!r.ok) throw new Error(`${r.status} ${r.statusText}`)
  return r.json()
}

async function postJSON(url, body) {
  const r = await fetch(url, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  })
  if (!r.ok) throw new Error(`${r.status} ${r.statusText}`)
  return r.json()
}

export const getRuntime = () => getJSON('/runtime')
export const getAnalytics = () => getJSON('/analytics')
export const getImage = (id) => getJSON(`/images/${id}`)
export const getViolation = (id) => getJSON(`/violations/${id}`)
export const getReviewQueue = () => getJSON('/review-queue')

export const uploadImage = async (file, cameraId) => {
  const fd = new FormData()
  fd.append('file', file)
  const qs = cameraId ? `?camera_id=${encodeURIComponent(cameraId)}` : ''
  const r = await fetch(`/images${qs}`, { method: 'POST', body: fd })
  if (!r.ok) throw new Error((await r.text()) || `${r.status}`)
  return r.json()
}

export const listViolations = (params = {}) => {
  const qs = new URLSearchParams()
  for (const [k, v] of Object.entries(params)) if (v) qs.set(k, v)
  return getJSON(`/violations?${qs.toString()}`)
}

export const reviewViolation = (id, decision, reviewer, note) =>
  postJSON(`/violations/${id}/review`, { decision, reviewer, note })

// Poll an image until processing finishes (or 90 ticks).
export const pollImage = async (id, onTick) => {
  for (let i = 0; i < 90; i++) {
    const d = await getImage(id)
    onTick?.(d)
    if (['completed', 'failed', 'undeterminable'].includes(d.status)) return d
    await new Promise((r) => setTimeout(r, 1200))
  }
  return getImage(id)
}