nightly - 2025-09-23

This commit is contained in:
2025-09-23 22:20:53 -04:00
parent cbcf43aee1
commit fc2d95d465
6 changed files with 147 additions and 4 deletions

View File

@@ -4,6 +4,7 @@ from fastapi import FastAPI
from sys import argv from sys import argv
from routers.prefixes import prefix_router from routers.prefixes import prefix_router
from routers.tickets import ticket_router
if argv[1] == "run": if argv[1] == "run":
app = FastAPI(title="TAM3 API Server", docs_url=None, redoc_url=None) app = FastAPI(title="TAM3 API Server", docs_url=None, redoc_url=None)
@@ -11,3 +12,4 @@ else:
app = FastAPI(title="TAM3 API Server") app = FastAPI(title="TAM3 API Server")
app.include_router(prefix_router) app.include_router(prefix_router)
app.include_router(ticket_router)

40
api/repos/tickets.py Normal file
View File

@@ -0,0 +1,40 @@
from dataclasses import dataclass
from .template import Repo
@dataclass
class Ticket:
prefix: str
t_id: int
first_name: str = ""
last_name: str = ""
phone_number: str = ""
preference: str = "CALL"
changed: bool = False
class TicketRepo(Repo):
def get_prefix_one(self, prefix: str, t_id: int):
self.cur.execute("SELECT * FROM tickets WHERE prefix = %s AND t_id = %s", (prefix, t_id))
result = self.cur.fetchone()
if not result:
return Ticket(prefix=prefix, t_id=t_id)
return Ticket(*result)
def get_prefix_range(self, prefix: str, t_from: int, t_to: int):
r_dict = {i: Ticket(prefix=prefix, t_id=i) for i in range(t_from, t_to+1)}
self.cur.execute("SELECT * FROM tickets WHERE prefix = %s AND t_id BETWEEN %s AND %s", (prefix, t_from, t_to))
results = self.cur.fetchall()
for r in results:
r_dict[r[1]] = Ticket(*r)
return list(r_dict.values())
def get_prefix_all(self, prefix: str):
self.cur.execute("SELECT * FROM tickets WHERE prefix = %s", (prefix,))
results = self.cur.fetchall()
return [Ticket(*r) for r in results]
def get_all(self):
self.cur.execute("SELECT * FROM tickets")
results = self.cur.fetchall()
return [Ticket(*r) for r in results]
def post_list(self, tickets: list[Ticket]):
for t in tickets:
self.cur.execute("REPLACE INTO tickets VALUES (%s, %s, %s, %s, %s, %s)", (t.prefix, t.t_id, t.first_name, t.last_name, t.phone_number, t.preference))
self.conn.commit()
return {"detail": "Tickets posted successfully."}

View File

@@ -1,26 +1,36 @@
from fastapi import APIRouter from fastapi import APIRouter
from repos.api_keys import ApiKeyRepo
from repos.prefixes import Prefix, PrefixRepo from repos.prefixes import Prefix, PrefixRepo
from exceptions import bad_key
prefix_router = APIRouter(prefix="/api/prefixes") prefix_router = APIRouter(prefix="/api/prefixes")
@prefix_router.get("/") @prefix_router.get("/")
def get_all_prefixes(): def get_all_prefixes(api_key: str):
if not ApiKeyRepo().check_api(api_key):
raise bad_key
return PrefixRepo().get_all() return PrefixRepo().get_all()
@prefix_router.get("/{prefix_name}/") @prefix_router.get("/{prefix_name}/")
def get_one_prefix(prefix_name: str): def get_one_prefix(api_key: str, prefix_name: str):
if not ApiKeyRepo().check_api(api_key):
raise bad_key
return PrefixRepo().get_one(prefix_name) return PrefixRepo().get_one(prefix_name)
@prefix_router.post("/") @prefix_router.post("/")
def post_one_prefix(p: Prefix): def post_one_prefix(api_key: str, p: Prefix):
if not ApiKeyRepo().check_api(api_key):
raise bad_key
rep_detail = PrefixRepo().add_one(p) rep_detail = PrefixRepo().add_one(p)
return {"detail": rep_detail} return {"detail": rep_detail}
@prefix_router.delete("/") @prefix_router.delete("/")
def del_one_prefix(prefix_name: str): def del_one_prefix(api_key: str, prefix_name: str):
if not ApiKeyRepo().check_api(api_key):
raise bad_key
rep_detail = PrefixRepo().del_one(prefix_name) rep_detail = PrefixRepo().del_one(prefix_name)
return {"detail": rep_detail} return {"detail": rep_detail}

36
api/routers/tickets.py Normal file
View File

@@ -0,0 +1,36 @@
from fastapi import APIRouter
from repos.tickets import TicketRepo, Ticket
from repos.api_keys import ApiKeyRepo
from exceptions import bad_key
ticket_router = APIRouter(prefix="/api/tickets")
@ticket_router.get("/")
def get_all_tickets(api_key: str) -> list[Ticket]:
if not ApiKeyRepo().check_api(api_key):
raise bad_key
return TicketRepo().get_all()
@ticket_router.get("/{prefix}/")
def get_prefix_tickets(api_key: str, prefix: str) -> list[Ticket]:
if not ApiKeyRepo().check_api(api_key):
raise bad_key
return TicketRepo().get_prefix_all(prefix)
@ticket_router.get("/{prefix}/{t_id}/")
def get_prefix_ticket_one(api_key: str, prefix: str, t_id: int) -> Ticket:
if not ApiKeyRepo().check_api(api_key):
raise bad_key
return TicketRepo().get_prefix_one(prefix, t_id)
@ticket_router.get("/{prefix}/{t_from}/{t_to}")
def get_prefix_ticket_range(api_key: str, prefix: str, t_from: int, t_to: int) -> list[Ticket]:
if not ApiKeyRepo().check_api(api_key):
raise bad_key
return TicketRepo().get_prefix_range(prefix, t_from, t_to)
@ticket_router.post("/")
def post_tickets(api_key: str, tickets: list[Ticket]):
if not ApiKeyRepo().check_api(api_key):
raise bad_key
return TicketRepo().post_list(tickets)

View File

@@ -0,0 +1,20 @@
import { db } from "$lib/server/db";
import { tickets } from "$lib/server/db/schema";
import { env } from "$env/dynamic/private";
export async function GET({ params }) {
if (env.TAM3_REMOTE) {
const res = await fetch(`${env.TAM3_REMOTE}/api/tickets/?api_key=${env.TAM3_REMOTE_KEY}`);
if (!res.ok) {
return new Response(JSON.stringify({details: "Couldn't fetch tickets."}), {
status: res.status,
statusText: res.statusText
});
};
const data = await res.json();
return new Response(JSON.stringify(data), {status: 200, statusText: "Tickets fetched successfully."})
} else {
const data = await db.select().from(tickets);
return new Response(JSON.stringify(data), {status: 200, statusText: "Tickets loaded successfully."})
};
}

View File

@@ -0,0 +1,35 @@
import { db } from "$lib/server/db";
import { tickets } from "$lib/server/db/schema";
import { env } from "$env/dynamic/private";
import { eq, and } from "drizzle-orm";
export async function GET({ params }) {
let n_t_from = parseInt(params.t_from), n_t_to = parseInt(params.t_to);
if (env.TAM3_REMOTE) {
const res = await fetch(`${env.TAM3_REMOTE}/api/tickets/${params.prefix}/${n_t_from}/${n_t_to}/?api_key=${env.TAM3_REMOTE_KEY}`);
if (!res.ok) {
return new Response(JSON.stringify({details: "Unable to fetch tickets."}), {status: res.status, statusText: res.statusText})
};
const data = await res.json();
return new Response(JSON.stringify(data), {
headers: {'Content-Type': 'application/json'},
status: 200,
statusText: "Tickets fetched successfully."
})
} else {
let r_dict = {};
for (let i=n_t_from; i <= n_t_to; i++) {
let data = await db.select().from(tickets).where(and(eq(tickets.prefix, params.prefix), eq(tickets.t_id, i)));
if (data[0]) {
r_dict[i] = {...data[0]};
} else {
r_dict[i] = {prefix: params.prefix, t_id: i, first_name: "", last_name: "", phone_number: "", preference: "CALL", changed: false};
}
};
return new Response(JSON.stringify(Object.values(r_dict)), {
headers: {'Content-Type': 'application/json'},
status: 200,
statusText: "Tickets loaded successfully."
})
}
}