linux et mac

This commit is contained in:
Louis Mazin 2026-10-01 16:04:37 +02:00
parent 323adb1888
commit 2bbd6fedcb
4 changed files with 313 additions and 56 deletions

200
README.md Normal file
View File

@ -0,0 +1,200 @@
# Python Application Template
> Un socle desktop PyQt6 pret a personnaliser pour lancer rapidement une application Python moderne sous Windows.
Ce template fournit une base complete pour une application de bureau : fenetre principale, ecran de chargement, themes, traductions, gestion des parametres, mises a jour et generation d'un executable avec PyInstaller.
## Apercu
- Interface graphique construite avec **PyQt6**
- Themes `dark` et `light` facilement extensibles
- Traductions francaise et anglaise
- Ecran de demarrage avec progression
- Parametres persistants entre les lancements
- Verification des mises a jour depuis GitHub ou Gitea
- Onglet de suggestions avec envoi SMTP asynchrone
- Build automatise pour Windows et script prevu pour macOS/Linux
## Demarrage rapide
### Prerequis
- Python 3 disponible dans le `PATH`
- Windows pour utiliser les scripts `.bat`
- PowerShell pour la lecture de `config.json` par les scripts Windows
- VS Code et la commande `code` pour utiliser `tools/open.bat`
### Installation manuelle
Depuis la racine du projet :
```powershell
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -r config\requirements.txt
python main.py
```
Si PowerShell bloque l'activation de l'environnement, lancez directement :
```powershell
.venv\Scripts\python.exe main.py
```
### Installation automatisee sous Windows
Le script suivant cree l'environnement dedie dans `config/WINenv_x64`, installe les dependances puis ouvre le projet dans VS Code :
```powershell
tools\open.bat
```
> `open.bat` prepare le workspace mais ne lance pas directement l'application. Utilisez ensuite `python main.py` depuis l'environnement actif.
## Configuration
### Identite de l'application
Les informations generales sont centralisees dans [config.json](config.json) :
```json
{
"app_name": "Application",
"app_os": "Windows",
"app_version": "1.0.0",
"architecture": "x64",
"icon_path": "data/assets/icon.ico",
"splash_image": "splash",
"main_script": "main.py",
"git_repo": "https://example.com/owner/repository"
}
```
Adaptez au minimum `app_name`, `app_version`, `icon_path` et `git_repo` avant de distribuer votre application.
### Variables d'environnement
Copiez `.env.example` vers `.env`, puis renseignez les valeurs necessaires :
```powershell
Copy-Item .env.example .env
```
Variables disponibles :
| Variable | Role |
| --- | --- |
| `PYTHON_PATH` | Interpreteur Python utilise par les scripts de build |
| `EMAIL_ADDRESS` | Adresse SMTP utilisee pour recevoir les suggestions |
| `EMAIL_PASSWORD` | Mot de passe applicatif SMTP |
| `EMAIL_SMTP_SERVER` | Serveur SMTP, par defaut `smtp.gmail.com` |
| `EMAIL_SMTP_PORT` | Port SMTP, par defaut `587` |
Ne committez jamais `.env` ni un mot de passe SMTP. Pour Gmail, utilisez un mot de passe d'application plutot que le mot de passe principal du compte.
## Execution et build
### Lancer l'application
```powershell
python main.py
```
Au demarrage, l'application initialise ses gestionnaires, verifie les mises a jour disponibles, puis affiche la fenetre principale.
### Generer l'executable Windows
```powershell
tools\build.bat
```
Le script :
1. cree l'environnement virtuel correspondant a l'architecture configuree ;
2. installe les dependances ;
3. execute PyInstaller avec `config/BUILD.spec` ;
4. place l'application generee dans `build/`.
Le resultat est un executable sans console, adapte a une application graphique Windows.
### macOS et Linux
Les scripts Unix sont maintenant disponibles pour macOS et Linux.
Pour preparer l'environnement et ouvrir le projet :
```bash
bash tools/open.command
```
Le script choisit automatiquement `MACenv_<architecture>` sur macOS ou `LINenv_<architecture>` sur Linux, installe les dependances, puis ouvre le projet avec la commande `code`. A defaut, il utilise `open` sur macOS ou `xdg-open` sur Linux.
Pour construire l'application :
```bash
bash tools/build.command
```
Sur macOS, il utilise un environnement `MACenv_<architecture>`, produit une application `.app` et cree une archive ZIP dans `build/`. Sur Linux, il utilise `LINenv_<architecture>`, produit un binaire executable ainsi qu'un fichier `.desktop`, puis cree une archive ZIP dans `build/`.
La commande `zip` doit etre installee sur le systeme pour generer l'archive.
## Structure du projet
```text
.
├── app/
│ ├── core/ # Gestionnaires : langue, theme, parametres, mises a jour...
│ ├── ui/ # Fenetre principale, ecrans et widgets PyQt6
│ └── utils/ # Utilitaires partages, notamment les chemins
├── config/
│ ├── BUILD.spec # Configuration PyInstaller
│ └── requirements.txt # Dependances Python
├── data/
│ ├── assets/ # Icones et images
│ ├── lang/ # Fichiers de traduction JSON
│ ├── themes/ # Themes JSON et feuilles QSS
│ └── others/ # Valeurs par defaut
├── tools/ # Scripts d'installation, lancement et build
├── config.json # Configuration de l'application
└── main.py # Point d'entree
```
## Personnalisation
1. Modifiez `config.json` pour donner son identite a l'application.
2. Ajoutez ou adaptez les textes dans `data/lang/en.json` et `data/lang/fr.json`.
3. Creez un theme dans `data/themes/` et referencez-le dans le gestionnaire de themes.
4. Ajoutez vos vues dans `app/ui/` et votre logique metier dans `app/core/`.
5. Ajoutez les ressources necessaires dans `data/assets/`.
6. Mettez a jour `config/BUILD.spec` si votre application embarque de nouvelles ressources ou dependances dynamiques.
## Architecture simplifiee
```mermaid
flowchart TD
A[main.py] --> B[MainManager]
B --> C[SettingsManager]
B --> D[LanguageManager]
B --> E[ThemeManager]
B --> F[UpdateManager]
A --> G[SplashScreen]
A --> H[MainWindow]
H --> I[SettingsWindow]
H --> J[SuggestionWindow]
D --> K[data/lang]
E --> L[data/themes]
F --> M[GitHub ou Gitea]
```
## Dependances principales
- [PyQt6](https://pypi.org/project/PyQt6/) : interface graphique
- [PyInstaller](https://pyinstaller.org/) : generation de l'executable
- [Requests](https://pypi.org/project/requests/) : appels HTTP pour les mises a jour
- [python-dotenv](https://pypi.org/project/python-dotenv/) : chargement des variables d'environnement
## Licence
Aucune licence n'est actuellement definie dans le depot. Ajoutez un fichier `LICENSE` avant toute distribution publique.

View File

@ -29,8 +29,10 @@ datas = [
(str(PROJECT_DIR / "data/assets/*"), "data/assets/"),
(str(PROJECT_DIR / "data/"), "data/"),
(str(PROJECT_DIR / "config.json"), "."),
(str(PROJECT_DIR / ".env"), "."),
]
env_file = PROJECT_DIR / ".env"
if env_file.exists():
datas.append((str(env_file), "."))
binaries = []
# --- Analysis ---
@ -96,7 +98,7 @@ elif sys.platform.startswith("linux"):
desktop_content = f"""[Desktop Entry]
Type=Application
Name={app_name}
Exec={dist_bin}
Exec={name}
Icon={icon if icon else "application-default-icon"}
Terminal=false
Categories=Utility;

View File

@ -1,88 +1,92 @@
#!/bin/bash
set -e
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PARENT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
CONFIG_DIR="$PROJECT_DIR/config"
CONFIG_FILE="$PROJECT_DIR/config.json"
ENV_FILE="$PROJECT_DIR/.env"
BUILD_DIR="$PROJECT_DIR/build"
ICON_FILE="$PROJECT_DIR/data/assets/icon.png"
CONFIG_DIR="$PARENT_DIR/config"
CONFIG_FILE="$PARENT_DIR/config.json"
ICON_FILE="$PARENT_DIR/data/assets/icon.png"
if [ -f "$PARENT_DIR/.env" ]; then
if [ -f "$ENV_FILE" ]; then
set -a
. "$PARENT_DIR/.env"
# shellcheck disable=SC1090
. "$ENV_FILE"
set +a
fi
# === Extract values from config.json ===
ICON_PATH=$(python3 -c "import json; print(json.load(open('$CONFIG_FILE'))['icon_path'])")
APP_NAME=$(python3 -c "import json; print(json.load(open('$CONFIG_FILE'))['app_name'])")
ARCHITECTURE=$(python3 -c "import json; print(json.load(open('$CONFIG_FILE'))['architecture'])")
# === Use the Python interpreter provided by the environment ===
SYSTEM_PYTHON="${PYTHON_PATH:-python3}"
VENV_PATH="$CONFIG_DIR/MACenv_$ARCHITECTURE"
APP_FILE="$APP_NAME.app"
PYTHON_IN_VENV="$VENV_PATH/bin/python"
BUILD_DIR="$PARENT_DIR/build"
ZIP_FILE="$BUILD_DIR/$APP_NAME.zip"
# === Verify Python existence ===
if ! command -v "$SYSTEM_PYTHON" >/dev/null 2>&1; then
echo "[ERROR] Python interpreter not found in PATH."
echo "[ERROR] Python introuvable : $SYSTEM_PYTHON" >&2
exit 1
fi
if ! command -v zip >/dev/null 2>&1; then
echo "[ERROR] La commande zip est requise pour creer l'archive." >&2
exit 1
fi
# === Check virtual environment ===
if [ ! -f "$VENV_PATH/bin/activate" ]; then
echo "[INFO] Virtual environment not found. Creating..."
"$SYSTEM_PYTHON" -m venv "$VENV_PATH"
APP_NAME="$("$SYSTEM_PYTHON" -c "import json; print(json.load(open(r'$CONFIG_FILE', encoding='utf-8'))['app_name'])")"
ARCHITECTURE="$("$SYSTEM_PYTHON" -c "import json; print(json.load(open(r'$CONFIG_FILE', encoding='utf-8'))['architecture'])")"
OS_NAME="$(uname -s)"
case "$OS_NAME" in
Darwin)
ENV_NAME="MACenv_${ARCHITECTURE}"
APP_FILE="$APP_NAME.app"
;;
Linux)
ENV_NAME="LINenv_${ARCHITECTURE}"
APP_FILE="$APP_NAME"
;;
*)
echo "[ERROR] Systeme non supporte : $OS_NAME" >&2
exit 1
;;
esac
ENV_PATH="$CONFIG_DIR/$ENV_NAME"
PYTHON_IN_VENV="$ENV_PATH/bin/python"
ZIP_FILE="$BUILD_DIR/${APP_NAME}-${OS_NAME}.zip"
if [ ! -x "$PYTHON_IN_VENV" ]; then
echo "[INFO] Creation de l'environnement $ENV_NAME..."
"$SYSTEM_PYTHON" -m venv "$ENV_PATH"
"$PYTHON_IN_VENV" -m pip install --upgrade pip
"$PYTHON_IN_VENV" -m pip install -r "$CONFIG_DIR/requirements.txt"
else
echo "[INFO] Virtual environment found."
echo "[INFO] Environnement $ENV_NAME trouve."
fi
# === Run PyInstaller ===
mkdir -p "$BUILD_DIR"
cd "$PROJECT_DIR"
"$PYTHON_IN_VENV" -m PyInstaller \
--distpath "$BUILD_DIR" \
--workpath "$BUILD_DIR/dist" \
--clean \
"$CONFIG_DIR/BUILD.spec"
# === Clean build cache ===
rm -rf "$BUILD_DIR/dist"
# === Create ZIP ===
echo "[INFO] Creating ZIP archive..."
if [ ! -e "$BUILD_DIR/$APP_FILE" ]; then
echo "[ERROR] Artefact attendu introuvable : $BUILD_DIR/$APP_FILE" >&2
exit 1
fi
TEMP_ZIP_DIR="$BUILD_DIR/temp_zip"
# Remove old temp dir
rm -rf "$TEMP_ZIP_DIR"
mkdir -p "$TEMP_ZIP_DIR"
# Move compiled app
mv "$BUILD_DIR/$APP_FILE" "$TEMP_ZIP_DIR/"
# Copy config.json
cp "$CONFIG_FILE" "$TEMP_ZIP_DIR/"
# Copy icon.png
cp "$ICON_FILE" "$TEMP_ZIP_DIR/"
cp -R "$PROJECT_DIR/data/lang" "$TEMP_ZIP_DIR/lang"
# Copy data/lang
cp -R "$PARENT_DIR/data/lang" "$TEMP_ZIP_DIR/lang"
if [ "$OS_NAME" = "Linux" ] && [ -f "$BUILD_DIR/$APP_NAME.desktop" ]; then
cp "$BUILD_DIR/$APP_NAME.desktop" "$TEMP_ZIP_DIR/"
fi
# Remove old ZIP
rm -f "$ZIP_FILE"
# Create ZIP
cd "$BUILD_DIR"
zip -r "$ZIP_FILE" "temp_zip" >/dev/null
# Remove temp folder
(cd "$BUILD_DIR" && zip -r "$ZIP_FILE" "temp_zip" >/dev/null)
rm -rf "$TEMP_ZIP_DIR"
echo "[INFO] ZIP created at: $ZIP_FILE"
echo "[INFO] Archive creee : $ZIP_FILE"

View File

@ -0,0 +1,51 @@
#!/bin/bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
CONFIG_DIR="$PROJECT_DIR/config"
CONFIG_FILE="$PROJECT_DIR/config.json"
ENV_FILE="$PROJECT_DIR/.env"
if [ -f "$ENV_FILE" ]; then
set -a
# shellcheck disable=SC1090
. "$ENV_FILE"
set +a
fi
SYSTEM_PYTHON="${PYTHON_PATH:-python3}"
if ! command -v "$SYSTEM_PYTHON" >/dev/null 2>&1; then
echo "[ERROR] Python introuvable : $SYSTEM_PYTHON" >&2
exit 1
fi
ARCHITECTURE="$("$SYSTEM_PYTHON" -c "import json; print(json.load(open(r'$CONFIG_FILE', encoding='utf-8'))['architecture'])")"
if [ "$(uname -s)" = "Darwin" ]; then
ENV_NAME="MACenv_${ARCHITECTURE}"
else
ENV_NAME="LINenv_${ARCHITECTURE}"
fi
ENV_PATH="$CONFIG_DIR/$ENV_NAME"
PYTHON_IN_VENV="$ENV_PATH/bin/python"
if [ ! -x "$PYTHON_IN_VENV" ]; then
echo "[INFO] Creation de l'environnement $ENV_NAME..."
"$SYSTEM_PYTHON" -m venv "$ENV_PATH"
"$PYTHON_IN_VENV" -m pip install --upgrade pip
"$PYTHON_IN_VENV" -m pip install -r "$CONFIG_DIR/requirements.txt"
else
echo "[INFO] Environnement $ENV_NAME trouve."
fi
if command -v code >/dev/null 2>&1; then
code "$PROJECT_DIR"
elif [ "$(uname -s)" = "Darwin" ] && command -v open >/dev/null 2>&1; then
open -a "Visual Studio Code" "$PROJECT_DIR"
elif command -v xdg-open >/dev/null 2>&1; then
xdg-open "$PROJECT_DIR"
else
echo "[ERROR] Impossible d'ouvrir le projet : installez VS Code (commande code) ou xdg-open." >&2
exit 1
fi