epaatampistle
This commit is contained in:
+1
-1
@@ -31,7 +31,7 @@ MANIFEST
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
# *.spec — NO ignorar: pocketsync.spec está versionado como configuración de build
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
|
||||
@@ -82,6 +82,40 @@ Las operaciones de copia corren en un hilo daemon separado para no bloquear la U
|
||||
### Extensibilidad de backends
|
||||
`core/sync_engine.py` define la ABC `SyncEngine`. `RobocopySyncEngine` es la implementación concreta. Para añadir rsync u otro backend: crear un nuevo archivo en `core/` que implemente la misma interfaz.
|
||||
|
||||
## Build (generar PocketSync.exe)
|
||||
|
||||
### Requisitos previos (una sola vez)
|
||||
|
||||
```bash
|
||||
py -m venv .venv
|
||||
.venv\Scripts\activate
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### Icono (opcional pero recomendado)
|
||||
|
||||
Coloca tu icono en `assets\pocketsync.ico` antes de empaquetar. Sin él, el `.exe` usará el icono genérico de Python. El `.spec` detecta automáticamente si el archivo existe.
|
||||
|
||||
### Empaquetar
|
||||
|
||||
```bash
|
||||
.venv\Scripts\activate
|
||||
pyinstaller pocketsync.spec
|
||||
```
|
||||
|
||||
El ejecutable final queda en `dist\PocketSync.exe`. No requiere Python instalado en el equipo destino.
|
||||
|
||||
### Archivos de build
|
||||
|
||||
| Archivo | Descripción |
|
||||
|---|---|
|
||||
| `requirements.txt` | Solo `pyinstaller>=6.0` |
|
||||
| `pocketsync.spec` | Configuración de PyInstaller (versionado) |
|
||||
| `assets/pocketsync.ico` | Icono del `.exe` (no versionado, añadir manualmente) |
|
||||
| `dist/` | Salida del build (ignorado por git) |
|
||||
| `build/` | Archivos temporales de PyInstaller (ignorado por git) |
|
||||
| `.venv/` | Entorno virtual (ignorado por git) |
|
||||
|
||||
## Plataforma
|
||||
|
||||
Windows 10/11 obligatorio (depende de `robocopy`). Python 3.6+, sin dependencias externas.
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,86 @@
|
||||
# PocketSync
|
||||
|
||||
Herramienta de escritorio para sincronizar archivos de emulación retro (ES-DE y ROMs) hacia almacenamiento externo. Soporta múltiples perfiles (uno por consola o dispositivo).
|
||||
|
||||
## Requisitos
|
||||
|
||||
- Windows 10 / 11
|
||||
- `robocopy` (incluido en Windows por defecto)
|
||||
- Para ejecutar desde código fuente: Python 3.6+
|
||||
|
||||
## Uso rápido (ejecutable)
|
||||
|
||||
Descarga `PocketSync.exe` y ejecútalo directamente. No requiere Python instalado.
|
||||
|
||||
## Uso desde código fuente
|
||||
|
||||
```bash
|
||||
python pocketsync.py
|
||||
```
|
||||
|
||||
## Configurar y usar la app
|
||||
|
||||
1. **Selecciona o crea un perfil** en el desplegable superior (New / Rename / Delete).
|
||||
2. **Configura las 4 rutas:**
|
||||
- ES-DE origen → carpeta local de ES-DE
|
||||
- ES-DE destino → carpeta en el almacenamiento externo
|
||||
- ROMs origen → carpeta local de ROMs
|
||||
- ROMs destino → carpeta en el almacenamiento externo
|
||||
3. **Selecciona los sistemas** a sincronizar (Select All / None para selección rápida).
|
||||
4. Pulsa **Sync Now**.
|
||||
|
||||
La configuración se guarda automáticamente en `config.json` al cerrar.
|
||||
|
||||
## Generar el ejecutable
|
||||
|
||||
### 1. Crear el entorno virtual e instalar dependencias
|
||||
|
||||
```bash
|
||||
py -m venv .venv
|
||||
.venv\Scripts\activate
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### 2. Añadir icono (opcional)
|
||||
|
||||
Coloca un archivo `pocketsync.ico` en la carpeta `assets\`. Sin él, el ejecutable usará el icono genérico de Windows.
|
||||
|
||||
### 3. Empaquetar
|
||||
|
||||
```bash
|
||||
.venv\Scripts\activate
|
||||
pyinstaller pocketsync.spec
|
||||
```
|
||||
|
||||
El resultado queda en `dist\PocketSync.exe`.
|
||||
|
||||
## Estructura del proyecto
|
||||
|
||||
```
|
||||
pocketsync.py # Entry point
|
||||
pocketsync.spec # Configuración de PyInstaller
|
||||
requirements.txt # Solo pyinstaller>=6.0
|
||||
config.json # Perfiles guardados (se crea al primer uso)
|
||||
assets/
|
||||
pocketsync.ico # Icono del .exe (añadir manualmente)
|
||||
|
||||
core/
|
||||
config.py # Gestión de perfiles y persistencia
|
||||
sync_engine.py # Interfaz abstracta de sincronización
|
||||
robocopy_engine.py # Implementación con Robocopy
|
||||
|
||||
ui/
|
||||
app.py # Ventana principal y lógica de sync
|
||||
profile_bar.py # Selector de perfiles
|
||||
path_panel.py # Selectores de ruta
|
||||
system_list.py # Lista de sistemas
|
||||
status_bar.py # Barra de estado
|
||||
summary_panel.py # Resumen de la última sincronización
|
||||
styles.py # Colores y fuentes
|
||||
```
|
||||
|
||||
## Notas
|
||||
|
||||
- La sincronización usa `robocopy /MIR`, que replica exactamente el origen en el destino (borra archivos en destino que no estén en origen).
|
||||
- Cada perfil guarda sus 4 rutas y la selección de sistemas de forma independiente.
|
||||
- El proceso de sync corre en un hilo separado para no bloquear la interfaz.
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 103 KiB |
+7
-2
@@ -2,8 +2,13 @@ import os
|
||||
import sys
|
||||
import tkinter as tk
|
||||
|
||||
# Asegurar que el directorio raíz esté en el path para imports relativos
|
||||
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
# Cuando se ejecuta como .exe (PyInstaller onefile), __file__ apunta a la
|
||||
# carpeta temporal de extracción. sys.executable apunta al .exe real.
|
||||
if getattr(sys, 'frozen', False):
|
||||
BASE_DIR = os.path.dirname(sys.executable)
|
||||
else:
|
||||
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
if BASE_DIR not in sys.path:
|
||||
sys.path.insert(0, BASE_DIR)
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
import os
|
||||
|
||||
icon_path = os.path.join('assets', 'pocketsync.ico')
|
||||
icon_arg = icon_path if os.path.exists(icon_path) else None
|
||||
|
||||
a = Analysis(
|
||||
['pocketsync.py'],
|
||||
pathex=['.'],
|
||||
binaries=[],
|
||||
datas=[],
|
||||
hiddenimports=[],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
noarchive=False,
|
||||
)
|
||||
|
||||
pyz = PYZ(a.pure)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.datas,
|
||||
[],
|
||||
name='PocketSync',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=False,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
icon=icon_arg,
|
||||
onefile=True,
|
||||
)
|
||||
@@ -0,0 +1 @@
|
||||
pyinstaller>=6.0
|
||||
Reference in New Issue
Block a user