icons
parent
715961b425
commit
51c58e22a0
25
app.py
25
app.py
|
|
@ -11,7 +11,7 @@ app = FastAPI()
|
||||||
conn = sqlite3.connect("/db/rustdesk.db", check_same_thread=False)
|
conn = sqlite3.connect("/db/rustdesk.db", check_same_thread=False)
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
|
|
||||||
# Создаем таблицы
|
# Создаем таблицы (добавляем поле protocol)
|
||||||
cursor.execute("""
|
cursor.execute("""
|
||||||
CREATE TABLE IF NOT EXISTS folders (
|
CREATE TABLE IF NOT EXISTS folders (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
|
@ -23,10 +23,11 @@ CREATE TABLE IF NOT EXISTS folders (
|
||||||
cursor.execute("""
|
cursor.execute("""
|
||||||
CREATE TABLE IF NOT EXISTS installs (
|
CREATE TABLE IF NOT EXISTS installs (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
rust_id TEXT,
|
rust_id TEXT, -- Оставляем название поля для совместимости, но оно теперь универсальное (ID подключения)
|
||||||
computer_name TEXT,
|
computer_name TEXT,
|
||||||
install_time TEXT,
|
install_time TEXT,
|
||||||
folder_id INTEGER,
|
folder_id INTEGER,
|
||||||
|
protocol TEXT DEFAULT 'rustdesk', -- Новое поле с протоколом, по умолчанию RustDesk
|
||||||
FOREIGN KEY (folder_id) REFERENCES folders(id)
|
FOREIGN KEY (folder_id) REFERENCES folders(id)
|
||||||
)
|
)
|
||||||
""")
|
""")
|
||||||
|
|
@ -55,6 +56,7 @@ class InstallData(BaseModel):
|
||||||
computer_name: str | None = None
|
computer_name: str | None = None
|
||||||
install_time: str | None = None
|
install_time: str | None = None
|
||||||
folder_id: int | None = None
|
folder_id: int | None = None
|
||||||
|
protocol: str | None = 'rustdesk' # По умолчанию RustDesk
|
||||||
|
|
||||||
# Монтируем папку templates как статические файлы
|
# Монтируем папку templates как статические файлы
|
||||||
app.mount("/templates", StaticFiles(directory="templates"), name="templates")
|
app.mount("/templates", StaticFiles(directory="templates"), name="templates")
|
||||||
|
|
@ -98,44 +100,43 @@ def delete_folder(folder_id: int):
|
||||||
@app.get("/api/installs")
|
@app.get("/api/installs")
|
||||||
def get_installs():
|
def get_installs():
|
||||||
cursor.execute("""
|
cursor.execute("""
|
||||||
SELECT i.id, i.rust_id, i.computer_name, i.install_time, i.folder_id, f.name as folder_name
|
SELECT i.id, i.rust_id, i.computer_name, i.install_time, i.folder_id, f.name as folder_name, i.protocol
|
||||||
FROM installs i
|
FROM installs i
|
||||||
LEFT JOIN folders f ON i.folder_id = f.id
|
LEFT JOIN folders f ON i.folder_id = f.id
|
||||||
""")
|
""")
|
||||||
rows = cursor.fetchall()
|
rows = cursor.fetchall()
|
||||||
return [{"id": row[0], "rust_id": row[1], "computer_name": row[2],
|
return [{"id": row[0], "rust_id": row[1], "computer_name": row[2],
|
||||||
"install_time": row[3], "folder_id": row[4], "folder_name": row[5]}
|
"install_time": row[3], "folder_id": row[4], "folder_name": row[5], "protocol": row[6]}
|
||||||
for row in rows]
|
for row in rows]
|
||||||
|
|
||||||
@app.post("/api/install")
|
@app.post("/api/install")
|
||||||
def add_install(data: InstallData):
|
def add_install(data: InstallData):
|
||||||
install_time = data.install_time or datetime.datetime.now().isoformat()
|
install_time = data.install_time or datetime.datetime.now().isoformat()
|
||||||
# Если folder_id не указан (например, от скрипта), используем "Несортированные"
|
|
||||||
folder_id = data.folder_id if data.folder_id is not None else unsorted_folder_id
|
folder_id = data.folder_id if data.folder_id is not None else unsorted_folder_id
|
||||||
cursor.execute("INSERT INTO installs (rust_id, computer_name, install_time, folder_id) VALUES (?, ?, ?, ?)",
|
protocol = data.protocol or 'rustdesk' # По умолчанию RustDesk для POST-запросов
|
||||||
(data.rust_id, data.computer_name, install_time, folder_id))
|
cursor.execute("INSERT INTO installs (rust_id, computer_name, install_time, folder_id, protocol) VALUES (?, ?, ?, ?, ?)",
|
||||||
|
(data.rust_id, data.computer_name, install_time, folder_id, protocol))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
return {"status": "success"}
|
return {"status": "success"}
|
||||||
|
|
||||||
@app.put("/api/install/{install_id}")
|
@app.put("/api/install/{install_id}")
|
||||||
def update_install(install_id: int, data: InstallData):
|
def update_install(install_id: int, data: InstallData):
|
||||||
# Получаем текущие данные записи
|
cursor.execute("SELECT rust_id, computer_name, install_time, folder_id, protocol FROM installs WHERE id = ?", (install_id,))
|
||||||
cursor.execute("SELECT rust_id, computer_name, install_time, folder_id FROM installs WHERE id = ?", (install_id,))
|
|
||||||
current = cursor.fetchone()
|
current = cursor.fetchone()
|
||||||
if not current:
|
if not current:
|
||||||
raise HTTPException(status_code=404, detail="Запись не найдена")
|
raise HTTPException(status_code=404, detail="Запись не найдена")
|
||||||
|
|
||||||
# Обновляем только те поля, которые переданы
|
|
||||||
new_rust_id = data.rust_id if data.rust_id is not None else current[0]
|
new_rust_id = data.rust_id if data.rust_id is not None else current[0]
|
||||||
new_computer_name = data.computer_name if data.computer_name is not None else current[1]
|
new_computer_name = data.computer_name if data.computer_name is not None else current[1]
|
||||||
new_install_time = data.install_time if data.install_time is not None else current[2]
|
new_install_time = data.install_time if data.install_time is not None else current[2]
|
||||||
new_folder_id = data.folder_id if data.folder_id is not None else current[3]
|
new_folder_id = data.folder_id if data.folder_id is not None else current[3]
|
||||||
|
new_protocol = data.protocol if data.protocol is not None else current[4]
|
||||||
|
|
||||||
cursor.execute("""
|
cursor.execute("""
|
||||||
UPDATE installs
|
UPDATE installs
|
||||||
SET rust_id = ?, computer_name = ?, install_time = ?, folder_id = ?
|
SET rust_id = ?, computer_name = ?, install_time = ?, folder_id = ?, protocol = ?
|
||||||
WHERE id = ?
|
WHERE id = ?
|
||||||
""", (new_rust_id, new_computer_name, new_install_time, new_folder_id, install_id))
|
""", (new_rust_id, new_computer_name, new_install_time, new_folder_id, new_protocol, install_id))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
return {"status": "success"}
|
return {"status": "success"}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
.header div { flex: 1; text-align: center; }
|
.header div { flex: 1; text-align: center; }
|
||||||
.header div:hover { background: #e0e0e0; }
|
.header div:hover { background: #e0e0e0; }
|
||||||
.sort-arrow { font-size: 12px; margin-left: 5px; }
|
.sort-arrow { font-size: 12px; margin-left: 5px; }
|
||||||
|
.protocol-icon { margin-right: 5px; }
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
@ -42,13 +43,21 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="form-container">
|
<div class="form-container">
|
||||||
<h2>Добавить запись</h2>
|
<h2>Добавить запись</h2>
|
||||||
<input type="text" id="rustId" placeholder="Rust ID" required>
|
<input type="text" id="rustId" placeholder="ID подключения" required>
|
||||||
<input type="text" id="computerName" placeholder="Имя компьютера" required>
|
<input type="text" id="computerName" placeholder="Имя компьютера" required>
|
||||||
<input type="text" id="installTime" placeholder="Время (опционально)">
|
<input type="text" id="installTime" placeholder="Время (опционально)">
|
||||||
|
<select id="protocol">
|
||||||
|
<option value="rustdesk" selected>RustDesk</option>
|
||||||
|
<option value="anydesk">AnyDesk</option>
|
||||||
|
<option value="ammyy">Ammyy Admin</option>
|
||||||
|
<option value="teamviewer">TeamViewer</option>
|
||||||
|
<option value="vnc">VNC</option>
|
||||||
|
<option value="rdp">RDP</option>
|
||||||
|
</select>
|
||||||
<button onclick="addInstall()">Добавить</button>
|
<button onclick="addInstall()">Добавить</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<div onclick="sortInstalls('rust_id')">Rust ID<span class="sort-arrow"></span></div>
|
<div onclick="sortInstalls('rust_id')">ID подключения<span class="sort-arrow"></span></div>
|
||||||
<div onclick="sortInstalls('computer_name')">Имя компьютера<span class="sort-arrow"></span></div>
|
<div onclick="sortInstalls('computer_name')">Имя компьютера<span class="sort-arrow"></span></div>
|
||||||
<div onclick="sortInstalls('install_time')">Время установки<span class="sort-arrow"></span></div>
|
<div onclick="sortInstalls('install_time')">Время установки<span class="sort-arrow"></span></div>
|
||||||
<div>Действия</div>
|
<div>Действия</div>
|
||||||
|
|
@ -63,6 +72,15 @@
|
||||||
let sortField = null;
|
let sortField = null;
|
||||||
let sortDirection = 'asc';
|
let sortDirection = 'asc';
|
||||||
|
|
||||||
|
const protocolIcons = {
|
||||||
|
'rustdesk': '🖥️', // Эмодзи для RustDesk
|
||||||
|
'anydesk': '🔴', // Эмодзи для AnyDesk
|
||||||
|
'ammyy': '🟢', // Эмодзи для Ammyy Admin
|
||||||
|
'teamviewer': '🔵', // Эмодзи для TeamViewer
|
||||||
|
'vnc': '🟡', // Эмодзи для VNC
|
||||||
|
'rdp': '🟣' // Эмодзи для RDP
|
||||||
|
};
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$('#folder-tree').jstree({
|
$('#folder-tree').jstree({
|
||||||
'core': {
|
'core': {
|
||||||
|
|
@ -120,12 +138,12 @@
|
||||||
function displayInstalls(installs) {
|
function displayInstalls(installs) {
|
||||||
$('#installs-list').html(installs.map(item => `
|
$('#installs-list').html(installs.map(item => `
|
||||||
<div class="install-item" data-id="${item.id}" draggable="true" style="display: flex; justify-content: space-between;">
|
<div class="install-item" data-id="${item.id}" draggable="true" style="display: flex; justify-content: space-between;">
|
||||||
<div style="flex: 1; text-align: center;">${item.rust_id}</div>
|
<div style="flex: 1; text-align: center;"><span class="protocol-icon">${protocolIcons[item.protocol]}</span>${item.rust_id}</div>
|
||||||
<div style="flex: 1; text-align: center;">${item.computer_name}</div>
|
<div style="flex: 1; text-align: center;">${item.computer_name}</div>
|
||||||
<div style="flex: 1; text-align: center;">${item.install_time}</div>
|
<div style="flex: 1; text-align: center;">${item.install_time}</div>
|
||||||
<div style="flex: 1; text-align: center;">
|
<div style="flex: 1; text-align: center;">
|
||||||
<a href="rustdesk://${item.rust_id}" onclick="openRustDesk('${item.rust_id}'); return false;">Подключиться</a>
|
<a href="${item.protocol}://${item.rust_id}" onclick="openRemote('${item.rust_id}', '${item.protocol}'); return false;">Подключиться</a>
|
||||||
<button onclick="editInstall(${item.id}, '${item.rust_id}', '${item.computer_name}', '${item.install_time}')">Редактировать</button>
|
<button onclick="editInstall(${item.id}, '${item.rust_id}', '${item.computer_name}', '${item.install_time}', '${item.protocol}')">Редактировать</button>
|
||||||
<button onclick="deleteInstall(${item.id})">Удалить</button>
|
<button onclick="deleteInstall(${item.id})">Удалить</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -173,7 +191,7 @@
|
||||||
function updateSortArrows() {
|
function updateSortArrows() {
|
||||||
$('.sort-arrow').text('');
|
$('.sort-arrow').text('');
|
||||||
if (sortField) {
|
if (sortField) {
|
||||||
$(`.header div:contains("${sortField === 'rust_id' ? 'Rust ID' : sortField === 'computer_name' ? 'Имя компьютера' : 'Время установки'}") .sort-arrow`)
|
$(`.header div:contains("${sortField === 'rust_id' ? 'ID подключения' : sortField === 'computer_name' ? 'Имя компьютера' : 'Время установки'}") .sort-arrow`)
|
||||||
.text(sortDirection === 'asc' ? '↑' : '↓');
|
.text(sortDirection === 'asc' ? '↑' : '↓');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -231,27 +249,29 @@
|
||||||
const rustId = $('#rustId').val();
|
const rustId = $('#rustId').val();
|
||||||
const computerName = $('#computerName').val();
|
const computerName = $('#computerName').val();
|
||||||
const installTime = $('#installTime').val() || new Date().toISOString();
|
const installTime = $('#installTime').val() || new Date().toISOString();
|
||||||
|
const protocol = $('#protocol').val();
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: `${API_URL}/install`,
|
url: `${API_URL}/install`,
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
data: JSON.stringify({ rust_id: rustId, computer_name: computerName, install_time: installTime, folder_id: selectedFolderId }),
|
data: JSON.stringify({ rust_id: rustId, computer_name: computerName, install_time: installTime, folder_id: selectedFolderId, protocol: protocol }),
|
||||||
success: function () {
|
success: function () {
|
||||||
loadInstalls(selectedFolderId);
|
loadInstalls(selectedFolderId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function editInstall(id, rustId, computerName, installTime) {
|
function editInstall(id, rustId, computerName, installTime, protocol) {
|
||||||
const newRustId = prompt("Rust ID:", rustId);
|
const newRustId = prompt("ID подключения:", rustId);
|
||||||
const newComputerName = prompt("Имя компьютера:", computerName);
|
const newComputerName = prompt("Имя компьютера:", computerName);
|
||||||
const newInstallTime = prompt("Время установки:", installTime);
|
const newInstallTime = prompt("Время установки:", installTime);
|
||||||
|
const newProtocol = prompt("Протокол (rustdesk, anydesk, ammyy, teamviewer, vnc, rdp):", protocol);
|
||||||
if (newRustId && newComputerName) {
|
if (newRustId && newComputerName) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: `${API_URL}/install/${id}`,
|
url: `${API_URL}/install/${id}`,
|
||||||
type: 'PUT',
|
type: 'PUT',
|
||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
data: JSON.stringify({ rust_id: newRustId, computer_name: newComputerName, install_time: newInstallTime, folder_id: selectedFolderId }),
|
data: JSON.stringify({ rust_id: newRustId, computer_name: newComputerName, install_time: newInstallTime, folder_id: selectedFolderId, protocol: newProtocol }),
|
||||||
success: function () {
|
success: function () {
|
||||||
loadInstalls(selectedFolderId);
|
loadInstalls(selectedFolderId);
|
||||||
}
|
}
|
||||||
|
|
@ -286,9 +306,9 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function openRustDesk(rustId) {
|
function openRemote(id, protocol) {
|
||||||
if (confirm("Подключиться к " + rustId + "?")) {
|
if (confirm(`Подключиться к ${id} через ${protocol}?`)) {
|
||||||
window.location.href = `rustdesk://${rustId}`;
|
window.location.href = `${protocol}://${id}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue