slideshow-vault 1.3.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.
- slideshow_vault-1.3.0/.gitignore +65 -0
- slideshow_vault-1.3.0/500px - Slideshow.py +16 -0
- slideshow_vault-1.3.0/COMO_COMPILAR.md +60 -0
- slideshow_vault-1.3.0/LICENSE +21 -0
- slideshow_vault-1.3.0/PKG-INFO +153 -0
- slideshow_vault-1.3.0/README.md +127 -0
- slideshow_vault-1.3.0/build.py +154 -0
- slideshow_vault-1.3.0/build_nuitka.bat +8 -0
- slideshow_vault-1.3.0/build_pyinstaller.bat +8 -0
- slideshow_vault-1.3.0/pyproject.toml +45 -0
- slideshow_vault-1.3.0/run.py +14 -0
- slideshow_vault-1.3.0/src/slideshow/__init__.py +25 -0
- slideshow_vault-1.3.0/src/slideshow/__main__.py +6 -0
- slideshow_vault-1.3.0/src/slideshow/app.py +1159 -0
- slideshow_vault-1.3.0/src/slideshow/assets/icon.ico +0 -0
- slideshow_vault-1.3.0/src/slideshow/assets/icon.png +0 -0
- slideshow_vault-1.3.0/src/slideshow/buffer.py +101 -0
- slideshow_vault-1.3.0/src/slideshow/cli.py +130 -0
- slideshow_vault-1.3.0/src/slideshow/core.py +173 -0
- slideshow_vault-1.3.0/src/slideshow/display.py +261 -0
- slideshow_vault-1.3.0/src/slideshow/favorites.py +312 -0
- slideshow_vault-1.3.0/src/slideshow/vault.py +254 -0
- slideshow_vault-1.3.0/tests/test_slideshow.py +289 -0
- slideshow_vault-1.3.0/uv.lock +689 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
*.manifest
|
|
31
|
+
*.spec
|
|
32
|
+
|
|
33
|
+
# Nuitka build artifacts
|
|
34
|
+
*.build/
|
|
35
|
+
*.dist/
|
|
36
|
+
*.onefile-build/
|
|
37
|
+
nuitka-crash-report.xml
|
|
38
|
+
|
|
39
|
+
# Environments
|
|
40
|
+
.env
|
|
41
|
+
.venv
|
|
42
|
+
env/
|
|
43
|
+
venv/
|
|
44
|
+
ENV/
|
|
45
|
+
env.bak/
|
|
46
|
+
venv.bak/
|
|
47
|
+
|
|
48
|
+
# Editor / IDE
|
|
49
|
+
.vscode/
|
|
50
|
+
.idea/
|
|
51
|
+
*.swp
|
|
52
|
+
*.swo
|
|
53
|
+
|
|
54
|
+
# Testing & Cache
|
|
55
|
+
.pytest_cache/
|
|
56
|
+
.coverage
|
|
57
|
+
htmlcov/
|
|
58
|
+
|
|
59
|
+
# Logs & Reports
|
|
60
|
+
*.log
|
|
61
|
+
*.xml
|
|
62
|
+
|
|
63
|
+
# Local user data & favorites
|
|
64
|
+
*.xlsx
|
|
65
|
+
*.xlsx.tmp
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Wrapper de compatibilidade para o antigo 500px - Slideshow.py.
|
|
2
|
+
Executa a nova engine modular do Slideshow Pro.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import sys
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
# Garante inclusão de src no caminho de busca
|
|
9
|
+
src_path = str(Path(__file__).resolve().parent / "src")
|
|
10
|
+
if src_path not in sys.path:
|
|
11
|
+
sys.path.insert(0, src_path)
|
|
12
|
+
|
|
13
|
+
from slideshow.cli import main
|
|
14
|
+
|
|
15
|
+
if __name__ == "__main__":
|
|
16
|
+
main()
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Guia de Compilação de Executáveis (.exe)
|
|
2
|
+
|
|
3
|
+
O **Slideshow Pro** oferece suporte completo e automatizado para geração de executáveis para Windows tanto pelo **Nuitka** (método preferencial, gera código C nativo otimizado e mais rápido) quanto pelo **PyInstaller** (método tradicional).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🛠️ Por que o Nuitka falhava anteriormente?
|
|
8
|
+
|
|
9
|
+
Ao compilar aplicações Tkinter e Pillow no Windows, o Nuitka requer flags específicas que frequentemente causam erros se omitidas:
|
|
10
|
+
1. **Falta do plugin Tkinter** (`--enable-plugin=tk-inter`): Sem este plugin, o Nuitka não empacota os arquivos de suporte `init.tcl`, bibliotecas Tcl/Tk e DLLs, resultando em erro `TclError: Can't find a usable init.tcl` ao abrir o executável.
|
|
11
|
+
2. **Empacotamento de pacotes dinâmicos** (`--include-package=PIL`, `--include-package=openpyxl`, `--include-package=slideshow`): Pillow e openpyxl carregam submódulos dinamicamente que precisam ser incluídos explicitamente.
|
|
12
|
+
3. **Ausência de compilador C no Windows**: O Nuitka compila Python para C e precisa de um compilador (MSVC ou MinGW64). Com a flag `--assume-yes-for-downloads`, o Nuitka baixa e configura automaticamente o MinGW64 oficial sem requerer nenhuma intervenção manual.
|
|
13
|
+
4. **Modo sem console para GUI**: `--windows-console-mode=disable` oculta a janela preta de terminal do DOS.
|
|
14
|
+
|
|
15
|
+
Todos esses parâmetros já foram integrados e automatizados no [`build.py`](build.py).
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 🚀 Como Compilar
|
|
20
|
+
|
|
21
|
+
### Opção 1: Via Scripts `.bat` (Um Clique)
|
|
22
|
+
|
|
23
|
+
- Para compilar com **Nuitka** (Preferencial):
|
|
24
|
+
Basta dar um duplo-clique no arquivo:
|
|
25
|
+
`build_nuitka.bat`
|
|
26
|
+
|
|
27
|
+
- Para compilar com **PyInstaller**:
|
|
28
|
+
Basta dar um duplo-clique no arquivo:
|
|
29
|
+
`build_pyinstaller.bat`
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
### Opção 2: Via Terminal com `uv`
|
|
34
|
+
|
|
35
|
+
Com o `uv` instalado, execute no terminal:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# Compilação preferencial com Nuitka (usando ambiente isolado)
|
|
39
|
+
uv run --isolated --python 3.12 --with nuitka --with zstandard python build.py --nuitka
|
|
40
|
+
|
|
41
|
+
# Compilação com PyInstaller
|
|
42
|
+
uv run --isolated --python 3.12 --with pyinstaller python build.py --pyinstaller
|
|
43
|
+
|
|
44
|
+
# Compilar ambos
|
|
45
|
+
uv run --isolated --python 3.12 --with nuitka --with pyinstaller --with zstandard python build.py --all
|
|
46
|
+
|
|
47
|
+
# Limpar artefatos temporários de compilação
|
|
48
|
+
uv run python build.py --clean
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 📂 Onde encontrar os executáveis gerados?
|
|
54
|
+
|
|
55
|
+
Após a compilação, os artefatos estarão disponíveis na pasta:
|
|
56
|
+
- `dist/Slideshow/Slideshow.exe` (Pasta portátil com inicialização ultrarrápida)
|
|
57
|
+
- `dist/Slideshow-Portatil.zip` (Arquivo compactado pronto para envio a outras pessoas)
|
|
58
|
+
- `dist/Slideshow-PyInstaller.exe` (Executável alternativo via PyInstaller)
|
|
59
|
+
|
|
60
|
+
O aplicativo portátil pode ser transportado ou compartilhado para qualquer computador com Windows sem necessidade de ter o Python ou o `uv` instalados. Basta descompactar o `.zip` e executar `Slideshow.exe`.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Slideshow Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: slideshow-vault
|
|
3
|
+
Version: 1.3.0
|
|
4
|
+
Summary: Apresentador de slides moderno, resiliente a OneDrive Personal Vault, com transições suaves, favoritos em SQLite (com exportação/importação Excel) e controle avançado.
|
|
5
|
+
Author: Slideshow Developer
|
|
6
|
+
License: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Keywords: ken-burns,onedrive,personal-vault,photo-viewer,slideshow,tkinter
|
|
9
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Topic :: Multimedia :: Graphics :: Viewers
|
|
16
|
+
Requires-Python: >=3.9
|
|
17
|
+
Requires-Dist: openpyxl>=3.1.0
|
|
18
|
+
Requires-Dist: pillow>=10.0.0
|
|
19
|
+
Provides-Extra: build
|
|
20
|
+
Requires-Dist: nuitka>=2.0.0; extra == 'build'
|
|
21
|
+
Requires-Dist: pyinstaller>=6.0.0; extra == 'build'
|
|
22
|
+
Requires-Dist: zstandard; extra == 'build'
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# Slideshow Pro
|
|
28
|
+
|
|
29
|
+
Um apresentador de slides moderno, resiliente, modular e extensível para Windows e Linux, com suporte aprofundado ao **Cofre Pessoal (Personal Vault) do OneDrive**, transições audiovisuais cinematográficas e sistema de favoritos em SQLite com exportação/importação para Excel.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 🌟 Principais Recursos
|
|
34
|
+
|
|
35
|
+
- **Módulo Python Reutilizável**: Instale via `pip`/`uv` ou importe diretamente em outros programas (`from slideshow import run_slideshow`).
|
|
36
|
+
- **Resiliência ao Cofre Pessoal do OneDrive**:
|
|
37
|
+
- Detecção inteligente do estado do cofre (montado vs. bloqueado/desmontado).
|
|
38
|
+
- Identificação de arquivos em nuvem (*Files On-Demand* desidratados).
|
|
39
|
+
- **Buffer em RAM condicional com teto de 1 GB**: lê fotos para a memória na inicialização se estiverem no cofre, evitando que o fechamento por inatividade (20 min) do BitLocker interrompa a reprodução.
|
|
40
|
+
- Se for uma pasta comum, lê sob demanda do disco com consumo mínimo de memória.
|
|
41
|
+
- **Transições Suaves**:
|
|
42
|
+
- **Crossfade**: Dissolvência suave entre imagens via interpolação de canais.
|
|
43
|
+
- **Dura**: Corte seco tradicional.
|
|
44
|
+
- **Fade to Black**: Esmaecimento para o preto.
|
|
45
|
+
- **Modos de Enquadramento**:
|
|
46
|
+
- **Ajustar (Fit)**: Imagem inteira visível sem distorção.
|
|
47
|
+
- **Zoom / Preencher (Fill)**: Cobre 100% da janela centralizada.
|
|
48
|
+
- **Panorâmico (Ken Burns Pan & Scan)**: A foto preenche a janela e se move suavemente de uma borda a outra durante o slide.
|
|
49
|
+
- **Histórico Infinito no Modo Aleatório**:
|
|
50
|
+
- O botão de voltar (Seta Esquerda) funciona retroativamente por toda a trilha de fotos exibidas, sem limite.
|
|
51
|
+
- **Sistema de Likes, Unlikes e Favoritos em SQLite**:
|
|
52
|
+
- Registrado automaticamente no banco `~/slideshow_favoritos.db` (gravação transacional, sem risco de corromper o arquivo).
|
|
53
|
+
- **Exportar (`Ctrl+E`)**: gera uma planilha `.xlsx` (abas `Favoritos`, `Unlikes`, `Configuracoes`).
|
|
54
|
+
- **Importar (`Ctrl+I`)**: lê um `.xlsx` e **substitui tudo** (favoritos, unlikes e configurações) após confirmação. Planilha inválida não altera nada.
|
|
55
|
+
- Via linha de comando: `--export-favorites ARQ.xlsx` e `--import-favorites ARQ.xlsx`.
|
|
56
|
+
- **Like (`L`)**: adiciona aos favoritos. Se a foto possuir Unlike, o primeiro toque cancela o unlike.
|
|
57
|
+
- **Unlike (`U`)**: marca como unlike. Se a foto possuir Like, o primeiro toque desfaz o like.
|
|
58
|
+
- **Ícones de Status Visuais**: exibe ❤️ (Like) ou ❌ (Unlike) no canto superior direito (alternável via tecla **`I`**).
|
|
59
|
+
- **Filtro Trilateral (`F`)**: alterna entre *Todas as Fotos*, *Apenas Favoritas* e *Apenas Unlikes*.
|
|
60
|
+
- **Exclusão em Lote (`Shift+Delete`)**: quando no modo de filtro *Apenas Unlikes*, permite listar e apagar permanentemente todas as fotos com unlike do disco após confirmação segura.
|
|
61
|
+
- **Persistência Automática de Preferências**:
|
|
62
|
+
- Salva automaticamente as últimas configurações (velocidade, enquadramento, transição, ordem, legenda, tela cheia, fixação no topo e melhoria de baixa resolução) no banco do usuário.
|
|
63
|
+
- Ao abrir o Slideshow novamente, suas preferências são restauradas instantaneamente.
|
|
64
|
+
- **Otimização Inteligente de Fotos em Baixa Resolução (`E`)**:
|
|
65
|
+
- Reescalonamento Lanczos de alta precisão, filtro Unsharp Mask adaptativo, granulação analógica suave (Film Grain) e desfoque de fundo ambiente.
|
|
66
|
+
- **Janela de Ajuda Interativa (`F1`) e Controle com `Esc`**:
|
|
67
|
+
- A tecla **`F1`** abre e fecha a documentação de atalhos (*Toggle*).
|
|
68
|
+
- A tecla **`Esc`** fecha prioritariamente a janela de ajuda sem sair da tela cheia ou encerrar o slideshow.
|
|
69
|
+
- **Compilável com Nuitka e PyInstaller**: Scripts prontos para gerar executável standalone para Windows.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 🚀 Instalação e Execução
|
|
74
|
+
|
|
75
|
+
### Usando o `uv` (Recomendado)
|
|
76
|
+
```bash
|
|
77
|
+
# Execução direta informando a pasta de imagens
|
|
78
|
+
uv run python -m slideshow -p "C:\Fotos"
|
|
79
|
+
|
|
80
|
+
# A partir de qualquer diretório no sistema
|
|
81
|
+
uv run --project "C:\caminho\para\slideshow" python -m slideshow -p "C:\Fotos"
|
|
82
|
+
|
|
83
|
+
# Com opções de enquadramento panorâmico, transição suave e tela cheia
|
|
84
|
+
uv run python -m slideshow -p "C:\Fotos" -d 4.0 --fullscreen -m panoramic -t crossfade
|
|
85
|
+
|
|
86
|
+
# Ao executar sem argumentos, o seletor gráfico de pastas abrirá automaticamente
|
|
87
|
+
uv run python -m slideshow
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Como Módulo em Outros Projetos
|
|
91
|
+
```python
|
|
92
|
+
from slideshow import run_slideshow
|
|
93
|
+
|
|
94
|
+
# Chamada simples
|
|
95
|
+
run_slideshow(folder=r"C:\MinhasFotos", delay=4.0, fullscreen=True)
|
|
96
|
+
|
|
97
|
+
# Chamada com opções avançadas e suporte a Cofre Pessoal
|
|
98
|
+
run_slideshow(
|
|
99
|
+
folder=r"C:\MinhasFotos",
|
|
100
|
+
delay=5.0,
|
|
101
|
+
framing="panoramic",
|
|
102
|
+
transition="crossfade",
|
|
103
|
+
order="random",
|
|
104
|
+
ram_limit_mb=1024
|
|
105
|
+
)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## ⌨️ Atalhos de Teclado
|
|
111
|
+
|
|
112
|
+
| Tecla | Ação |
|
|
113
|
+
| :--- | :--- |
|
|
114
|
+
| **`F1`** | Abre / fecha a janela de ajuda flutuante (**Toggle**) |
|
|
115
|
+
| **`F11`** | Alterna o modo de Tela Cheia |
|
|
116
|
+
| **`Espaço`** | Pausar / Retomar apresentação |
|
|
117
|
+
| **`Seta Esquerda`** | Foto anterior (**Histórico Infinito**) |
|
|
118
|
+
| **`Seta Direita`** | Próxima foto |
|
|
119
|
+
| **`Seta Cima / Baixo`** | Acelerar / desacelerar intervalo |
|
|
120
|
+
| **`D`** | Digitar intervalo de tempo personalizado em segundos |
|
|
121
|
+
| **`O`** | Alternar ordem (Aleatória / Data / Alfabética) |
|
|
122
|
+
| **`L`** | Like ❤️ (Se possuir Unlike, o 1º aperto desfaz o unlike) |
|
|
123
|
+
| **`U`** | Unlike ❌ (Se possuir Like, o 1º aperto desfaz o like) |
|
|
124
|
+
| **`F`** | Alternar filtro: **Todas as Fotos** ➔ **Apenas Favoritas** ➔ **Apenas Unlikes** |
|
|
125
|
+
| **`I`** | Alternar exibição dos Ícones de Status (**❤️** / **❌**) no canto superior direito |
|
|
126
|
+
| **`Shift+Delete`** | Apagar permanentemente do disco todas as fotos com Unlike (ativo no filtro Unlikes) |
|
|
127
|
+
| **`E`** | Alternar Otimização de Baixa Resolução (Nitidez, Grão e Fundo Suave) |
|
|
128
|
+
| **`C`** | Alternar legenda (Oculta / Compacta / Detalhada) |
|
|
129
|
+
| **`M`** | Alternar modo de enquadramento (Ajustar / Zoom / Panorâmico) |
|
|
130
|
+
| **`X`** | Alternar estilo de transição (Suave Crossfade / Dura / Fade) |
|
|
131
|
+
| **`T` / `P`** | Alternar janela sempre no topo (Sempre Visível) |
|
|
132
|
+
| **`Esc`** | Fecha janela de ajuda (se aberta) / sai da tela cheia / encerra |
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## 🔍 Ferramenta de Diagnóstico do Cofre OneDrive
|
|
137
|
+
|
|
138
|
+
Para testar e inspecionar o status de acesso e atributos dos arquivos de qualquer diretório:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
uv run slideshow --check-vault -p "C:\caminho\para\pasta"
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## 📦 Construção de Executáveis (.exe)
|
|
147
|
+
|
|
148
|
+
Consulte o arquivo [`COMO_COMPILAR.md`](COMO_COMPILAR.md) para instruções completas sobre compilação com **Nuitka** (preferencial) e **PyInstaller**.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## 📄 Licença
|
|
153
|
+
Distribuído sob a licença MIT. Veja `LICENSE` para mais detalhes.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Slideshow Pro
|
|
2
|
+
|
|
3
|
+
Um apresentador de slides moderno, resiliente, modular e extensível para Windows e Linux, com suporte aprofundado ao **Cofre Pessoal (Personal Vault) do OneDrive**, transições audiovisuais cinematográficas e sistema de favoritos em SQLite com exportação/importação para Excel.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🌟 Principais Recursos
|
|
8
|
+
|
|
9
|
+
- **Módulo Python Reutilizável**: Instale via `pip`/`uv` ou importe diretamente em outros programas (`from slideshow import run_slideshow`).
|
|
10
|
+
- **Resiliência ao Cofre Pessoal do OneDrive**:
|
|
11
|
+
- Detecção inteligente do estado do cofre (montado vs. bloqueado/desmontado).
|
|
12
|
+
- Identificação de arquivos em nuvem (*Files On-Demand* desidratados).
|
|
13
|
+
- **Buffer em RAM condicional com teto de 1 GB**: lê fotos para a memória na inicialização se estiverem no cofre, evitando que o fechamento por inatividade (20 min) do BitLocker interrompa a reprodução.
|
|
14
|
+
- Se for uma pasta comum, lê sob demanda do disco com consumo mínimo de memória.
|
|
15
|
+
- **Transições Suaves**:
|
|
16
|
+
- **Crossfade**: Dissolvência suave entre imagens via interpolação de canais.
|
|
17
|
+
- **Dura**: Corte seco tradicional.
|
|
18
|
+
- **Fade to Black**: Esmaecimento para o preto.
|
|
19
|
+
- **Modos de Enquadramento**:
|
|
20
|
+
- **Ajustar (Fit)**: Imagem inteira visível sem distorção.
|
|
21
|
+
- **Zoom / Preencher (Fill)**: Cobre 100% da janela centralizada.
|
|
22
|
+
- **Panorâmico (Ken Burns Pan & Scan)**: A foto preenche a janela e se move suavemente de uma borda a outra durante o slide.
|
|
23
|
+
- **Histórico Infinito no Modo Aleatório**:
|
|
24
|
+
- O botão de voltar (Seta Esquerda) funciona retroativamente por toda a trilha de fotos exibidas, sem limite.
|
|
25
|
+
- **Sistema de Likes, Unlikes e Favoritos em SQLite**:
|
|
26
|
+
- Registrado automaticamente no banco `~/slideshow_favoritos.db` (gravação transacional, sem risco de corromper o arquivo).
|
|
27
|
+
- **Exportar (`Ctrl+E`)**: gera uma planilha `.xlsx` (abas `Favoritos`, `Unlikes`, `Configuracoes`).
|
|
28
|
+
- **Importar (`Ctrl+I`)**: lê um `.xlsx` e **substitui tudo** (favoritos, unlikes e configurações) após confirmação. Planilha inválida não altera nada.
|
|
29
|
+
- Via linha de comando: `--export-favorites ARQ.xlsx` e `--import-favorites ARQ.xlsx`.
|
|
30
|
+
- **Like (`L`)**: adiciona aos favoritos. Se a foto possuir Unlike, o primeiro toque cancela o unlike.
|
|
31
|
+
- **Unlike (`U`)**: marca como unlike. Se a foto possuir Like, o primeiro toque desfaz o like.
|
|
32
|
+
- **Ícones de Status Visuais**: exibe ❤️ (Like) ou ❌ (Unlike) no canto superior direito (alternável via tecla **`I`**).
|
|
33
|
+
- **Filtro Trilateral (`F`)**: alterna entre *Todas as Fotos*, *Apenas Favoritas* e *Apenas Unlikes*.
|
|
34
|
+
- **Exclusão em Lote (`Shift+Delete`)**: quando no modo de filtro *Apenas Unlikes*, permite listar e apagar permanentemente todas as fotos com unlike do disco após confirmação segura.
|
|
35
|
+
- **Persistência Automática de Preferências**:
|
|
36
|
+
- Salva automaticamente as últimas configurações (velocidade, enquadramento, transição, ordem, legenda, tela cheia, fixação no topo e melhoria de baixa resolução) no banco do usuário.
|
|
37
|
+
- Ao abrir o Slideshow novamente, suas preferências são restauradas instantaneamente.
|
|
38
|
+
- **Otimização Inteligente de Fotos em Baixa Resolução (`E`)**:
|
|
39
|
+
- Reescalonamento Lanczos de alta precisão, filtro Unsharp Mask adaptativo, granulação analógica suave (Film Grain) e desfoque de fundo ambiente.
|
|
40
|
+
- **Janela de Ajuda Interativa (`F1`) e Controle com `Esc`**:
|
|
41
|
+
- A tecla **`F1`** abre e fecha a documentação de atalhos (*Toggle*).
|
|
42
|
+
- A tecla **`Esc`** fecha prioritariamente a janela de ajuda sem sair da tela cheia ou encerrar o slideshow.
|
|
43
|
+
- **Compilável com Nuitka e PyInstaller**: Scripts prontos para gerar executável standalone para Windows.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 🚀 Instalação e Execução
|
|
48
|
+
|
|
49
|
+
### Usando o `uv` (Recomendado)
|
|
50
|
+
```bash
|
|
51
|
+
# Execução direta informando a pasta de imagens
|
|
52
|
+
uv run python -m slideshow -p "C:\Fotos"
|
|
53
|
+
|
|
54
|
+
# A partir de qualquer diretório no sistema
|
|
55
|
+
uv run --project "C:\caminho\para\slideshow" python -m slideshow -p "C:\Fotos"
|
|
56
|
+
|
|
57
|
+
# Com opções de enquadramento panorâmico, transição suave e tela cheia
|
|
58
|
+
uv run python -m slideshow -p "C:\Fotos" -d 4.0 --fullscreen -m panoramic -t crossfade
|
|
59
|
+
|
|
60
|
+
# Ao executar sem argumentos, o seletor gráfico de pastas abrirá automaticamente
|
|
61
|
+
uv run python -m slideshow
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Como Módulo em Outros Projetos
|
|
65
|
+
```python
|
|
66
|
+
from slideshow import run_slideshow
|
|
67
|
+
|
|
68
|
+
# Chamada simples
|
|
69
|
+
run_slideshow(folder=r"C:\MinhasFotos", delay=4.0, fullscreen=True)
|
|
70
|
+
|
|
71
|
+
# Chamada com opções avançadas e suporte a Cofre Pessoal
|
|
72
|
+
run_slideshow(
|
|
73
|
+
folder=r"C:\MinhasFotos",
|
|
74
|
+
delay=5.0,
|
|
75
|
+
framing="panoramic",
|
|
76
|
+
transition="crossfade",
|
|
77
|
+
order="random",
|
|
78
|
+
ram_limit_mb=1024
|
|
79
|
+
)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## ⌨️ Atalhos de Teclado
|
|
85
|
+
|
|
86
|
+
| Tecla | Ação |
|
|
87
|
+
| :--- | :--- |
|
|
88
|
+
| **`F1`** | Abre / fecha a janela de ajuda flutuante (**Toggle**) |
|
|
89
|
+
| **`F11`** | Alterna o modo de Tela Cheia |
|
|
90
|
+
| **`Espaço`** | Pausar / Retomar apresentação |
|
|
91
|
+
| **`Seta Esquerda`** | Foto anterior (**Histórico Infinito**) |
|
|
92
|
+
| **`Seta Direita`** | Próxima foto |
|
|
93
|
+
| **`Seta Cima / Baixo`** | Acelerar / desacelerar intervalo |
|
|
94
|
+
| **`D`** | Digitar intervalo de tempo personalizado em segundos |
|
|
95
|
+
| **`O`** | Alternar ordem (Aleatória / Data / Alfabética) |
|
|
96
|
+
| **`L`** | Like ❤️ (Se possuir Unlike, o 1º aperto desfaz o unlike) |
|
|
97
|
+
| **`U`** | Unlike ❌ (Se possuir Like, o 1º aperto desfaz o like) |
|
|
98
|
+
| **`F`** | Alternar filtro: **Todas as Fotos** ➔ **Apenas Favoritas** ➔ **Apenas Unlikes** |
|
|
99
|
+
| **`I`** | Alternar exibição dos Ícones de Status (**❤️** / **❌**) no canto superior direito |
|
|
100
|
+
| **`Shift+Delete`** | Apagar permanentemente do disco todas as fotos com Unlike (ativo no filtro Unlikes) |
|
|
101
|
+
| **`E`** | Alternar Otimização de Baixa Resolução (Nitidez, Grão e Fundo Suave) |
|
|
102
|
+
| **`C`** | Alternar legenda (Oculta / Compacta / Detalhada) |
|
|
103
|
+
| **`M`** | Alternar modo de enquadramento (Ajustar / Zoom / Panorâmico) |
|
|
104
|
+
| **`X`** | Alternar estilo de transição (Suave Crossfade / Dura / Fade) |
|
|
105
|
+
| **`T` / `P`** | Alternar janela sempre no topo (Sempre Visível) |
|
|
106
|
+
| **`Esc`** | Fecha janela de ajuda (se aberta) / sai da tela cheia / encerra |
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## 🔍 Ferramenta de Diagnóstico do Cofre OneDrive
|
|
111
|
+
|
|
112
|
+
Para testar e inspecionar o status de acesso e atributos dos arquivos de qualquer diretório:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
uv run slideshow --check-vault -p "C:\caminho\para\pasta"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## 📦 Construção de Executáveis (.exe)
|
|
121
|
+
|
|
122
|
+
Consulte o arquivo [`COMO_COMPILAR.md`](COMO_COMPILAR.md) para instruções completas sobre compilação com **Nuitka** (preferencial) e **PyInstaller**.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## 📄 Licença
|
|
127
|
+
Distribuído sob a licença MIT. Veja `LICENSE` para mais detalhes.
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"""Script de automação de compilação do executável com Nuitka e PyInstaller."""
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import os
|
|
5
|
+
import shutil
|
|
6
|
+
import subprocess
|
|
7
|
+
import sys
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
ROOT_DIR = Path(__file__).resolve().parent
|
|
11
|
+
ENTRY_POINT = ROOT_DIR / "run.py"
|
|
12
|
+
DIST_DIR = ROOT_DIR / "dist"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def run_command(cmd, desc):
|
|
16
|
+
print(f"\n==================================================")
|
|
17
|
+
print(f"[{desc}] Executando: {' '.join(cmd)}")
|
|
18
|
+
print(f"==================================================\n")
|
|
19
|
+
res = subprocess.run(cmd, cwd=str(ROOT_DIR))
|
|
20
|
+
if res.returncode != 0:
|
|
21
|
+
print(f"\n[ERRO] Falha ao executar: {desc} (Código {res.returncode})")
|
|
22
|
+
sys.exit(res.returncode)
|
|
23
|
+
print(f"\n[SUCESSO] {desc} concluído com sucesso!")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def clean_artifacts():
|
|
27
|
+
print("[Limpeza] Removendo pastas de compilação temporárias...")
|
|
28
|
+
dirs_to_clean = [
|
|
29
|
+
ROOT_DIR / "build",
|
|
30
|
+
ROOT_DIR / "run.build",
|
|
31
|
+
ROOT_DIR / "run.dist",
|
|
32
|
+
ROOT_DIR / "run.onefile-build",
|
|
33
|
+
ROOT_DIR / "Slideshow.build",
|
|
34
|
+
ROOT_DIR / "Slideshow.dist",
|
|
35
|
+
ROOT_DIR / "Slideshow.onefile-build",
|
|
36
|
+
]
|
|
37
|
+
for d in dirs_to_clean:
|
|
38
|
+
if d.exists() and d.is_dir():
|
|
39
|
+
shutil.rmtree(d, ignore_errors=True)
|
|
40
|
+
print(f" - Removido: {d.name}")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def build_nuitka():
|
|
44
|
+
clean_artifacts()
|
|
45
|
+
DIST_DIR.mkdir(exist_ok=True)
|
|
46
|
+
icon_path = ROOT_DIR / "src" / "slideshow" / "assets" / "icon.ico"
|
|
47
|
+
|
|
48
|
+
# Remove pasta dist/Slideshow anterior se existir, deixando apenas o executável único
|
|
49
|
+
old_folder = DIST_DIR / "Slideshow"
|
|
50
|
+
if old_folder.exists() and old_folder.is_dir():
|
|
51
|
+
shutil.rmtree(old_folder, ignore_errors=True)
|
|
52
|
+
print(" - Removida pasta dist/Slideshow anterior.")
|
|
53
|
+
|
|
54
|
+
old_zip = DIST_DIR / "Slideshow-Portatil.zip"
|
|
55
|
+
if old_zip.exists():
|
|
56
|
+
old_zip.unlink(missing_ok=True)
|
|
57
|
+
|
|
58
|
+
# Parâmetros otimizados do Nuitka para modo onefile (executável único) no Windows
|
|
59
|
+
cmd = [
|
|
60
|
+
sys.executable,
|
|
61
|
+
"-m", "nuitka",
|
|
62
|
+
"--onefile",
|
|
63
|
+
"--windows-console-mode=disable",
|
|
64
|
+
"--enable-plugin=tk-inter",
|
|
65
|
+
"--include-package=slideshow",
|
|
66
|
+
"--include-package-data=slideshow",
|
|
67
|
+
"--include-package=PIL",
|
|
68
|
+
"--include-package=openpyxl",
|
|
69
|
+
"--assume-yes-for-downloads",
|
|
70
|
+
f"--output-dir={DIST_DIR}",
|
|
71
|
+
"--output-filename=Slideshow.exe",
|
|
72
|
+
]
|
|
73
|
+
# Localiza pastas Tcl/Tk para garantir empacotamento completo do Tkinter no Windows
|
|
74
|
+
prefix = Path(sys.base_prefix)
|
|
75
|
+
tcl_cand = prefix / "tcl"
|
|
76
|
+
tcl_dir = None
|
|
77
|
+
tk_dir = None
|
|
78
|
+
if tcl_cand.exists():
|
|
79
|
+
for sub in tcl_cand.iterdir():
|
|
80
|
+
if sub.is_dir():
|
|
81
|
+
if (sub / "init.tcl").exists() and not tcl_dir:
|
|
82
|
+
tcl_dir = str(sub)
|
|
83
|
+
elif sub.name.lower().startswith("tk") and not tk_dir:
|
|
84
|
+
tk_dir = str(sub)
|
|
85
|
+
|
|
86
|
+
if tcl_dir:
|
|
87
|
+
cmd.append(f"--tcl-library-dir={tcl_dir}")
|
|
88
|
+
if tk_dir:
|
|
89
|
+
cmd.append(f"--tk-library-dir={tk_dir}")
|
|
90
|
+
|
|
91
|
+
if icon_path.exists():
|
|
92
|
+
cmd.append(f"--windows-icon-from-ico={icon_path}")
|
|
93
|
+
|
|
94
|
+
cmd.append(str(ENTRY_POINT))
|
|
95
|
+
run_command(cmd, "Compilação com Nuitka")
|
|
96
|
+
|
|
97
|
+
exe_target = DIST_DIR / "Slideshow.exe"
|
|
98
|
+
print(f"\n[SUCESSO] Executável único gerado com sucesso em: {exe_target}")
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def build_pyinstaller():
|
|
102
|
+
clean_artifacts()
|
|
103
|
+
DIST_DIR.mkdir(exist_ok=True)
|
|
104
|
+
icon_path = ROOT_DIR / "src" / "slideshow" / "assets" / "icon.ico"
|
|
105
|
+
|
|
106
|
+
cmd = [
|
|
107
|
+
sys.executable,
|
|
108
|
+
"-m", "PyInstaller",
|
|
109
|
+
"--onefile",
|
|
110
|
+
"--noconsole",
|
|
111
|
+
"--clean",
|
|
112
|
+
"--name", "Slideshow-PyInstaller",
|
|
113
|
+
f"--distpath={DIST_DIR}",
|
|
114
|
+
f"--paths={ROOT_DIR / 'src'}",
|
|
115
|
+
"--collect-all", "slideshow",
|
|
116
|
+
"--collect-all", "PIL",
|
|
117
|
+
"--collect-all", "openpyxl",
|
|
118
|
+
]
|
|
119
|
+
if icon_path.exists():
|
|
120
|
+
cmd.append(f"--icon={icon_path}")
|
|
121
|
+
|
|
122
|
+
cmd.append(str(ENTRY_POINT))
|
|
123
|
+
run_command(cmd, "Compilação com PyInstaller")
|
|
124
|
+
print(f"\nExecutável gerado em: {DIST_DIR / 'Slideshow-PyInstaller.exe'}")
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def main():
|
|
128
|
+
parser = argparse.ArgumentParser(description="Automação de compilação do Slideshow Pro")
|
|
129
|
+
parser.add_argument("--nuitka", action="store_true", help="Compilar executável usando Nuitka (Preferencial)")
|
|
130
|
+
parser.add_argument("--pyinstaller", action="store_true", help="Compilar executável usando PyInstaller")
|
|
131
|
+
parser.add_argument("--all", action="store_true", help="Compilar ambas as versões (Nuitka e PyInstaller)")
|
|
132
|
+
parser.add_argument("--clean", action="store_true", help="Apenas limpar arquivos e pastas temporárias de build")
|
|
133
|
+
|
|
134
|
+
args = parser.parse_args()
|
|
135
|
+
|
|
136
|
+
if args.clean:
|
|
137
|
+
clean_artifacts()
|
|
138
|
+
return
|
|
139
|
+
|
|
140
|
+
if args.all:
|
|
141
|
+
build_nuitka()
|
|
142
|
+
build_pyinstaller()
|
|
143
|
+
elif args.nuitka:
|
|
144
|
+
build_nuitka()
|
|
145
|
+
elif args.pyinstaller:
|
|
146
|
+
build_pyinstaller()
|
|
147
|
+
else:
|
|
148
|
+
# Padrão: compilar preferencialmente com Nuitka
|
|
149
|
+
print("Nenhuma opção especificada. Utilizando Nuitka por padrão.")
|
|
150
|
+
build_nuitka()
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
if __name__ == "__main__":
|
|
154
|
+
main()
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
@echo off
|
|
2
|
+
chcp 65001 > nul
|
|
3
|
+
echo ========================================================
|
|
4
|
+
echo Compilando Slideshow com Nuitka (via uv)
|
|
5
|
+
echo ========================================================
|
|
6
|
+
uv run --isolated --python 3.12 --with nuitka --with zstandard python build.py --nuitka
|
|
7
|
+
echo.
|
|
8
|
+
pause
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
@echo off
|
|
2
|
+
chcp 65001 > nul
|
|
3
|
+
echo ========================================================
|
|
4
|
+
echo Compilando Slideshow com PyInstaller (via uv)
|
|
5
|
+
echo ========================================================
|
|
6
|
+
uv run --isolated --python 3.12 --with pyinstaller python build.py --pyinstaller
|
|
7
|
+
echo.
|
|
8
|
+
pause
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "slideshow-vault"
|
|
7
|
+
version = "1.3.0"
|
|
8
|
+
description = "Apresentador de slides moderno, resiliente a OneDrive Personal Vault, com transições suaves, favoritos em SQLite (com exportação/importação Excel) e controle avançado."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Slideshow Developer" }
|
|
14
|
+
]
|
|
15
|
+
keywords = ["slideshow", "onedrive", "personal-vault", "photo-viewer", "tkinter", "ken-burns"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3.9",
|
|
19
|
+
"Programming Language :: Python :: 3.10",
|
|
20
|
+
"Programming Language :: Python :: 3.11",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
"Operating System :: Microsoft :: Windows",
|
|
23
|
+
"Topic :: Multimedia :: Graphics :: Viewers",
|
|
24
|
+
]
|
|
25
|
+
dependencies = [
|
|
26
|
+
"pillow>=10.0.0",
|
|
27
|
+
"openpyxl>=3.1.0",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.optional-dependencies]
|
|
31
|
+
build = [
|
|
32
|
+
"nuitka>=2.0.0",
|
|
33
|
+
"pyinstaller>=6.0.0",
|
|
34
|
+
"zstandard",
|
|
35
|
+
]
|
|
36
|
+
dev = [
|
|
37
|
+
"pytest>=7.0.0",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
[project.scripts]
|
|
41
|
+
slideshow = "slideshow.cli:main"
|
|
42
|
+
slideshow-diag = "slideshow.vault:main_diag"
|
|
43
|
+
|
|
44
|
+
[tool.hatch.build.targets.wheel]
|
|
45
|
+
packages = ["src/slideshow"]
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""Script de inicialização direta para execução e compilação do executável."""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
# Adiciona o diretório 'src' ao sys.path para garantir importação em qualquer ambiente
|
|
7
|
+
src_path = str(Path(__file__).resolve().parent / "src")
|
|
8
|
+
if src_path not in sys.path:
|
|
9
|
+
sys.path.insert(0, src_path)
|
|
10
|
+
|
|
11
|
+
from slideshow.cli import main
|
|
12
|
+
|
|
13
|
+
if __name__ == "__main__":
|
|
14
|
+
main()
|