traslado 2.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- traslado-2.0.0/ABRIR.bat +3 -0
- traslado-2.0.0/ABRIR.ps1 +16 -0
- traslado-2.0.0/CHANGELOG.md +56 -0
- traslado-2.0.0/INSTALAR.bat +12 -0
- traslado-2.0.0/INSTALAR.ps1 +49 -0
- traslado-2.0.0/LEGACY-CATALOG.json +894 -0
- traslado-2.0.0/LICENCE +661 -0
- traslado-2.0.0/PKG-INFO +328 -0
- traslado-2.0.0/README.md +294 -0
- traslado-2.0.0/THIRD-PARTY-INVENTORY.json +1268 -0
- traslado-2.0.0/THIRD-PARTY.md +53 -0
- traslado-2.0.0/ci/libs-permitidas-linux.txt +18 -0
- traslado-2.0.0/ci/libs-permitidas-macos.txt +15 -0
- traslado-2.0.0/ci/libs-permitidas-windows.txt +14 -0
- traslado-2.0.0/instalar.command +7 -0
- traslado-2.0.0/instalar.sh +7 -0
- traslado-2.0.0/install.ps1 +414 -0
- traslado-2.0.0/install.sh +483 -0
- traslado-2.0.0/licenses-allowlist.json +27 -0
- traslado-2.0.0/locks/core.in +1 -0
- traslado-2.0.0/locks/full.in +10 -0
- traslado-2.0.0/locks/legacy.in +2 -0
- traslado-2.0.0/locks/requirements-core.hashes.lock +2 -0
- traslado-2.0.0/locks/requirements-full.hashes.lock +318 -0
- traslado-2.0.0/locks/requirements-legacy.hashes.lock +12 -0
- traslado-2.0.0/ocr-assets.lock.json +437 -0
- traslado-2.0.0/pyproject.toml +42 -0
- traslado-2.0.0/release-files.txt +78 -0
- traslado-2.0.0/requirements-full.hashes.lock +318 -0
- traslado-2.0.0/requirements-full.lock +11 -0
- traslado-2.0.0/requirements-test.hashes.lock +4 -0
- traslado-2.0.0/revocation/revoked-list.json +5 -0
- traslado-2.0.0/scripts/auditar_libs.py +477 -0
- traslado-2.0.0/scripts/bootstrap_ocr.ps1 +303 -0
- traslado-2.0.0/scripts/build_release.py +349 -0
- traslado-2.0.0/scripts/ci_gate.py +54 -0
- traslado-2.0.0/scripts/e2e_runner.py +830 -0
- traslado-2.0.0/scripts/fuzz_atheris.py +159 -0
- traslado-2.0.0/scripts/gerar_fixtures.py +98 -0
- traslado-2.0.0/scripts/gerar_icone.py +32 -0
- traslado-2.0.0/scripts/gerar_locks.py +129 -0
- traslado-2.0.0/scripts/install_windows.py +517 -0
- traslado-2.0.0/scripts/installation_processes.ps1 +10 -0
- traslado-2.0.0/scripts/inventario.py +218 -0
- traslado-2.0.0/scripts/resumir_contencao.py +48 -0
- traslado-2.0.0/scripts/shortcut_windows.ps1 +20 -0
- traslado-2.0.0/scripts/versao.py +186 -0
- traslado-2.0.0/skills/traslado/SKILL.md +40 -0
- traslado-2.0.0/src/freoa_v6/__init__.py +53 -0
- traslado-2.0.0/src/traslado/__init__.py +4 -0
- traslado-2.0.0/src/traslado/__main__.py +6 -0
- traslado-2.0.0/src/traslado/advanced.py +179 -0
- traslado-2.0.0/src/traslado/assets/bootstrap_ocr.ps1 +303 -0
- traslado-2.0.0/src/traslado/assets/fixture.docx +0 -0
- traslado-2.0.0/src/traslado/assets/fixture.pdf +33 -0
- traslado-2.0.0/src/traslado/assets/ocr-assets.lock.json +437 -0
- traslado-2.0.0/src/traslado/assets/traslado.png +0 -0
- traslado-2.0.0/src/traslado/chunks.py +466 -0
- traslado-2.0.0/src/traslado/cli.py +236 -0
- traslado-2.0.0/src/traslado/detect.py +118 -0
- traslado-2.0.0/src/traslado/doctor.py +63 -0
- traslado-2.0.0/src/traslado/errors.py +88 -0
- traslado-2.0.0/src/traslado/formats.py +595 -0
- traslado-2.0.0/src/traslado/gui.py +781 -0
- traslado-2.0.0/src/traslado/legacy.py +248 -0
- traslado-2.0.0/src/traslado/lifecycle.py +1279 -0
- traslado-2.0.0/src/traslado/model.py +137 -0
- traslado-2.0.0/src/traslado/ocr.py +179 -0
- traslado-2.0.0/src/traslado/pathguard.py +18 -0
- traslado-2.0.0/src/traslado/pdf.py +520 -0
- traslado-2.0.0/src/traslado/platform.py +382 -0
- traslado-2.0.0/src/traslado/registry.py +122 -0
- traslado-2.0.0/src/traslado/render.py +189 -0
- traslado-2.0.0/src/traslado/review.py +55 -0
- traslado-2.0.0/src/traslado/revocation.py +444 -0
- traslado-2.0.0/src/traslado/runner.py +413 -0
- traslado-2.0.0/src/traslado/runtime.py +112 -0
- traslado-2.0.0/src/traslado/safety.py +275 -0
- traslado-2.0.0/src/traslado/windows_job.py +87 -0
- traslado-2.0.0/src/traslado/worker.py +126 -0
- traslado-2.0.0/tests/core-skips.txt +42 -0
- traslado-2.0.0/tests/fixtures/legacy/doc-fonte.rtf +1 -0
- traslado-2.0.0/tests/fixtures/legacy/gerar.ps1 +18 -0
- traslado-2.0.0/tests/fixtures/legacy/gerar.py +49 -0
- traslado-2.0.0/tests/fixtures/legacy/gerar_pptx.py +7 -0
- traslado-2.0.0/tests/fixtures/legacy/ppt-fonte.pptx +0 -0
- traslado-2.0.0/tests/fixtures/legacy/publico.doc +0 -0
- traslado-2.0.0/tests/fixtures/legacy/publico.doc.expected.json +33 -0
- traslado-2.0.0/tests/fixtures/legacy/publico.epub +0 -0
- traslado-2.0.0/tests/fixtures/legacy/publico.epub.expected.json +17 -0
- traslado-2.0.0/tests/fixtures/legacy/publico.odp +0 -0
- traslado-2.0.0/tests/fixtures/legacy/publico.odp.expected.json +15 -0
- traslado-2.0.0/tests/fixtures/legacy/publico.ods +0 -0
- traslado-2.0.0/tests/fixtures/legacy/publico.ods.expected.json +15 -0
- traslado-2.0.0/tests/fixtures/legacy/publico.odt +0 -0
- traslado-2.0.0/tests/fixtures/legacy/publico.odt.expected.json +43 -0
- traslado-2.0.0/tests/fixtures/legacy/publico.ppt +0 -0
- traslado-2.0.0/tests/fixtures/legacy/publico.ppt.expected.json +16 -0
- traslado-2.0.0/tests/fixtures/legacy/publico.rtf +1 -0
- traslado-2.0.0/tests/fixtures/legacy/publico.rtf.expected.json +36 -0
- traslado-2.0.0/tests/test_acceptance.py +284 -0
- traslado-2.0.0/tests/test_advanced_rc2.py +137 -0
- traslado-2.0.0/tests/test_boundaries.py +146 -0
- traslado-2.0.0/tests/test_chunk_transport_rc4.py +126 -0
- traslado-2.0.0/tests/test_chunks.py +142 -0
- traslado-2.0.0/tests/test_chunks_prose_fence_p6.py +96 -0
- traslado-2.0.0/tests/test_chunks_unclosed_p6.py +198 -0
- traslado-2.0.0/tests/test_cli_rc2.py +27 -0
- traslado-2.0.0/tests/test_compat_e1.py +286 -0
- traslado-2.0.0/tests/test_containment_e2.py +194 -0
- traslado-2.0.0/tests/test_corrections_rc7.py +182 -0
- traslado-2.0.0/tests/test_corrections_rc9.py +364 -0
- traslado-2.0.0/tests/test_detect_e3.py +139 -0
- traslado-2.0.0/tests/test_document_warnings_rc2.py +27 -0
- traslado-2.0.0/tests/test_docx_notes_t11.py +294 -0
- traslado-2.0.0/tests/test_e5_corrections.py +625 -0
- traslado-2.0.0/tests/test_errors_e3.py +216 -0
- traslado-2.0.0/tests/test_fechamento_e10.py +112 -0
- traslado-2.0.0/tests/test_fidelity_rc2.py +283 -0
- traslado-2.0.0/tests/test_furniture_t11.py +225 -0
- traslado-2.0.0/tests/test_gui_rc2.py +178 -0
- traslado-2.0.0/tests/test_gui_rc3.py +251 -0
- traslado-2.0.0/tests/test_gui_rc6.py +174 -0
- traslado-2.0.0/tests/test_gui_smoke_e6.py +148 -0
- traslado-2.0.0/tests/test_installer_rc3.py +279 -0
- traslado-2.0.0/tests/test_integrity_rc2.py +92 -0
- traslado-2.0.0/tests/test_large_scan_rc4.py +155 -0
- traslado-2.0.0/tests/test_launcher_rc3.py +103 -0
- traslado-2.0.0/tests/test_layout_publication_rc6.py +54 -0
- traslado-2.0.0/tests/test_legacy_e4.py +348 -0
- traslado-2.0.0/tests/test_legacy_r2.py +32 -0
- traslado-2.0.0/tests/test_lifecycle_e5.py +866 -0
- traslado-2.0.0/tests/test_minor_rc3.py +132 -0
- traslado-2.0.0/tests/test_mutation_e6.py +201 -0
- traslado-2.0.0/tests/test_ocr_bootstrap_rc3.py +166 -0
- traslado-2.0.0/tests/test_ocr_concurrency_t11.py +379 -0
- traslado-2.0.0/tests/test_ocr_geometry_t11.py +329 -0
- traslado-2.0.0/tests/test_onedrive_rc5.py +123 -0
- traslado-2.0.0/tests/test_output_layout_rc4.py +219 -0
- traslado-2.0.0/tests/test_pdf_lines_t11.py +225 -0
- traslado-2.0.0/tests/test_platform_e2.py +141 -0
- traslado-2.0.0/tests/test_readable_rc6.py +288 -0
- traslado-2.0.0/tests/test_registry_t11.py +341 -0
- traslado-2.0.0/tests/test_release_t11.py +705 -0
- traslado-2.0.0/tests/test_residual_e3e4.py +180 -0
- traslado-2.0.0/tests/test_review_e23fix.py +282 -0
- traslado-2.0.0/tests/test_runtime_rc3.py +132 -0
- traslado-2.0.0/tests/test_scan_stamp_t11.py +158 -0
- traslado-2.0.0/tests/test_scripts_e6.py +182 -0
- traslado-2.0.0/tests/test_security_review_rc3.py +332 -0
- traslado-2.0.0/tests/test_word_overlap_rc8.py +53 -0
traslado-2.0.0/ABRIR.bat
ADDED
traslado-2.0.0/ABRIR.ps1
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
# Copyright (C) 2026 Ricardo Peres Freoa
|
|
3
|
+
param([string]$InstallRoot=(Join-Path $env:LOCALAPPDATA 'Freoa\MarkdownConverter'))
|
|
4
|
+
$ErrorActionPreference='Stop'
|
|
5
|
+
$taskRoot=[IO.Path]::GetFullPath($InstallRoot)
|
|
6
|
+
$taskRecord=Get-Content -LiteralPath (Join-Path $taskRoot 'current.json') -Raw -Encoding UTF8 | ConvertFrom-Json
|
|
7
|
+
$taskOwner=Get-Content -LiteralPath (Join-Path $taskRoot '.freoa-installation.json') -Raw -Encoding UTF8 | ConvertFrom-Json
|
|
8
|
+
if ($taskRecord.product -ne 'freoa-md-converter' -or $taskRecord.install_id -ne $taskOwner.install_id -or
|
|
9
|
+
$taskRecord.release_id -notmatch '^[0-9A-Za-z.-]+_[0-9a-f]{32}$') { throw 'Registro de instalação inválido.' }
|
|
10
|
+
$taskRelease=Join-Path (Join-Path $taskRoot 'releases') $taskRecord.release_id
|
|
11
|
+
foreach($taskItem in @($taskRoot,$taskRelease,(Join-Path $taskRelease '.venv'))) {
|
|
12
|
+
if ((Get-Item -LiteralPath $taskItem -Force).Attributes -band [IO.FileAttributes]::ReparsePoint) { throw 'Instalação não pode ser link/junction.' }
|
|
13
|
+
}
|
|
14
|
+
$taskPythonW=Join-Path $taskRelease '.venv\Scripts\pythonw.exe'
|
|
15
|
+
if (-not (Test-Path -LiteralPath $taskPythonW)) { throw 'Instale o conversor primeiro com INSTALAR.bat.' }
|
|
16
|
+
Start-Process -FilePath $taskPythonW -ArgumentList @('-I','-m','freoa_v6','gui') -WorkingDirectory $taskRecord.data_root -WindowStyle Normal
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Histórico de versões
|
|
2
|
+
|
|
3
|
+
Ricardo Peres Freoa | Stocche Forbes Advogados
|
|
4
|
+
|
|
5
|
+
## 2.0.0
|
|
6
|
+
|
|
7
|
+
- **Licença**: código próprio sob `AGPL-3.0-or-later` (`LICENCE`), cabeçalhos SPDX em todos os fontes; `THIRD-PARTY.md`, inventário e política de licenças (`LICENSE-POLICY.md`) atualizados.
|
|
8
|
+
- **Instalação sem administrador e sem Python prévio** em Windows, Linux e macOS (one-liner, atalho clicável ou `traslado setup`): uv e Python 3.13 gerenciados e fixados por SHA-256, dependências com `--require-hashes`, release candidata em `releases/<id>/` promovida atomicamente a `current.json` só com doctor, fixture e revogação aprovados; `-NoPromote`/`--no-promote` qualifica a candidata lado a lado sem promover.
|
|
9
|
+
- **Autenticidade em dois canais**: `SHA256SUMS` e GitHub Attestations do `release.yml`; no modo remoto, digests conferidos na API de releases antes de instalar qualquer coisa (sem exigir Python no sistema); revogação por `revoked.json` atestado, com sequência monotônica e validade de 14 dias. Exceção offline só explícita (`--allow-offline-promotion` com `TRASLADO_PROMOCAO_OFFLINE=rascunho|teste`).
|
|
10
|
+
- **Ciclo de vida pelo CLI**: `where`, `update`, `rollback`, `uninstall` (preserva sempre `data_root`; no Windows, o que o próprio processo prende é removido logo após a saída dele), `shortcuts`.
|
|
11
|
+
- **CI** em Windows, Ubuntu e macOS, Python 3.11 a 3.14, perfis Core, Full e legacy contra o wheel instalado; mutação, contenção, E2E em contêineres Debian e Fedora mínimos, Windows e macOS, auditoria das bibliotecas dinâmicas carregadas; release em rascunho com bytes idênticos aos testados no CI; PyPI por trusted publishing só após publicação manual.
|
|
12
|
+
- **GUI**: prévia quebra visualmente sequências longas sem espaço (o texto não muda).
|
|
13
|
+
- `needs_ocr` no Linux indica o comando do gerenciador da distribuição (apt, dnf, zypper, pacman ou apk, por `/etc/os-release`); ZIP com método de compressão, versão ou criptografia não suportados resulta em `unsupported`/`encrypted`, não em `internal`.
|
|
14
|
+
- `--version` de `update` recusa o prefixo `v`; sem `gh`, a conferência do `revoked.json` não é criptográfica (presença e SAN declarado).
|
|
15
|
+
- Limite conhecido: no Windows Server Core a extensão nativa do PyMuPDF não carrega (DLL de sistema ausente); a instalação falha fechada, sem promover.
|
|
16
|
+
- **Instalação pelo ZIP extraído** (`INSTALAR.bat`, `instalar.sh`): `install.ps1`/`install.sh` com `-FromDir`/`--from-dir` procuram primeiro o layout do ZIP (`dist/`, `locks/`) e só depois o layout plano dos ativos da release. Antes, a raiz do ZIP trazia o `requirements-full.hashes.lock` do instalador legado (linha 1.x), homônimo do lock 2.0, e a instalação Full pelo ZIP recusava por SHA-256 divergente (falha fechada, sem instalar nada). Teste da instalação pelo ZIP passa a cobrir Core, Full e Full com `legacy`.
|
|
17
|
+
- `install.ps1` com a saída redirecionada dentro do Windows PowerShell 5.1 (`*>`, `2>&1`) não aborta mais quando o uv escreve progresso em stderr; o resultado de cada etapa continua decidido pelo código de saída. README: seção de instalação no Windows reescrita para o fluxo 2.0; `INSTALAR.ps1` documentado como instalador legado da linha 1.x.
|
|
18
|
+
|
|
19
|
+
- Extra `legacy` com anydoc 0.2.4 para DOC, RTF, ODT, ODS, ODP, PPT e EPUB,
|
|
20
|
+
somente com ativação explícita no CLI/TOML. XLS permanece não suportado.
|
|
21
|
+
- Adaptador local no worker contido, erros tipados, notas, tabelas e proveniência
|
|
22
|
+
experimental em documento/manifesto; doctor informa disponibilidade.
|
|
23
|
+
- Fixtures sintéticas públicas, gabaritos estruturais e mutações determinísticas.
|
|
24
|
+
A GUI ainda não oferece seleção do motor legado.
|
|
25
|
+
- Detecção pelo conteúdo para PDF, OOXML, imagens cadastradas e HTML; extensão divergente gera `format_extension_mismatch`, com despacho pelo formato detectado. OLE2, RTF, ODF e EPUB são identificados para diagnóstico e recusados pelo perfil padrão.
|
|
26
|
+
- Erros tipados no worker, no resultado por arquivo e no stderr do CLI, com `error_pages` para OCR indisponível; códigos de saída e mensagens anteriores preservados.
|
|
27
|
+
- Distribuição e módulo `traslado`, com aliases de módulo `freoa_v6` na série 2.x.
|
|
28
|
+
- Comandos `traslado` e `traslado-gui`; aliases `freoa-md` e `freoa-md-gui` mantidos.
|
|
29
|
+
- Artefatos e avisos de conversão preservados; doctor informa o módulo.
|
|
30
|
+
|
|
31
|
+
## 1.1.0
|
|
32
|
+
|
|
33
|
+
### Conversão
|
|
34
|
+
- **DOCX: notas de rodapé e de fim** como notas Markdown (`[^n]`), ligadas às definições de `footnotes.xml` e `endnotes.xml`, com famílias distintas e separadores ignorados. Vale também para `.doc`, `.rtf` e `.odt` que chegam como `.docx`. Avisos por espécie de perda remanescente substituem o aviso agregado da 1.0.0: `docx_note_reference_unresolved`, `docx_note_definition_unreferenced`, `docx_note_duplicate_or_missing_id`, `docx_note_complex_content_flattened`, `docx_headers_footers_not_extracted`, `docx_comments_not_extracted`.
|
|
35
|
+
- **OCR com geometria**: um bloco por parágrafo do Tesseract, com caixa em coordenadas da folha (escala, origem e rotação do raster), confiança média por bloco e sequência de palavras idêntica à do TXT da mesma execução; divergência recai no texto sem geometria, com aviso `ocr_geometry_fallback`. O TSV é lido sem tratamento de aspas, e palavra sem escore conserva a caixa e fica fora da média. Efeito no Markdown das páginas com OCR: mesmas palavras, um parágrafo por linha.
|
|
36
|
+
- **PDF nativo: linhas e spans** (caixa, tamanho de fonte, flags) sob os blocos, só em `document-layout.json`; o refino avançado não recebe essa geometria.
|
|
37
|
+
- **Mobiliário de página** (`furniture = "mark"`, padrão; `--furniture off|mark`): cabeçalhos corridos, rodapés e fólios classificados com `role: furniture` nos chunks, nas faixas de borda da página exibida; romanos só quando canônicos. Nenhum texto é omitido.
|
|
38
|
+
- **Folha escaneada com carimbo**: imagem única cobrindo ao menos metade da folha, com pouca área de texto visível ou camada invisível, vai a OCR.
|
|
39
|
+
- **OCR concorrente** por folha (`ocr_workers`, 1 a 4, padrão 4; `--ocr-workers`), com fila limitada, ordem determinística e resultado idêntico ao serial. Em cinco obras escaneadas (18 a 134 folhas), o tempo total caiu de 833 s para 321 s. O Tesseract roda com `OMP_THREAD_LIMIT=1`, na sessão do worker, encerrado com ele.
|
|
40
|
+
- **Registro único de conversores**: despacho por extensão, descoberta e `doctor` leem o mesmo cadastro; indisponibilidade vira recusa com motivo.
|
|
41
|
+
|
|
42
|
+
### Distribuição
|
|
43
|
+
- Versão única em `src/freoa_v6/__init__.py`; `converter_version` do documento deriva dela.
|
|
44
|
+
- CI em Windows e Linux, perfis Core e Full, Python 3.11 a 3.14; release por tag cria apenas rascunho, depois da matriz verde no mesmo commit.
|
|
45
|
+
- Seleção explícita dos arquivos distribuídos (`release-files.txt`), wheel construído da seleção, ZIP determinístico, `SHA256SUMS`, attestation e varredura de bytes de PyMuPDF/MuPDF no pacote.
|
|
46
|
+
- Inventário de terceiros confrontado com locks, downloads, membros extraídos, modelos e licenças.
|
|
47
|
+
- Windows: busca do Tesseract no PATH sem `shutil.which` (PATHEXT vazio usa o padrão; entradas relativas e o diretório corrente excluídos).
|
|
48
|
+
|
|
49
|
+
### Fora desta versão
|
|
50
|
+
- Ordem de leitura por calhas (`layout = gutters`): nas folhas de referência, as folhas fora de ordem passaram de 20 para 30. Não incluída.
|
|
51
|
+
- Omissão de mobiliário (`furniture = omit`): exige mapa de paginação independente do texto.
|
|
52
|
+
- Licença do perfil Full (PyMuPDF): questão aberta; consulte THIRD-PARTY.md.
|
|
53
|
+
|
|
54
|
+
## 1.0.0
|
|
55
|
+
|
|
56
|
+
Primeira versão pública (antes Freoa Markdown Converter 6.0.0rc9). Ver a seção "Novidades da 1.0.0" do README.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
@echo off
|
|
2
|
+
REM SPDX-License-Identifier: AGPL-3.0-or-later
|
|
3
|
+
REM Copyright (C) 2026 Ricardo Peres Freoa
|
|
4
|
+
REM Fonte correspondente: https://github.com/rickfreoa/traslado/tree/v2.0.0
|
|
5
|
+
"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoLogo -NoProfile -ExecutionPolicy Bypass -File "%~dp0install.ps1" -FromDir "%~dp0." %*
|
|
6
|
+
if errorlevel 1 (
|
|
7
|
+
echo Instalacao nao concluida. Leia a mensagem acima.
|
|
8
|
+
pause
|
|
9
|
+
exit /b %errorlevel%
|
|
10
|
+
)
|
|
11
|
+
echo Instalacao concluida. Use o atalho Traslado na Area de Trabalho ou no Menu Iniciar.
|
|
12
|
+
pause
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
# Copyright (C) 2026 Ricardo Peres Freoa
|
|
3
|
+
[CmdletBinding()]
|
|
4
|
+
param(
|
|
5
|
+
[ValidateSet('Full','Core')][string]$Profile = 'Full',
|
|
6
|
+
[string]$Python,
|
|
7
|
+
[string]$InstallRoot = (Join-Path $env:LOCALAPPDATA 'Freoa\MarkdownConverter'),
|
|
8
|
+
[string]$DataRoot = (Join-Path ([Environment]::GetFolderPath('MyDocuments')) 'Freoa Markdown Converter'),
|
|
9
|
+
[string]$ShortcutDirectory = ([Environment]::GetFolderPath('Desktop')),
|
|
10
|
+
[string[]]$OCRLanguages = @('por','eng','spa','ita','fra','deu'),
|
|
11
|
+
[switch]$SkipOCR,
|
|
12
|
+
[switch]$NoShortcut,
|
|
13
|
+
[switch]$Launch,
|
|
14
|
+
[string]$LegacyRoot
|
|
15
|
+
)
|
|
16
|
+
$ErrorActionPreference = 'Stop'
|
|
17
|
+
[Console]::OutputEncoding = [Text.UTF8Encoding]::new($false)
|
|
18
|
+
$OutputEncoding = [Console]::OutputEncoding
|
|
19
|
+
function Find-TaskPython {
|
|
20
|
+
param([string]$Command, [string[]]$Leading=@())
|
|
21
|
+
try {
|
|
22
|
+
$taskFound = & $Command @Leading -I -S -X utf8 -c 'import sys,tkinter; print(sys._base_executable); sys.exit(0 if (3,11)<=sys.version_info[:2]<(3,15) else 9)' 2>$null
|
|
23
|
+
if ($LASTEXITCODE -eq 0 -and $taskFound) { return ($taskFound | Select-Object -Last 1) }
|
|
24
|
+
} catch {}
|
|
25
|
+
return $null
|
|
26
|
+
}
|
|
27
|
+
if ($Python) {
|
|
28
|
+
$taskPython = Find-TaskPython $Python
|
|
29
|
+
} else {
|
|
30
|
+
$taskPython = $null
|
|
31
|
+
if (Get-Command py -ErrorAction SilentlyContinue) {
|
|
32
|
+
foreach ($taskVersion in @('-3.14','-3.13','-3.12','-3.11')) {
|
|
33
|
+
$taskPython = Find-TaskPython 'py' @($taskVersion)
|
|
34
|
+
if ($taskPython) { break }
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (-not $taskPython -and (Get-Command python -ErrorAction SilentlyContinue)) { $taskPython = Find-TaskPython 'python' }
|
|
38
|
+
}
|
|
39
|
+
if (-not $taskPython) { throw 'Instale Python 3.11–3.14 com Tcl/Tk. O Python deve vir de uma instalação confiável.' }
|
|
40
|
+
$taskArgs = @('-I', '-X', 'utf8', (Join-Path $PSScriptRoot 'scripts\install_windows.py'),
|
|
41
|
+
'--package', $PSScriptRoot, '--root', $InstallRoot, '--data-root', $DataRoot,
|
|
42
|
+
'--shortcut-directory', $ShortcutDirectory, '--profile', $Profile,
|
|
43
|
+
'--languages', ($OCRLanguages -join ','))
|
|
44
|
+
if ($SkipOCR) { $taskArgs += '--skip-ocr' }
|
|
45
|
+
if ($NoShortcut) { $taskArgs += '--no-shortcut' }
|
|
46
|
+
if ($Launch) { $taskArgs += '--launch' }
|
|
47
|
+
if ($LegacyRoot) { $taskArgs += @('--legacy-root', $LegacyRoot) }
|
|
48
|
+
& $taskPython @taskArgs
|
|
49
|
+
if ($LASTEXITCODE -ne 0) { throw 'Instalação não concluída. A versão anterior foi preservada quando possível; confira o diagnóstico.' }
|