Files
ap-capture/backend/main.py
2026-01-26 04:57:20 -06:00

111 lines
3.4 KiB
Python

# main.py
from fastapi import FastAPI, Form, UploadFile, File
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from filelock import FileLock
import aiofiles
import httpx
import os
from datetime import datetime
import openpyxl
# -------------------------
# Configuration
# -------------------------
NEXTCLOUD_BASE_URL = "https://nextcloud.sdanywhere.com/remote.php/webdav/APs"
NEXTCLOUD_USER = "kamaji"
NEXTCLOUD_PASSWORD = "DvB0U2Uj3tOJaD"
EXCEL_FILENAME = "ap_data.xlsx"
LOCK_FILENAME = f"{EXCEL_FILENAME}.lock"
app = FastAPI()
# Allow CORS for frontend (if needed)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
# -------------------------
# Utility: Upload file to Nextcloud
# -------------------------
async def upload_to_nextcloud(local_path, remote_name):
url = f"{NEXTCLOUD_BASE_URL}/{remote_name}"
async with httpx.AsyncClient() as client:
with open(local_path, "rb") as f:
r = await client.put(url, content=f, auth=(NEXTCLOUD_USER, NEXTCLOUD_PASSWORD))
r.raise_for_status()
# -------------------------
# Utility: Save Excel safely
# -------------------------
def append_to_excel(data_row):
lock = FileLock(LOCK_FILENAME)
with lock:
if not os.path.exists(EXCEL_FILENAME):
wb = openpyxl.Workbook()
ws = wb.active
ws.append(["Timestamp", "Site ID", "AP Location", "Cable Length", "Serial Number"])
wb.save(EXCEL_FILENAME)
wb = openpyxl.load_workbook(EXCEL_FILENAME)
ws = wb.active
ws.append(data_row)
wb.save(EXCEL_FILENAME)
# -------------------------
# Endpoint
# -------------------------
@app.post("/api/ap/submit")
async def submit_ap(
site_id: str = Form(...),
ap_location: str = Form(...),
cable_length: float = Form(...),
serial_number: str = Form(...),
photo_continuity: UploadFile = File(...),
photo_length: UploadFile = File(...),
photo_verification: UploadFile = File(...),
photo_close: UploadFile = File(...),
photo_distance: UploadFile = File(...),
):
# Capitalize serial number
serial_number = serial_number.upper()
# Create folder locally before upload
folder_name = f"AP{ap_location}"
os.makedirs(folder_name, exist_ok=True)
# Save photos locally first
photo_mapping = {
"continuity": photo_continuity,
"length": photo_length,
"verification": photo_verification,
"close": photo_close,
"distance": photo_distance
}
saved_files = []
for key, file in photo_mapping.items():
filename = f"AP{ap_location}_{key}.jpg"
local_path = os.path.join(folder_name, filename)
async with aiofiles.open(local_path, "wb") as out_file:
content = await file.read()
await out_file.write(content)
saved_files.append((local_path, filename)) # store for upload
# Append data to Excel
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
data_row = [timestamp, site_id, ap_location, cable_length, serial_number]
append_to_excel(data_row)
# Upload Excel to Nextcloud
await upload_to_nextcloud(EXCEL_FILENAME, EXCEL_FILENAME)
# Upload photos to Nextcloud
for local_path, remote_name in saved_files:
await upload_to_nextcloud(local_path, remote_name)
return JSONResponse(content={"site_id": site_id, "ap_location": ap_location})