Repository navigation
Development fr
Français | English
Cette page décrit les concepts nécessaires pour contribuer à Photo Album v0.3.0. Le parcours de l’application est dans Utilisation ; les contrats d’extension sont dans Créer des packs de templates.
| Ensemble | Responsabilité |
|---|---|
| Modèles et base de données | Identités, candidats et valeurs effectives des photos ; stockage SQLite et repositories. |
| Sources, analyse et géocodage | Adaptateurs local et Synology, import, métadonnées, matérialisation des images et résolution des lieux. |
| Album | Réglages persistés, validation, plan chronologique, pagination, composition et diagnostics. |
| Moteur de templates | Découverte, activation, API publique, traductions et contrats d’aperçu. |
| Packs | Réglages, dispositions et peinture propres à leurs templates. |
| Rendu et export | Cible de peinture commune, caches d’images, géométrie physique et PDF. |
| Service de projet et interface | Orchestration, session ouverte, contrôles et travaux d’arrière-plan. |
Le réseau propre à un fournisseur reste dans photoalbum.sources. Les fournisseurs implémentent PhotoSource pour les collections, assets, miniatures et originaux, sans dépendre de l’interface ou du rendu. Les originaux ne sont jamais réécrits.
Un fichier .photoalbum est une base SQLite de schéma 5. Elle contient les sources ordonnées, les photos, les candidats de métadonnées, les corrections manuelles et éditoriales, le cache de géocodage, les réglages d’album, le nom du projet et les préférences PDF. La configuration JSON des sources utilise le schéma 2 ; les réglages JSON d’album utilisent le schéma 3. Ces schémas sont distincts.
Photo.identity combine source_id et asset_id. C’est la clé à utiliser pour les sélections persistantes, les directives éditoriales et la déduplication. Deux sources peuvent exposer le même chemin sans désigner la même photo. Les opérations historiques acceptant un chemin refusent les correspondances ambiguës.
Cette stabilité n’implique pas le suivi automatique des déplacements de fichiers : l’adaptateur local utilise le chemin absolu comme asset_id. Pour une source distante, le chemin local n’est que la matérialisation de l’asset.
Le cache distant voisin .<fichier-projet>.cache/assets/ dérive ses chemins de l’identité. Une miniature occupe d’abord le chemin canonique ; l’original la remplace à ce même chemin et reçoit un marqueur. La révision du fournisseur permet d’invalider ce marqueur. Les sessions et secrets des fournisseurs restent en mémoire dans ProjectService, jusqu’à la fermeture du projet.
Le modèle conserve séparément les candidats EXIF, nom de fichier et fournisseur ; les valeurs effectives choisies par la politique ; les corrections manuelles prioritaires ; puis le texte de lieu, la légende et l’utilisation éditoriale. La synchronisation met à jour les candidats sans écraser ces décisions.
Les filtres sont centralisés dans le service :
| Accès | Contenu |
|---|---|
list_photos() |
Photos présentes des sources actives, y compris OFF. |
list_album_photos() |
Même ensemble sans OFF : BODY et TEMPLATE_ONLY. |
list_body_photos() |
Photos BODY uniquement. |
Le plan chronologique exige ensuite une date effective. Le jeu destiné aux templates peut donc contenir une photo absente du corps, notamment sans date. AlbumBuildResult.template_photos transporte ce jeu canonique vers les sélecteurs, l’aperçu, le PDF et la préparation des originaux. Ne le reconstruisez pas à partir des seules pages photo.
L’import distant constitue un instantané explicite. L’analyse locale et l’actualisation de métadonnées sont séparées de cet import ; les politiques et les commandes correspondantes sont documentées dans Sources de photos.
AlbumStructureSettings est la configuration persistante. AlbumBuilder valide les instances et dimensions, filtre les pages facultatives incompatibles, construit le plan sémantique et lance la pagination et les diagnostics d’impression. La composition par PageComposer et les diagnostics de légendes complètent ensuite ce résultat pour les vues.
Le plan sémantique décrit le contenu chronologique ; pagination.pages décrit la séquence physique effective, côtés et blancs compris. Les quatre couvertures sont traitées séparément. Une page insérée peut être présente dans la pagination sans apparaître dans plan.items : le préchargement des aperçus doit parcourir la pagination effective.
PhotoPageOverride(photo_identity, page) et BodyPageInsertion(anchor, page, enabled) enregistrent des frontières de contenu, jamais des numéros physiques. Leurs règles d’application, de désactivation et de compatibilité sont dans Fonctions avancées. Le stockage conserve les IDs d’instances, options et directives dormantes.
La capacité résiduelle en fin de mois provient de la dernière page photo du mois réel et des blancs techniques de fin admissibles. Une coupure volontaire ou une page spéciale interne ne devient pas artificiellement une fin de mois.
L’hôte résout le format en millimètres avant la validation, les éditeurs et le rendu. Le pack reçoit cette géométrie ; il ne décide pas de l’orientation à partir d’un nom de papier.
Le Plan, l’Aperçu et le PDF consomment la même séquence construite. PageRenderer.paint_template() partage le dispatch de peinture, mais un aperçu n’est pas une image du PDF final : taille écran, miniatures, cache raster et disponibilité des originaux diffèrent. Le PDF fournit une cible QPainter et utilise un rendu synchrone, sans service d’aperçu.
PreviewRenderService partage les calculs coûteux entre éditeurs et aperçu. La clé PreviewRenderKey comprend l’ID de template, l’ID d’instance, les signatures de réglages et photos, la taille raster et les dimensions physiques. Le raster canonique conserve le rapport physique avec un grand côté de 594 pixels.
Le backend définit les photos effectives, dédupliquées par identité et ordonnées, ainsi que les états influant sur son résultat. La signature des photos tient compte de l’identité, de la modification du fichier et de photo_signature() ; cette dernière inclut par défaut le nom, la date, les dimensions et l’orientation. Un backend dépendant du GPS doit l’ajouter. render_settings_signature() doit inclure les réglages partagés dont dépend le calcul.
Une couche légère peut être peinte après le fond en cache. Ainsi, le pêle-mêle MSB exclut la typographie du titre de sa signature de fond, mais pas la graine ou la géométrie. Les workers produisent des octets ; la conversion en QPixmap se fait sur le thread graphique.
MainWindow coordonne les onglets et le résultat de l’album. PhotoSourcesWidget possède les contrôles et la table ; ScanController orchestre les scans ; PhotoEditor gère les corrections et le géocodage ; PdfExportWidget pilote l’export. Les widgets reçoivent leurs dépendances et émettent des signaux, sans accéder aux champs privés de leur parent Qt.
Les propriétaires conservent leurs workers jusqu’à la fin du thread. Les travaux en base utilisent des connexions adaptées à leur thread. Les corrections de lieux et légendes sont persistées immédiatement, avec reconstruction différée à la sortie de l’onglet ou avant l’export. Les réglages d’album déclenchent une reconstruction après leur modification validée.
Charger les réglages n’émet pas de changement. Une action de format actualise les choix compatibles en une transaction d’interface et n’émet qu’un changement consolidé.
Préparez l’environnement Python décrit dans Installation, puis installez les dépendances de contribution :
python -m pip install -e '.[dev]'
python -m pytest -qSous Linux sans affichage :
QT_QPA_PLATFORM=offscreen python -m pytest -qLe code est sous src/photoalbum/, les tests sous tests/. Les tests couvrent les frontières de stockage, sources, politiques, pagination, composition, interface, rendu, traductions et inclusion des données dans les distributions. Les tests de fournisseurs avec réponses simulées ne garantissent pas la connexion à tout NAS réel.
Pour un changement, testez la frontière qui possède le comportement, puis les consommateurs concernés. Pour un pack, vérifiez ensemble composition, aperçu et PDF. Les traductions générales sont dans photoalbum/i18n/translator.py ; les catalogues et aides des packs restent dans leurs dossiers. Maintenez les versions française et anglaise ensemble.