From 244259975746c7d89fa8be00a1d1a1f9c23ae2b9 Mon Sep 17 00:00:00 2001 From: "Satur@it-depot.ru" Date: Wed, 5 Mar 2025 10:45:32 +0300 Subject: [PATCH] export --- app.py | 57 ++++++++++++++++++++++++++++++++++++++++++-- templates/index.html | 37 ++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 2 deletions(-) diff --git a/app.py b/app.py index 24b522b..5ffa1b3 100644 --- a/app.py +++ b/app.py @@ -1,9 +1,11 @@ -from fastapi import FastAPI, HTTPException +from fastapi import FastAPI, HTTPException, File, UploadFile from pydantic import BaseModel import sqlite3 import datetime +import csv from fastapi.staticfiles import StaticFiles -from fastapi.responses import FileResponse +from fastapi.responses import FileResponse, StreamingResponse +import io app = FastAPI() @@ -162,6 +164,57 @@ def delete_install(install_id: int): raise HTTPException(status_code=404, detail="Запись не найдена") return {"status": "success"} +# --- CSV Export/Import API --- +@app.get("/api/export/csv") +async def export_csv(): + cursor.execute(""" + SELECT i.rust_id, i.computer_name, i.install_time, f.name as folder_name, i.protocol + FROM installs i + LEFT JOIN folders f ON i.folder_id = f.id + """) + rows = cursor.fetchall() + + output = io.StringIO() + writer = csv.writer(output, lineterminator='\n') + writer.writerow(['ID подключения', 'Имя компьютера', 'Время установки', 'Папка', 'Протокол']) + for row in rows: + writer.writerow(row) + + headers = { + 'Content-Disposition': 'attachment; filename="rustdesk_data.csv"', + 'Content-Type': 'text/csv' + } + return StreamingResponse(iter([output.getvalue()]), headers=headers) + +@app.post("/api/import/csv") +async def import_csv(file: UploadFile = File(...)): + try: + contents = await file.read() + csv_data = io.StringIO(contents.decode('utf-8')) + reader = csv.DictReader(csv_data) + + for row in reader: + rust_id = row['ID подключения'] + computer_name = row['Имя компьютера'] + install_time = row['Время установки'] + folder_name = row['Папка'] + protocol = row['Протокол'] or 'rustdesk' + + # Получаем или создаем ID папки + cursor.execute("SELECT id FROM folders WHERE name = ?", (folder_name,)) + folder = cursor.fetchone() + folder_id = folder[0] if folder else unsorted_folder_id + + cursor.execute(""" + INSERT INTO installs (rust_id, computer_name, install_time, folder_id, protocol) + VALUES (?, ?, ?, ?, ?) + """, (rust_id, computer_name, install_time, folder_id, protocol)) + + conn.commit() + return {"status": "success", "message": "Данные успешно импортированы"} + except Exception as e: + raise HTTPException(status_code=400, detail=f"Ошибка импорта: {str(e)}") + # CORS from fastapi.middleware.cors import CORSMiddleware app.add_middleware( diff --git a/templates/index.html b/templates/index.html index 700f34e..63833b4 100644 --- a/templates/index.html +++ b/templates/index.html @@ -23,6 +23,10 @@ .sort-arrow { font-size: 12px; margin-left: 5px; } .protocol-icon { margin-right: 5px; height: 16px; width: 16px; vertical-align: middle; } .connection-link { color: blue; text-decoration: underline; cursor: pointer; } + #import-form { margin-top: 10px; } + #import-file { display: none; } + #import-label { cursor: pointer; background: #007bff; color: white; padding: 5px 10px; border-radius: 5px; } + #import-label:hover { background: #0056b3; } @@ -41,6 +45,13 @@ +
+ +
+ + +
+

Добавить запись

@@ -344,6 +355,32 @@ window.location.href = link; } } + + function exportCSV() { + window.location.href = `${API_URL}/export/csv`; + } + + function importCSV(file) { + if (!file) return; + + const formData = new FormData(); + formData.append('file', file); + + $.ajax({ + url: `${API_URL}/import/csv`, + type: 'POST', + data: formData, + processData: false, + contentType: false, + success: function (response) { + alert(response.message); + loadInstalls(selectedFolderId); + }, + error: function (xhr, status, error) { + alert(`Ошибка импорта: ${xhr.responseJSON.detail || error}`); + } + }); + } \ No newline at end of file