main
Satur@it-depot.ru 2025-03-05 10:45:32 +03:00
parent 30ae8b76b6
commit 2442599757
2 changed files with 92 additions and 2 deletions

57
app.py
View File

@ -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(

View File

@ -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; }
</style>
</head>
<body>
@ -41,6 +45,13 @@
<input type="radio" id="search-all" name="search-scope" value="all">
<label for="search-all">Все папки</label>
</div>
<div style="margin-top: 10px;">
<button onclick="exportCSV()">Экспорт CSV</button>
<form id="import-form" enctype="multipart/form-data">
<input type="file" id="import-file" accept=".csv" onchange="importCSV(this.files[0])">
<label for="import-file" id="import-label">Импорт CSV</label>
</form>
</div>
</div>
<div class="form-container">
<h2>Добавить запись</h2>
@ -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}`);
}
});
}
</script>
</body>
</html>