linux et mac
This commit is contained in:
parent
323adb1888
commit
2bbd6fedcb
200
README.md
Normal file
200
README.md
Normal 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.
|
||||
@ -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;
|
||||
|
||||
@ -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"
|
||||
@ -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
|
||||
Loading…
x
Reference in New Issue
Block a user