v2.0.11: вся загрузка через ВМ-буфер (ZIP + .doc)
Deploy contracts-flask / validate (push) Canceled after 0s
Deploy contracts-flask / validate (push) Canceled after 0s
- /api/unzip_refs: pull ZIP с ВМ + распаковка - /api/convert_refs: pull .doc с ВМ + конвертация в .docx - convertDoc/addZipFile: PUT на ВМ вместо прямого multipart
This commit is contained in:
+25
-17
@@ -207,21 +207,29 @@ window.toggleClassifyDetail = async function(i) {
|
||||
};
|
||||
|
||||
/**
|
||||
* convertDoc(file, onProgress) — .doc → .docx через внешний libreoffice-сервис.
|
||||
* С честным счётчиком времени.
|
||||
* convertDoc(file, onProgress) — .doc → .docx через ВМ-буфер (паттерн drhider).
|
||||
* Фаза 1: PUT .doc на ВМ. Фаза 2: /api/convert_refs → pull → конвертация → .docx.
|
||||
*/
|
||||
function convertDoc(file, onProgress) {
|
||||
var startTime = Date.now();
|
||||
if (onProgress) onProgress({ kind: 'converting', elapsed: 0 });
|
||||
var fd = new FormData();
|
||||
fd.append('files', file, file.name);
|
||||
var token = crypto.randomUUID();
|
||||
var vmUrl = VM_UPLOAD_URL + token + '_0';
|
||||
|
||||
var timer = setInterval(function() {
|
||||
var elapsed = Math.floor((Date.now() - startTime) / 1000);
|
||||
if (onProgress) onProgress({ kind: 'converting', elapsed: elapsed });
|
||||
}, 1000);
|
||||
|
||||
return fetch(CONVERT_URL + '?_=' + Date.now(), { method: 'POST', body: fd })
|
||||
return fetch(vmUrl, { method: 'PUT', body: file, headers: { 'Content-Type': 'application/octet-stream' } })
|
||||
.then(function(r) {
|
||||
if (!r.ok) throw new Error('Конвертация: VM upload HTTP ' + r.status);
|
||||
return fetch('/api/convert_refs?_=' + Date.now(), {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ files: [{ name: file.name, size: file.size, url: vmUrl }] })
|
||||
});
|
||||
})
|
||||
.then(function(r) {
|
||||
if (!r.ok) throw new Error('Конвертация: HTTP ' + r.status);
|
||||
return r.blob();
|
||||
@@ -236,6 +244,7 @@ function convertDoc(file, onProgress) {
|
||||
})
|
||||
.catch(function(e) {
|
||||
clearInterval(timer);
|
||||
if (e.message === 'Failed to fetch' || e.name === 'TypeError') throw new Error('Конвертация: Сеть');
|
||||
throw e;
|
||||
});
|
||||
}
|
||||
@@ -386,19 +395,18 @@ async function addZipFile(file) {
|
||||
render(state);
|
||||
|
||||
try {
|
||||
// Шаг 1: распаковать ZIP на бэкенде
|
||||
var zipResp = await new Promise(function(resolve, reject) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', UNZIP_URL);
|
||||
xhr.responseType = 'json';
|
||||
xhr.onload = function() { resolve(xhr.response); };
|
||||
xhr.onerror = function() { reject(new Error('Сеть')); };
|
||||
xhr.ontimeout = function() { reject(new Error('Таймаут')); };
|
||||
xhr.timeout = 60000;
|
||||
var fd = new FormData();
|
||||
fd.append('files', file);
|
||||
xhr.send(fd);
|
||||
// Шаг 1: распаковать ZIP через ВМ-буфер (паттерн drhider)
|
||||
var token = crypto.randomUUID();
|
||||
var vmUrl = VM_UPLOAD_URL + token + '_0';
|
||||
var putResp = await fetch(vmUrl, { method: 'PUT', body: file, headers: { 'Content-Type': 'application/octet-stream' } });
|
||||
if (!putResp.ok) throw new Error('unzip failed: VM upload HTTP ' + putResp.status);
|
||||
var refsResp = await fetch('/api/unzip_refs?_=' + Date.now(), {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ files: [{ name: file.name, size: file.size, url: vmUrl }] })
|
||||
});
|
||||
if (!refsResp.ok) throw new Error('unzip failed: HTTP ' + refsResp.status);
|
||||
var zipResp = await refsResp.json();
|
||||
if (!zipResp.ok || !zipResp.files) throw new Error('unzip failed');
|
||||
|
||||
// Подтверждение: показать первые 10 файлов + итог
|
||||
|
||||
Reference in New Issue
Block a user