pyPhotoAlbum/VERSIONING.md
2025-11-11 16:02:02 +00:00

5.4 KiB

Data Format Versioning

pyPhotoAlbum uses a comprehensive versioning system to manage data format changes and ensure compatibility across versions.

Current Version

Data Format Version: 2.0

Version History

Version 2.0 (Released: 2025-01-11)

Description: Fixed asset path handling - paths now stored relative to project folder

Breaking Changes:

  • Asset paths changed from absolute/full-project-relative to project-relative
  • Added automatic path normalization for legacy projects

Compatibility: Can read and migrate v1.0 files automatically

Key Improvements:

  • Asset paths now stored as assets/image.jpg instead of ./projects/ProjectName/assets/image.jpg
  • Automatic path normalization when loading old projects
  • Added search path system for finding assets in multiple locations
  • ZIP file directory automatically added as a search path
  • New "Heal Assets" feature to reconnect missing images

Version 1.0 (Released: 2024-01-01)

Description: Initial format with basic serialization

Features:

  • Basic project structure
  • Page layouts and elements
  • Asset management with reference counting
  • ZIP-based .ppz project format

How Versioning Works

File Format

Each .ppz file contains a project.json with version information:

{
  "name": "My Project",
  "data_version": "2.0",
  "serialization_version": "2.0",
  ...
}
  • data_version: Current versioning system (introduced in v2.0)
  • serialization_version: Legacy version field (for backward compatibility)

Loading Process

When loading a project file:

  1. Version Detection: The system reads both data_version (new) and serialization_version (legacy) fields
  2. Compatibility Check: Verifies if the file version is compatible with the current version
  3. Migration (if needed): Automatically migrates data from old versions to current format
  4. Path Normalization: Fixes asset paths to work with current project location
  5. Asset Resolution: Sets up search paths for finding images

Compatibility Levels

The system supports multiple compatibility levels:

  • Full Compatibility: Same version, no migration needed
  • Backward Compatibility: Older version can be read with automatic migration
  • Incompatible: Version cannot be loaded (future versions or corrupted files)

For Developers

Adding a New Version

When making breaking changes to the data format:

  1. Update version_manager.py:

    CURRENT_DATA_VERSION = "3.0"  # Increment major version
    
    VERSION_HISTORY["3.0"] = {
        "description": "Description of changes",
        "released": "2025-XX-XX",
        "breaking_changes": [
            "List of breaking changes"
        ],
        "compatible_with": ["2.0", "3.0"],
    }
    
  2. Create a migration function:

    @DataMigration.register_migration("2.0", "3.0")
    def migrate_2_0_to_3_0(data: Dict[str, Any]) -> Dict[str, Any]:
        # Perform data transformations
        data['data_version'] = "3.0"
        return data
    
  3. Test the migration:

    • Create test files with old format
    • Verify they load correctly with migration
    • Verify no migration needed for new files

Version Compatibility Guidelines

When to increment version:

  • Major version (1.0 → 2.0): Breaking changes to data structure

    • Field renames or removals
    • Changed data types
    • New required fields
    • Incompatible serialization changes
  • Minor version (2.0 → 2.1): Backward-compatible additions

    • New optional fields
    • New features that don't break old data
    • Performance improvements

Migration Best Practices:

  1. Always test migrations with real user data
  2. Log migration steps for debugging
  3. Preserve user data even if it can't be fully migrated
  4. Provide clear error messages for incompatible versions
  5. Document all breaking changes in VERSION_HISTORY

For Users

What You Need to Know

  • Automatic Updates: Old project files are automatically updated when opened
  • No Data Loss: Your original .ppz file remains unchanged
  • Backward Compatibility: Newer versions can read older files
  • Version Info: Use File → About to see current version information

Troubleshooting

"Incompatible file version" error:

  • The file was created with a much newer or incompatible version
  • Solution: Use the version of pyPhotoAlbum that created the file, or upgrade

Missing assets after loading:

  • Use File → "Heal Assets" to add search paths
  • The directory containing the .ppz file is automatically searched
  • You can add additional locations where images might be found

Want to ensure future compatibility:

  • Keep your .ppz files
  • When upgrading, test opening your projects
  • Report any migration issues on GitHub

Implementation Details

Files Involved

  • version_manager.py: Core versioning system and migrations
  • project_serializer.py: Handles loading/saving with version checks
  • models.py: Asset path resolution with search paths
  • asset_heal_dialog.py: UI for reconnecting missing assets

Key Classes

  • VersionCompatibility: Checks version compatibility
  • DataMigration: Manages migration functions
  • AssetManager: Handles asset storage and reference counting

Search Path Priority

When resolving asset paths (in order):

  1. Project folder (primary location)
  2. Additional search paths (from Heal Assets)
  3. Directory containing the .ppz file
  4. Current working directory (fallback)
  5. Parent of working directory (fallback)