- копирую модуль upload/ из drhider (слои 1-2) - blueprint: параметр sink (drhider-сессия по умолчанию, сверка — DB+парсинг) - upload_bp: contracts_upload_sink = _store_and_parse - routes: регистрирую create_upload_refs_blueprint(cfg, sink=...) - app.py: корень репо в sys.path (для import upload) - History: план переиспользования + ревью Соннета
23 lines
1.4 KiB
JavaScript
23 lines
1.4 KiB
JavaScript
// decodeZipName — декодирование имени из ZIP: UTF-8-флаг / эвристика (UTF-8 → CP437 → CP866).
|
|
|
|
export function decodeZipName(bytes, isUtf8) {
|
|
if (isUtf8) return new TextDecoder('utf-8').decode(bytes);
|
|
// Многие архиваторы пишут имя в UTF-8, но НЕ выставляют UTF-8-флаг (bit 11).
|
|
// Сначала строго пробуем UTF-8: если байты — валидный UTF-8 с кириллицей/текстом,
|
|
// берём их как есть (иначе декодирование CP437→CP866 превратит их в «╨╣…»-мусор).
|
|
try {
|
|
const s = new TextDecoder('utf-8', { fatal: true }).decode(bytes);
|
|
// Кириллица — точно UTF-8; либо чистый печатаемый текст без управляющих символов.
|
|
if (/[\u0400-\u04FF]/.test(s) || !/[^\u0020-\u007e]/.test(s)) return s;
|
|
} catch (e) { /* не UTF-8 — legacy (CP437/CP866) */ }
|
|
let name;
|
|
try { name = new TextDecoder('ibm437').decode(bytes); }
|
|
catch (e) { name = new TextDecoder('utf-8').decode(bytes); }
|
|
// Кириллица из 1С (CP866) — перекодировать, если имя пришло как CP437-мусор
|
|
if (/[^\x00-\x7f]/.test(name)) {
|
|
try { name = new TextDecoder('ibm866').decode(bytes); }
|
|
catch (e) { /* оставить как есть */ }
|
|
}
|
|
return name;
|
|
}
|