domovoy_bot/web/templates/files.html

192 lines
7.8 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "base.html" %}
{% block title %}Менеджер артефактов - LKM37{% endblock %}
{% block nav_files %}active{% endblock %}
{% block content %}
<h2 class="mb-4" style="color: var(--matrix-green); text-shadow: 0 0 10px var(--matrix-green);">
>_ ЦЕНТРАЛЬНЫЙ_АРХИВАННЫХ (FILES_CORE)
</h2>
<!-- Секция загрузки артефактов -->
<div class="row mb-4">
<div class="col-md-12">
<div class="card bg-black border-success shadow-sm">
<div class="card-body">
<h5 class="text-success mb-3"><i class="bi bi-cloud-upload"></i> РЕГИСТРАЦИЯ НОВОГО АРТЕФАКТА В TELEGRAM</h5>
<p class="small text-muted mb-3">Загрузите файл сюда, и бот отправит его вам в личку, чтобы получить постоянный <code>file_id</code>. Вы сможете использовать этот ID в рассылках и постах многократно.</p>
<form id="uploadForm" class="row g-3">
<div class="col-md-9">
<input type="file" id="fileInput" class="form-control bg-dark border-success text-success">
</div>
<div class="col-md-3">
<button type="button" id="uploadBtn" onclick="uploadFile()" class="btn btn-matrix w-100">
<span id="uploadSpinner" class="spinner-border spinner-border-sm d-none" role="status"></span>
ЗАГРУЗИТЬ
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<!-- Таблица артефактов -->
<div class="card mb-4 border-info">
<div class="card-header border-info bg-info bg-opacity-10 d-flex justify-content-between align-items-center">
<span class="text-info fw-bold">💠 АРТЕФАКТЫ TELEGRAM (ДЛЯ РАССЫЛОК)</span>
<button class="btn btn-outline-info btn-sm" onclick="loadFiles()">
<i class="bi bi-arrow-clockwise"></i> ОБНОВИТЬ
</button>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-dark table-hover mb-0">
<thead>
<tr class="text-info opacity-75" style="font-size: 0.8em;">
<th>ИМЯ ФАЙЛА</th>
<th>ТИП</th>
<th>TELEGRAM_FILE_ID</th>
<th class="text-end">ДЕЙСТВИЯ</th>
</tr>
</thead>
<tbody id="artifactsTable">
<!-- Заполняется через API -->
</tbody>
</table>
</div>
</div>
</div>
<!-- Таблица системных файлов -->
<div class="card border-secondary">
<div class="card-header border-secondary bg-secondary bg-opacity-10">
<span class="text-secondary fw-bold">📁 СИСТЕМНЫЕ ФАЙЛЫ (ЛОГИ И ЭКСПОРТЫ)</span>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-dark table-hover mb-0">
<thead>
<tr class="text-muted" style="font-size: 0.8em;">
<th>ИМЯ ФАЙЛА</th>
<th>КАТЕГОРИЯ</th>
<th>РАЗМЕР</th>
<th class="text-end">ДЕЙСТВИЯ</th>
</tr>
</thead>
<tbody id="systemFilesTable">
<!-- Заполняется через API -->
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}
{% block extra_script %}
<script>
document.addEventListener('DOMContentLoaded', loadFiles);
async function loadFiles() {
const artifactsTable = document.getElementById('artifactsTable');
const systemFilesTable = document.getElementById('systemFilesTable');
try {
const response = await fetch('/api/files/list');
const result = await response.json();
if (!result.success) throw new Error(result.error);
artifactsTable.innerHTML = '';
systemFilesTable.innerHTML = '';
const artifacts = result.files.filter(f => f.is_artifact);
const systemFiles = result.files.filter(f => !f.is_artifact);
if (artifacts.length === 0) {
artifactsTable.innerHTML = '<tr><td colspan="4" class="text-center p-3 text-muted">Артефакты не зарегистрированы</td></tr>';
} else {
artifacts.forEach(f => {
artifactsTable.innerHTML += `
<tr>
<td class="font-monospace text-info">${f.filename}</td>
<td><span class="badge bg-info text-dark">${f.file_type}</span></td>
<td><code class="text-success small" style="word-break: break-all;">${f.file_id}</code></td>
<td class="text-end">
<button class="btn btn-sm btn-outline-info" onclick="copyId('${f.file_id}')">
<i class="bi bi-copy"></i> ID
</button>
</td>
</tr>
`;
});
}
if (systemFiles.length === 0) {
systemFilesTable.innerHTML = '<tr><td colspan="4" class="text-center p-3 text-muted">Файлы не найдены</td></tr>';
} else {
systemFiles.forEach(f => {
systemFilesTable.innerHTML += `
<tr>
<td class="font-monospace">${f.filename}</td>
<td><span class="badge bg-secondary">${f.file_type}</span></td>
<td class="text-muted">${f.size}</td>
<td class="text-end">
<a href="${f.path}" class="btn btn-sm btn-outline-secondary" download>
<i class="bi bi-download"></i>
</a>
</td>
</tr>
`;
});
}
} catch (error) {
console.error(error);
}
}
function copyId(id) {
navigator.clipboard.writeText(id);
const toast = document.createElement('div');
toast.className = 'position-fixed bottom-0 end-0 p-3';
toast.style.zIndex = '11';
toast.innerHTML = `<div class="alert alert-success">FILE_ID скопирован!</div>`;
document.body.appendChild(toast);
setTimeout(() => toast.remove(), 2000);
}
async function uploadFile() {
const fileInput = document.getElementById('fileInput');
const btn = document.getElementById('uploadBtn');
const spinner = document.getElementById('uploadSpinner');
if (!fileInput.files[0]) return alert('Выберите файл для загрузки');
btn.disabled = true;
spinner.classList.remove('d-none');
const formData = new FormData();
formData.append('file', fileInput.files[0]);
try {
const response = await fetch('/api/files/upload', {
method: 'POST',
body: formData
});
const result = await response.json();
if (result.success) {
alert('Файл успешно зарегистрирован в Telegram!\nFILE_ID: ' + result.file_id);
location.reload();
} else {
alert('Ошибка при регистрации: ' + result.error);
}
} catch (error) {
alert('Сетевая ошибка: ' + error.message);
} finally {
btn.disabled = false;
spinner.classList.add('d-none');
}
}
</script>
{% endblock %}