Skip to content

Import d'un export Google Photos (Takeout) : dézip serveur + rangement #327

Description

@ronan-develop

Contexte

Google Photos (via Google Takeout) exporte la bibliothèque sous forme d'archive(s) ZIP. Objectif : permettre à un utilisateur d'uploader ce ZIP tel quel dans HomeCloud, et que le serveur se charge du dézip + rangement, plutôt que de forcer l'utilisateur à décompresser et réorganiser manuellement avant l'upload.

Ce qui existe déjà (réutilisable)

  • FolderZipArchiver (src/Service/FolderZipArchiver.php) : zippe un dossier pour l'export/téléchargement — sens inverse de ce qu'il faut ici, mais montre le pattern ZipArchive déjà en place dans le projet
  • CreateFileService / StorageService : création de fichiers avec structure de dossiers, déjà utilisés par le glisser-déposer de dossier local (✨ feat(explorer-drop): glisser-déposer un dossier local avec sa structure #279)
  • directory-entry-reader.js / explorer-drop.js : reconstitution d'une arborescence de dossiers côté client depuis un drop — utile en référence pour la logique de rangement, même si l'extraction ZIP se fera côté serveur

Spécificités d'un export Google Takeout à anticiper

  • L'export est souvent scindé en plusieurs ZIP (takeout-*-001.zip, -002.zip, …) si la bibliothèque dépasse une taille seuil — décider si on gère le multi-fichiers dès le départ ou seulement un ZIP unique dans une v1
  • Structure interne typique : Google Photos/<Nom d'album ou année>/photo.jpg + un fichier .json par média (photo.jpg.supplemental-metadata.json ou similaire) contenant les métadonnées Google (date de prise de vue, géoloc, titre) — distinctes de l'EXIF embarqué dans le fichier, parfois plus fiables que l'EXIF (Google réencode certaines images et peut perdre l'EXIF d'origine)
  • Présence de fichiers non-média à ignorer (métadonnées d'album metadata.json, print-subscriptions.json, etc.)
  • Risque de doublons si l'utilisateur réimporte un export qui chevauche des photos déjà présentes (uploadées individuellement avant, ou export précédent partiel)

Décisions à prendre

  • Dézip en flux (streaming) ou sur disque temporaire ? Impact mémoire/disque sur l'hébergement mutualisé (cf. contraintes déjà connues sur o2switch : OOM kill observés sur des opérations lourdes comme composer install)
  • Traitement synchrone (petit export) vs asynchrone via le worker Messenger existant (cf. routage lots lourds déjà en place pour l'upload standard) — probablement toujours asynchrone vu la taille potentielle d'un export Google Photos complet
  • Rangement cible : un dossier "Import Google Photos " à la racine ? Reproduire la structure d'albums Google telle quelle (un Folder par album) ? Aplatir dans la Galerie sans dossiers, avec les métadonnées Google Photos comme fallback EXIF ?
  • Faut-il lire les .json de métadonnées pour enrichir/corriger l'EXIF (date de prise de vue, géoloc) avant MediaProcessor::process(), ou les ignorer et se contenter de l'EXIF embarqué existant ?
  • Détection de doublons à l'import (par hash de contenu ? nom + taille ?) ou hors scope v1 (l'utilisateur gère lui-même)
  • Limite de taille d'upload du ZIP côté PHP/Symfony (upload_max_filesize, post_max_size) à revoir pour ce cas d'usage

Zone concernée

Upload, Galerie, Worker média

Effort estimé

L — nécessite décisions de design (rangement, métadonnées) avant l'implémentation, TDD complet (dézip malveillant/zip bomb à couvrir en sécurité, cf. critères d'acceptation habituels du projet)

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNouvelle fonctionnalité

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions