nightly - 2025-09-23
This commit is contained in:
@@ -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
40
api/repos/tickets.py
Normal 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."}
|
||||||
@@ -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
36
api/routers/tickets.py
Normal 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)
|
||||||
20
webapp/src/routes/api/tickets/+server.js
Normal file
20
webapp/src/routes/api/tickets/+server.js
Normal 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."})
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -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."
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user