domovoy_bot/web/templates/files.html

188 lines
7.4 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 %}Файлы и архивы - МКД ЛенКом 37{% endblock %}
{% block nav_files %}active{% endblock %}
{% block content %}
<div class="mb-3">
<h4 class="mb-1" style="font-size: 16px; font-weight: bold;">Менеджер файлов и медиа-артефактов</h4>
<div class="small text-muted">Хранилище документов, системных архивов и медиа-файлов для рассылок</div>
</div>
<!-- Секция загрузки артефактов -->
<div class="row mb-3">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<i class="bi bi-cloud-upload"></i> ЗАГРУЗКА МЕДИА-ФАЙЛА (РЕГИСТРАЦИЯ В TELEGRAM)
</div>
<div class="card-body">
<p class="small text-muted mb-3">
Загрузите изображение или документ. Бот сохранит его в Telegram и сгенерирует постоянный <code>file_id</code> для безопасного использования в постах и рассылках.
</p>
<form id="uploadForm" class="row g-2 align-items-center">
<div class="col-md-9">
<input type="file" id="fileInput" class="form-control">
</div>
<div class="col-md-3">
<button type="button" id="uploadBtn" onclick="uploadFile()" class="btn-unix btn-unix-primary 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-3">
<div class="card-header d-flex justify-content-between align-items-center">
<span>ЗАРЕГИСТРИРОВАННЫЕ МЕДИА-АРТЕФАКТЫ TELEGRAM</span>
<button class="btn-unix" onclick="loadFiles()">
<i class="bi bi-arrow-clockwise"></i> Обновить список
</button>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table mb-0">
<thead>
<tr>
<th>Имя файла</th>
<th style="width: 120px;">Тип</th>
<th>Telegram File ID</th>
<th class="text-end" style="width: 120px;">Действие</th>
</tr>
</thead>
<tbody id="artifactsTable">
<!-- Заполняется через JS -->
</tbody>
</table>
</div>
</div>
</div>
<!-- Таблица системных файлов -->
<div class="card">
<div class="card-header">СИСТЕМНЫЕ АРХИВЫ И ЛОГИ СЕРВЕРА</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table mb-0">
<thead>
<tr>
<th>Имя файла</th>
<th style="width: 140px;">Категория</th>
<th style="width: 120px;">Размер</th>
<th class="text-end" style="width: 100px;">Скачать</th>
</tr>
</thead>
<tbody id="systemFilesTable">
<!-- Заполняется через JS -->
</tbody>
</table>
</div>
</div>
</div>
<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><b>${f.filename}</b></td>
<td><span class="badge-status">${f.file_type}</span></td>
<td><code style="word-break: break-all;">${f.file_id}</code></td>
<td class="text-end">
<button class="btn-unix" onclick="copyId('${f.file_id}')">
Копировать 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><b>${f.filename}</b></td>
<td><span class="badge-status">${f.file_type}</span></td>
<td>${f.size}</td>
<td class="text-end">
<a href="${f.path}" class="btn-unix" download>
Скачать
</a>
</td>
</tr>
`;
});
}
} catch (error) {
console.error(error);
}
}
function copyId(id) {
navigator.clipboard.writeText(id);
alert('File ID скопирован в буфер обмена');
}
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 %}