From 7f503dc30747fea7c762e1160c872b8002a6c346 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B8=D0=BA=D1=82=D0=BE=D1=80?= <78488229+viktor138irk@users.noreply.github.com> Date: Thu, 7 May 2026 05:27:52 +0900 Subject: [PATCH] =?UTF-8?q?=D0=9F=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA?= =?UTF-8?q?=D0=B0=20=D1=80=D0=B0=D1=81=D1=88=D0=B8=D1=80=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D0=B4=D0=B8=D1=81=D0=BA=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE?= =?UTF-8?q?=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B7=D0=B0=20=D0=B1=D1=8B=D0=BB?= =?UTF-8?q?=D0=B0=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0?= =?UTF-8?q?=20=D0=BF=D1=80=D0=B8=20=D0=B2=D1=8B=D0=B1=D0=BE=D1=80=D0=B5=20?= =?UTF-8?q?=D1=84=D0=B0=D0=B9=D0=BB=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/templates/disk_images.html | 41 ++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/web/templates/disk_images.html b/web/templates/disk_images.html index 2610dd4..861c14c 100644 --- a/web/templates/disk_images.html +++ b/web/templates/disk_images.html @@ -11,7 +11,7 @@
Диски
-
Готовые образы установленных систем: .img / .raw / .qcow2, а также архивы .zip / .tar.gz / .tgz
+
Готовые образы установленных систем: .img / .raw / .qcow2 / .img.xz, а также архивы .zip / .tar.gz / .tgz
user: {{ user }} @@ -30,14 +30,15 @@

Загрузить образ установленной системы

- .img .raw .qcow2 .zip .tar.gz + .img .raw .qcow2 .img.xz .zip .tar.gz
-
Файл ещё не выбран. Разрешены .img, .raw, .qcow2, .zip, .tar.gz и .tgz.
+
Файл ещё не выбран. Разрешены .img, .raw, .qcow2, .img.xz, .zip, .tar.gz и .tgz.
+
@@ -62,11 +63,11 @@
Raspberry / Orange Pi images - Загрузи .img или архив с .img, дождись распаковки/конвертации, затем в “Создать VM” выбери режим “Готовый диск”. + Загрузи .img, .img.xz или архив с .img, дождись распаковки/конвертации, затем в “Создать VM” выбери режим “Готовый диск”.
Архивы безопасно распаковываются - Поддерживаются .zip, .tar.gz и .tgz. Из архива берём только .img/.raw/.qcow2. + Поддерживаются .zip, .tar.gz, .tgz и .img.xz. Из обычных архивов берём только .img/.raw/.qcow2.
qemu-img convert -p -f raw -O qcow2 source.img source.qcow2
@@ -97,7 +98,7 @@ {% else %} - Образов пока нет. Загрузи .img, .raw, .qcow2 или архив .zip/.tar.gz/.tgz. + Образов пока нет. Загрузи .img, .raw, .qcow2, .img.xz или архив .zip/.tar.gz/.tgz. {% endfor %} @@ -109,13 +110,14 @@ const fileInput = document.getElementById('disk-file-input'); const button = document.getElementById('disk-upload-button'); const hint = document.getElementById('disk-file-hint'); + const errorBox = document.getElementById('disk-file-error'); const box = document.getElementById('upload-progress-wrap'); const bar = document.getElementById('upload-progress-bar'); const percent = document.getElementById('upload-percent'); const statusLine = document.getElementById('upload-status'); const loadedLine = document.getElementById('upload-loaded'); const speedLine = document.getElementById('upload-speed'); - const allowedExtensions = ['.img', '.raw', '.qcow2', '.zip', '.tar.gz', '.tgz']; + const allowedExtensions = ['.img', '.raw', '.qcow2', '.img.xz', '.zip', '.tar.gz', '.tgz']; function bytesText(bytes) { if (!bytes) return '0 MB'; @@ -132,6 +134,12 @@ return allowedExtensions.some(ext => lower.endsWith(ext)); } + function setFileError(message) { + if (!errorBox) return; + errorBox.textContent = message || ''; + errorBox.hidden = !message; + } + function resetProgress(title, detail) { bar.style.width = '0%'; percent.textContent = '0%'; @@ -172,23 +180,32 @@ fileInput.addEventListener('change', function () { const file = fileInput.files[0]; + setFileError(''); if (!file) { - hint.textContent = 'Файл ещё не выбран. Разрешены .img, .raw, .qcow2, .zip, .tar.gz и .tgz.'; + hint.textContent = 'Файл ещё не выбран. Разрешены .img, .raw, .qcow2, .img.xz, .zip, .tar.gz и .tgz.'; + button.disabled = false; return; } if (!validDiskFile(file)) { - hint.textContent = 'Неверный тип файла. Здесь можно выбрать только .img, .raw, .qcow2, .zip, .tar.gz или .tgz.'; + const message = 'Неверное расширение: ' + file.name + '. Разрешены только .img, .raw, .qcow2, .img.xz, .zip, .tar.gz и .tgz.'; + hint.textContent = message; + setFileError(message); fileInput.value = ''; + button.disabled = true; return; } + button.disabled = false; hint.textContent = file.name + ' · ' + bytesText(file.size); }); form.addEventListener('submit', function (event) { event.preventDefault(); const file = fileInput.files[0]; + setFileError(''); if (!validDiskFile(file)) { - hint.textContent = 'Выбери образ установленной системы или архив: .img, .raw, .qcow2, .zip, .tar.gz или .tgz.'; + const message = 'Выбери образ установленной системы или архив: .img, .raw, .qcow2, .img.xz, .zip, .tar.gz или .tgz.'; + hint.textContent = message; + setFileError(message); return; }