Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ packaging/ppa/debian/copyright text eol=lf
packaging/ppa/debian/source/format text eol=lf
packaging/copr/pdf-equilibrist.spec text eol=lf
packaging/copr/pdf-equilibrist.sh text eol=lf
*.sh text eol=lf
packaging/appimage/AppRun text eol=lf
207 changes: 207 additions & 0 deletions .github/workflows/linux-appimage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
name: Linux AppImage

# Canal « autres distributions » : un seul fichier .AppImage, joint à la release GitHub.
# - tag v* : construit, teste, puis JOINT l'AppImage à la release du tag (celle que crée
# release.yml ; ce workflow attend qu'elle existe).
# - workflow_dispatch avec `tag` (ex. v0.1.25) : même chose pour une release existante (rattrapage) ;
# le code construit est celui de la branche choisie dans « Run workflow ».
# - workflow_dispatch sans `tag`, ou PR touchant packaging/appimage/ : construit et teste seulement,
# artefact de run de 14 jours, rien n'est publié.
#
# Construit sur Ubuntu 22.04 (glibc 2.35) : un binaire construit sur un système ancien tourne sur
# les récents, pas l'inverse. L'AppImage est ensuite lancée dans plusieurs distributions vierges.

on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
tag:
description: 'Tag de la release à laquelle joindre l''AppImage (ex. v0.1.25) ; vide = essai sans publication'
required: false
default: ''
pull_request:
branches: [main]
paths:
- 'packaging/appimage/**'
- '.github/workflows/linux-appimage.yml'
- 'src/pdf_equilibrist/update.py'

permissions:
contents: read

env:
APPIMAGETOOL_VERSION: '1.9.1'
# SHA-256 du binaire de la release officielle AppImage/appimagetool 1.9.1 (épinglé : on n'exécute
# jamais un binaire téléchargé sans l'avoir vérifié)
APPIMAGETOOL_SHA256: 'ed4ce84f0d9caff66f50bcca6ff6f35aae54ce8135408b3fa33abfc3cb384eb0'

jobs:
# Comme tous les workflows de publication : rien n'est construit ni publié si les contrôles échouent.
checks:
if: github.event_name == 'push'
name: Contrôles (lint, Bandit, tests)
uses: ./.github/workflows/checks.yml

build:
name: Build AppImage (Ubuntu 22.04)
needs: checks
# `checks` est ignoré hors tag (PR, dispatch) : on construit alors quand même
if: ${{ !cancelled() && (needs.checks.result == 'success' || needs.checks.result == 'skipped') }}
runs-on: ubuntu-22.04
outputs:
tag: ${{ steps.version.outputs.TAG }}
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Resolve version
id: version
env:
REF_TYPE: ${{ github.ref_type }}
REF_NAME: ${{ github.ref_name }}
INPUT_TAG: ${{ inputs.tag }}
run: |
tag=""
if [ "$REF_TYPE" = "tag" ]; then tag="$REF_NAME"; elif [ -n "$INPUT_TAG" ]; then tag="$INPUT_TAG"; fi
if [ -n "$tag" ]; then
case "$tag" in v[0-9]*.[0-9]*.[0-9]*) ;; *) echo "Tag inattendu : $tag" >&2; exit 1;; esac
echo "TAG=$tag" >> "$GITHUB_OUTPUT"
# Même injection que release.yml : l'application affiche (et compare) la version du tag
sed -i "s/^__version__ = \".*\"/__version__ = \"${tag#v}\"/" src/pdf_equilibrist/__init__.py
grep '^__version__' src/pdf_equilibrist/__init__.py
fi

- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.12'

- name: Install system libraries (Qt6/xcb, offscreen)
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
libxcb-cursor0 libegl1 libgl1 libxkbcommon0 libdbus-1-3 libfontconfig1 libglib2.0-0 binutils

- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt pyinstaller

- name: Download appimagetool (pinned and verified)
run: |
curl -fsSL -o appimagetool \
"https://github.com/AppImage/appimagetool/releases/download/${APPIMAGETOOL_VERSION}/appimagetool-x86_64.AppImage"
echo "${APPIMAGETOOL_SHA256} appimagetool" | sha256sum -c -
chmod +x appimagetool

- name: Build the AppDir and the AppImage
env:
PYTHON: python
run: |
APPIMAGETOOL="$PWD/appimagetool" bash packaging/appimage/build_appimage.sh
ls -la build/appimage/*.AppImage

# Environnement minimal et HOME vide : ce que verrait un utilisateur sur une machine vierge.
- name: OCR selftest on the AppImage (offline, empty home)
run: |
H="$(mktemp -d)"
env -i HOME="$H" PATH=/usr/bin:/bin APPIMAGE_EXTRACT_AND_RUN=1 \
build/appimage/PDF-Equilibrist-x86_64.AppImage --ocr-selftest "$H/report.txt" || { cat "$H/report.txt"; exit 1; }
cat "$H/report.txt"
# Informatif : en local (Ubuntu 24.04) un dossier ~/.cache apparaît pendant le selftest ; on veut
# savoir quel composant l'écrit (aucun fichier utilisateur ne doit contenir de document).
echo "Fichiers créés dans HOME hors rapport :"
find "$H" -mindepth 1 ! -name report.txt | head -20 || true

- name: GUI starts offscreen and stays up
run: |
H="$(mktemp -d)"
set +e
env -i HOME="$H" PATH=/usr/bin:/bin APPIMAGE_EXTRACT_AND_RUN=1 QT_QPA_PLATFORM=offscreen \
timeout 15 build/appimage/PDF-Equilibrist-x86_64.AppImage > "$H/run.log" 2>&1
rc=$?
cat "$H/run.log" | tail -20
# 124 = toujours en cours d'exécution au bout de 15 s = démarrage réussi
test "$rc" = 124

- name: Summary
run: |
{
echo "### AppImage (prototype)"
echo "- Taille : $(du -h build/appimage/PDF-Equilibrist-x86_64.AppImage | cut -f1)"
echo "- sha256 : \`$(sha256sum build/appimage/PDF-Equilibrist-x86_64.AppImage | cut -d' ' -f1)\`"
} >> "$GITHUB_STEP_SUMMARY"

- name: Upload the AppImage
uses: actions/upload-artifact@v4
with:
name: PDF-Equilibrist-x86_64.AppImage
path: build/appimage/PDF-Equilibrist-x86_64.AppImage
retention-days: 14

# La même AppImage, lancée dans des distributions vierges (sans Python ni aucune dépendance de l'appli)
distros:
name: Run on ${{ matrix.image }}
needs: build
# `checks` (ancêtre) est ignoré hors tag : sans cette condition, GitHub ignorerait aussi ce job
if: ${{ !cancelled() && needs.build.result == 'success' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
image: ['debian:12', 'ubuntu:24.04', 'fedora:44', 'archlinux:latest', 'opensuse/tumbleweed']
container:
image: ${{ matrix.image }}
steps:
- name: Download the AppImage
uses: actions/download-artifact@v4
with:
name: PDF-Equilibrist-x86_64.AppImage

- name: OCR selftest (no Python, no network used, fresh distribution)
run: |
chmod +x PDF-Equilibrist-x86_64.AppImage
. /etc/os-release; echo "== $PRETTY_NAME"; command -v python3 || echo "(pas de python3 : normal)"
export HOME="$(mktemp -d)" APPIMAGE_EXTRACT_AND_RUN=1
./PDF-Equilibrist-x86_64.AppImage --ocr-selftest "$HOME/report.txt" || { cat "$HOME/report.txt" 2>/dev/null; exit 1; }
cat "$HOME/report.txt"

# Joint l'AppImage à la release GitHub (créée par release.yml sur le même tag).
publish:
name: Attach to the GitHub release
needs: [build, distros]
if: ${{ !cancelled() && needs.build.result == 'success' && needs.distros.result == 'success' && needs.build.outputs.tag != '' }}
runs-on: ubuntu-latest
permissions:
contents: write
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
TAG: ${{ needs.build.outputs.tag }}
steps:
- name: Checkout (install script)
uses: actions/checkout@v4
with:
sparse-checkout: packaging/appimage/install.sh
sparse-checkout-cone-mode: false

- name: Download the AppImage
uses: actions/download-artifact@v4
with:
name: PDF-Equilibrist-x86_64.AppImage

# release.yml (Windows) crée la release bien après la fin de ce workflow : on attend (max 60 min)
- name: Wait for the release
run: |
for i in $(seq 1 60); do
if gh release view "$TAG" >/dev/null 2>&1; then echo "Release $TAG trouvée"; exit 0; fi
echo "Release $TAG pas encore créée (essai $i/60)…"; sleep 60
done
echo "Release $TAG introuvable : le workflow Release a-t-il échoué ?" >&2; exit 1

- name: Upload (replaces any previous AppImage)
run: |
sha256sum PDF-Equilibrist-x86_64.AppImage | tee PDF-Equilibrist-x86_64.AppImage.sha256
gh release upload "$TAG" PDF-Equilibrist-x86_64.AppImage PDF-Equilibrist-x86_64.AppImage.sha256 packaging/appimage/install.sh --clobber
3 changes: 3 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ jobs:
- **Arch Linux et dérivées** : `yay -S pdf-equilibrist` ([AUR](https://aur.archlinux.org/packages/pdf-equilibrist))
- **Ubuntu et dérivées** : `sudo add-apt-repository ppa:paulwoisard/pdf-equilibrist && sudo apt update && sudo apt install pdf-equilibrist` ([PPA](https://launchpad.net/~paulwoisard/+archive/ubuntu/pdf-equilibrist))
- **Fedora et dérivées** : `sudo dnf copr enable paullux/PDF-Equilibrist && sudo dnf install pdf-equilibrist` ([COPR](https://copr.fedorainfracloud.org/coprs/paullux/PDF-Equilibrist/))
- **Autres distributions Linux** (Debian, openSUSE, Mint…) : AppImage, un seul fichier, ajoutée quelques minutes après l'installeur.
Installation guidée (menu, association aux PDF, sans root) : `curl -fsSLO https://github.com/Bit-Scripts/PDF-Equilibrist/releases/latest/download/install.sh && bash install.sh`
ou téléchargez `PDF-Equilibrist-x86_64.AppImage` ci-dessous, `chmod +x` puis lancez-la (`.sha256` fourni).
append_body: true
generate_release_notes: true
draft: false
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ PDF Equilibrist.zip
# PyInstaller
*.spec
!packaging/copr/pdf-equilibrist.spec
!packaging/appimage/PDF-Equilibrist-linux.spec

# Logs and temp files
*.log
Expand Down Expand Up @@ -51,5 +52,8 @@ packaging/copr/*.src.rpm
*.pyo
*.pyd

# Dossier de preuves forensiques (antériorité) — jamais poussé
forensic/

# Réglages locaux de Claude Code (chemins, permissions) — ne pas versionner
.claude/settings.local.json
4 changes: 2 additions & 2 deletions PRIVACY.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ the content of a document, and both can be blocked (see below).

| Service | Endpoint | When | What is sent |
|---|---|---|---|
| GitHub | `api.github.com` | At startup, if "Check for updates at startup" is enabled (default on Windows only), and when you open *Help › Check for Updates* or *Help › About PDF-Equilibrist* | Nothing: the version comparison happens on your computer. Clicking *Download and install* (Windows) downloads the installer from GitHub. |
| GitHub | `api.github.com` | At startup, if "Check for updates at startup" is enabled (default on Windows only), and when you open *Help › Check for Updates* or *Help › About PDF-Equilibrist* | Nothing: the version comparison happens on your computer. Clicking *Download and install* (Windows) downloads the installer from GitHub; on an AppImage, *Download the new AppImage* and the install-script link download the file from the GitHub release. |
| OSV.dev | `api.osv.dev` | Only when you run *Help › Check CVE Vulnerabilities* | The names and versions of the libraries used by the application |

Like any Internet request, these connections expose your IP address to the
Expand Down Expand Up @@ -54,7 +54,7 @@ jamais le contenu d'un document, et les deux peuvent être bloqués (voir plus b

| Service | Point d'accès | Quand | Ce qui est envoyé |
|---|---|---|---|
| GitHub | `api.github.com` | Au démarrage si « Vérifier les mises à jour au démarrage » est coché (par défaut sous Windows uniquement), et à l'ouverture de *Aide › Vérifier les mises à jour* ou *Aide › À propos de PDF-Equilibrist* | Rien : la comparaison de version se fait sur votre ordinateur. Le bouton *Télécharger et installer* (Windows) télécharge l'installeur depuis GitHub. |
| GitHub | `api.github.com` | Au démarrage si « Vérifier les mises à jour au démarrage » est coché (par défaut sous Windows uniquement), et à l'ouverture de *Aide › Vérifier les mises à jour* ou *Aide › À propos de PDF-Equilibrist* | Rien : la comparaison de version se fait sur votre ordinateur. Le bouton *Télécharger et installer* (Windows) télécharge l'installeur depuis GitHub ; sous AppImage, *Télécharger la nouvelle AppImage* et le lien du script d'installation téléchargent le fichier depuis la release GitHub. |
| OSV.dev | `api.osv.dev` | Uniquement quand vous lancez *Aide › Vérifier les vulnérabilités CVE* | Les noms et versions des bibliothèques utilisées par l'application |

Comme toute requête Internet, ces connexions exposent votre adresse IP au service
Expand Down
16 changes: 14 additions & 2 deletions README.fr.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
[![AUR](https://img.shields.io/aur/version/pdf-equilibrist)](https://aur.archlinux.org/packages/pdf-equilibrist)

[![Téléchargements (total)](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fpdf-equilibrist.org%2Fstats.json&query=%24.total&label=t%C3%A9l%C3%A9chargements%20%28total%29&color=6BBF4E&cacheSeconds=3600&v=2)](https://pdf-equilibrist.org/#diffusion)
[![Téléchargements Windows](https://img.shields.io/github/downloads/Bit-Scripts/PDF-Equilibrist/total?label=t%C3%A9l%C3%A9chargements%20Windows&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAxNiI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTAgMGg3LjV2Ny41SDB6TTguNSAwSDE2djcuNUg4LjV6TTAgOC41aDcuNVYxNkgwek04LjUgOC41SDE2VjE2SDguNXoiLz48L3N2Zz4=&cacheSeconds=3600)](https://github.com/Bit-Scripts/PDF-Equilibrist/releases)
[![Téléchargements Windows](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fpdf-equilibrist.org%2Fstats.json&query=%24.channels.github.total&label=t%C3%A9l%C3%A9chargements%20Windows&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAxNiI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTAgMGg3LjV2Ny41SDB6TTguNSAwSDE2djcuNUg4LjV6TTAgOC41aDcuNVYxNkgwek04LjUgOC41SDE2VjE2SDguNXoiLz48L3N2Zz4=&cacheSeconds=3600&v=2)](https://github.com/Bit-Scripts/PDF-Equilibrist/releases)
[![Téléchargements Ubuntu](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fpdf-equilibrist.org%2Fstats.json&query=%24.channels.launchpad.total&label=t%C3%A9l%C3%A9chargements%20Ubuntu&logo=ubuntu&logoColor=white&color=E95420&cacheSeconds=3600&v=2)](https://launchpad.net/~paulwoisard/+archive/ubuntu/pdf-equilibrist)
[![Téléchargements Fedora](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fpdf-equilibrist.org%2Fstats.json&query=%24.channels.copr.total&label=t%C3%A9l%C3%A9chargements%20Fedora&logo=fedora&logoColor=white&color=51A2DA&cacheSeconds=3600&v=2)](https://copr.fedorainfracloud.org/coprs/paullux/PDF-Equilibrist/)
[![Téléchargements AppImage](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fpdf-equilibrist.org%2Fstats.json&query=%24.channels.appimage.total&label=t%C3%A9l%C3%A9chargements%20AppImage&logo=linux&logoColor=white&color=8E6BBF&cacheSeconds=3600&v=2)](https://github.com/Bit-Scripts/PDF-Equilibrist/releases/latest)
[![Téléchargements Arch : non mesuré](https://img.shields.io/badge/t%C3%A9l%C3%A9chargements%20Arch-non%20mesur%C3%A9-lightgrey?logo=archlinux&logoColor=white "L'AUR ne publie aucun compteur de téléchargements")](https://pdf-equilibrist.org/#diffusion-arch)

[![CI](https://github.com/Bit-Scripts/PDF-Equilibrist/actions/workflows/ci.yml/badge.svg)](https://github.com/Bit-Scripts/PDF-Equilibrist/actions/workflows/ci.yml)
Expand Down Expand Up @@ -118,6 +119,17 @@ sudo dnf install pdf-equilibrist

→ [Page COPR](https://copr.fedorainfracloud.org/coprs/paullux/PDF-Equilibrist/)

🐧 **Toute autre distribution Linux** (AppImage — Debian, openSUSE, Mint…) : un seul fichier, sans dépôt.

```bash
curl -fsSLO https://github.com/Bit-Scripts/PDF-Equilibrist/releases/latest/download/install.sh
bash install.sh # sans root : installe dans ~/.local (menu, association aux PDF)
# sudo bash install.sh --system # tous les utilisateurs : /usr/local
# bash install.sh --uninstall # désinstaller
```

Le script télécharge la dernière release et vérifie son SHA-256. Vous pouvez aussi télécharger [`PDF-Equilibrist-x86_64.AppImage`](https://github.com/Bit-Scripts/PDF-Equilibrist/releases/latest/download/PDF-Equilibrist-x86_64.AppImage) vous-même, `chmod +x` puis le lancer. Sans FUSE (`libfuse2`), lancez-le avec `--appimage-extract-and-run`. *Aide › À propos* propose de télécharger les nouvelles versions.

### Installation depuis les sources (développeurs)

1. Créez un environnement Python compatible (`>=3.12`).
Expand Down Expand Up @@ -159,7 +171,7 @@ Pour de nombreux usages courants — édition, annotation, conversion, protectio

**Quels systèmes d'exploitation sont supportés ?**

Windows (installeur .exe), Arch Linux (AUR), Ubuntu (PPA) et Fedora (COPR).
Windows (installeur .exe), Arch Linux (AUR), Ubuntu (PPA), Fedora (COPR) et toute autre distribution Linux 64 bits (AppImage).

**Faut-il des droits administrateur pour l'installer ?**

Expand Down
Loading
Loading