Skip to content

TristanPutman/Zenfolio-Downloader

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

8 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Zenfolio Downloader

A robust, feature-rich Python application for downloading photos and videos from Zenfolio galleries with advanced capabilities including resume functionality, concurrent downloads, interactive menus, batch processing, and comprehensive error handling.

✨ Features

Core Functionality

  • πŸš€ Concurrent Downloads: Download multiple files simultaneously with configurable concurrency
  • ⏯️ Resume Capability: Automatically resume interrupted downloads from where they left off
  • πŸ”„ Intelligent Retry Logic: Exponential backoff retry mechanism for failed downloads
  • πŸ“Š Progress Tracking: Real-time progress bars, detailed statistics, and checkpoint management
  • πŸ—‚οΈ Cache System: Gallery hierarchy caching to minimize API calls and improve performance
  • πŸ›‘οΈ Comprehensive Error Handling: Detailed error reporting, logging, and graceful failure recovery
  • βœ… File Integrity Verification: Optional verification of downloaded files
  • πŸ•’ Timestamp Preservation: Maintain original file creation and modification timestamps

User Interface Options

  • 🎯 Interactive Menu Mode: User-friendly menu system for browsing and selecting galleries
  • ⚑ Command-Line Interface: Full CLI with extensive options for automation and scripting
  • πŸ“¦ Batch Processing: Download entire archives or specific folder collections
  • πŸ” Advanced Filtering: Filter galleries by name patterns, IDs, or folder hierarchies

Advanced Features

  • πŸ“‹ Retrieval Queue Management: Handle Zenfolio's retrieval queue for archived content
  • πŸ—οΈ Metadata Export: Export complete gallery structure and metadata to JSON/CSV
  • πŸ”§ Debug Tools: Comprehensive debugging utilities for troubleshooting
  • βš™οΈ First-Time Setup: Guided configuration wizard for new users
  • πŸ“ˆ Statistics & Analytics: Detailed download statistics and progress reporting
  • πŸ”— Shared Gallery Support: Download original-quality photos from shared gallery URLs (no login required)

πŸš€ Quick Start

1. Installation

# Clone the repository
git clone <repository-url>
cd zenfolio-downloader

# Create and activate virtual environment
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install dependencies
pip install -r requirements.txt

2. First-Time Setup

Run the setup wizard to configure your credentials and preferences:

python main.py --setup

Or manually create your configuration:

# Copy the sample environment file
cp .env.sample .env

# Edit .env with your Zenfolio credentials
nano .env  # or your preferred editor

3. Basic Usage

Interactive Mode (Recommended for Beginners)

python main.py

Launches an interactive menu where you can browse folders, select galleries, and manage downloads.

Command-Line Mode

# Download all galleries
python main.py

# Download specific folder by ID
python main.py --folder-id 1234567890

# Download specific gallery by ID  
python main.py --gallery-id 9876543210

# Download with custom settings
python main.py --concurrent-downloads 4 --output-dir ./my-photos

βš™οΈ Configuration

Environment Variables

The application uses a comprehensive .env configuration file. All settings are documented in .env.sample:

πŸ” Required Credentials

ZENFOLIO_USERNAME=your_zenfolio_username
ZENFOLIO_PASSWORD=your_zenfolio_password

πŸ“₯ Download Settings

CONCURRENT_DOWNLOADS=8          # Simultaneous downloads (1-20)
DEFAULT_OUTPUT_DIR=./downloads  # Download destination
OVERWRITE_EXISTING=false        # Overwrite existing files

πŸ”„ Retry & Performance Settings

MAX_RETRIES=5                   # Maximum retry attempts (0-50)
INITIAL_BACKOFF_SECONDS=1.0     # Initial retry delay
MAX_BACKOFF_SECONDS=60.0        # Maximum retry delay
REQUEST_TIMEOUT=60              # API request timeout (5-300s)
DOWNLOAD_TIMEOUT=30             # File download timeout (10-300s)
CHUNK_SIZE=8192                 # Download chunk size in bytes

πŸ“ Logging Configuration

LOG_LEVEL=INFO                  # DEBUG, INFO, WARNING, ERROR, CRITICAL
LOG_FILE=zenfolio_downloader.log # Log file path (empty to disable)

πŸ—„οΈ Cache Settings

CACHE_ENABLED=true              # Enable gallery hierarchy caching
CACHE_DIR=.zenfolio_cache       # Cache directory path
CACHE_TTL_HOURS=48              # Cache expiration time (1-168 hours)

πŸ“ File Management

VERIFY_INTEGRITY=true           # Verify downloaded file integrity
PRESERVE_TIMESTAMPS=true        # Maintain original file timestamps

πŸ—οΈ Project Structure

zenfolio-downloader/
β”œβ”€β”€ πŸ“„ main.py                     # Main application entry point
β”œβ”€β”€ πŸ“„ requirements.txt            # Python dependencies
β”œβ”€β”€ πŸ“„ .env.sample                 # Sample configuration file
β”œβ”€β”€ πŸ“„ .gitignore                  # Git ignore rules
β”œβ”€β”€ πŸ“ api/                        # Zenfolio API client and models
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ exceptions.py              # API exception classes
β”‚   β”œβ”€β”€ models.py                  # Data models (Gallery, Group, etc.)
β”‚   └── zenfolio_client.py         # Main API client
β”œβ”€β”€ πŸ“ auth/                       # Authentication management
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ token_manager.py           # Authentication token handling
β”‚   └── zenfolio_auth.py           # Zenfolio authentication logic
β”œβ”€β”€ πŸ“ cache/                      # Caching system
β”‚   β”œβ”€β”€ __init__.py
β”‚   └── cache_manager.py           # Gallery hierarchy caching
β”œβ”€β”€ πŸ“ config/                     # Configuration management
β”‚   β”œβ”€β”€ __init__.py
β”‚   └── settings.py                # Settings validation and loading
β”œβ”€β”€ πŸ“ download/                   # Download management
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ concurrent_downloader.py   # Concurrent download handling
β”‚   β”œβ”€β”€ download_manager.py        # Main download orchestration
β”‚   β”œβ”€β”€ integrity_checker.py       # File integrity verification
β”‚   └── retry_manager.py           # Retry logic and backoff
β”œβ”€β”€ πŸ“ filesystem/                 # File system utilities
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ directory_manager.py       # Directory creation and management
β”‚   β”œβ”€β”€ duplicate_detector.py      # Duplicate file detection
β”‚   └── file_manager.py            # File operations and metadata
β”œβ”€β”€ πŸ“ logs/                       # Logging configuration
β”‚   β”œβ”€β”€ __init__.py
β”‚   └── logger.py                  # Logging setup and configuration
β”œβ”€β”€ πŸ“ progress/                   # Progress tracking and checkpoints
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ checkpoint_manager.py      # Download checkpoint management
β”‚   β”œβ”€β”€ console_progress.py        # Console progress display
β”‚   β”œβ”€β”€ progress_tracker.py        # Progress tracking utilities
β”‚   β”œβ”€β”€ retrieval_queue.py         # Zenfolio retrieval queue handling
β”‚   └── statistics.py              # Download statistics tracking
└── πŸ“ utils/                      # Utility functions
    β”œβ”€β”€ __init__.py
    β”œβ”€β”€ constants.py               # Application constants
    β”œβ”€β”€ first_time_setup.py        # Initial setup wizard
    β”œβ”€β”€ helpers.py                 # General utility functions
    β”œβ”€β”€ interactive_menu.py        # Interactive menu system
    β”œβ”€β”€ metadata_exporter.py       # Metadata export functionality
    └── shared_gallery.py          # Shared gallery download support

🎯 Usage Examples

Command-Line Interface

Basic Operations

# List all available galleries
python main.py --list-galleries

# List only folders/groups
python main.py --list-folders --folder-depth 2

# Show detailed gallery information
python main.py --list-galleries --list-details --show-ids

# Perform dry run (show what would be downloaded)
python main.py --dry-run

# Show download statistics without downloading
python main.py --stats-only

Targeted Downloads

# Download specific folder and all its contents
python main.py --folder-id 1234567890

# Download specific gallery
python main.py --gallery-id 9876543210

# Download galleries matching a pattern
python main.py --galleries "Wedding.*2023"

# Download specific folder by name pattern
python main.py --folder "Marketing.*"

Advanced Options

# Resume interrupted download
python main.py --resume

# Force overwrite existing files
python main.py --overwrite

# Custom output directory and concurrency
python main.py --output-dir /path/to/photos --concurrent-downloads 12

# Verify existing files integrity
python main.py --verify-integrity

# Verify download completion
python main.py --verify

# Export complete metadata structure
python main.py --export-metadata --metadata-format json

Cache Management

# Refresh gallery hierarchy cache
python main.py --refresh-cache

# Show cache information
python main.py --cache-info

# Clear cache
python main.py --clear-cache

Debug Operations

# Debug single photo download
python main.py --debug-download 1234567890

# Debug first photo from gallery
python main.py --debug-gallery 9876543210

# Enable verbose logging
python main.py --log-level DEBUG

Interactive Menu Mode

When run without arguments, the application launches an interactive menu:

python main.py

The interactive mode provides:

  • πŸ“‚ Folder Browser: Navigate through your Zenfolio hierarchy
  • 🎯 Selective Downloads: Choose specific folders or galleries
  • βœ… Verification Tools: Verify completed downloads
  • πŸ“‹ Queue Management: Process Zenfolio's retrieval queue
  • πŸ“Š Status Reports: View download progress and statistics

πŸ”§ Advanced Features

Shared Gallery Downloads

Download original-quality photos from shared Zenfolio galleries without requiring Zenfolio login credentials. This feature uses browser automation to access photos shared via public or access-code-protected gallery links.

Supported URL Formats

# Public shared galleries
https://username.zenfolio.com/p123456789/gallery-name

# Access-code protected galleries
https://username.zenfolio.com/p123456789/gallery-name?c=accesscode

How to Use

  1. Run the application in interactive mode: python main.py
  2. Select "Download Shared Gallery" from the main menu
  3. Paste the shared gallery URL when prompted
  4. Photos will be downloaded to downloads/shared_galleries/ directory

Download Methods

The shared gallery downloader uses a two-tier approach:

  • Primary: ZIP download (all photos in a single request for maximum efficiency)
  • Fallback: Individual photo downloads (if ZIP download fails)

Requirements

  • Playwright: Browser automation library (automatically installed with dependencies)
  • Chromium: Downloaded automatically on first run via playwright install chromium

Example

# Start interactive mode
python main.py

# Select option: "Download Shared Gallery"
# Enter URL: https://photographer.zenfolio.com/p123456789/wedding-photos
# Photos downloaded to: downloads/shared_galleries/photographer_wedding-photos/

Retrieval Queue Management

Zenfolio archives some content in a retrieval queue. The downloader can:

  • πŸ“‹ Check Queue Status: View pending items in the retrieval queue
  • ⚑ Process Queue: Download available items from the queue
  • πŸ“Š Queue Analytics: Show detailed queue statistics
# Check retrieval queue status
python check_retrieval_queue.py

# Process retrieval queue (interactive mode)
python main.py  # Select "Process Retrieval Queue" from menu

Metadata Export

Export complete gallery structure and metadata:

# Export to JSON format
python main.py --export-metadata --metadata-format json

# Export to CSV format  
python main.py --export-metadata --metadata-format csv

# Export to both formats
python main.py --export-metadata --metadata-format both

Checkpoint System

The application automatically saves progress and can resume interrupted downloads:

  • πŸ’Ύ Auto-Save: Progress saved after each gallery
  • πŸ”„ Smart Resume: Skips completed galleries on restart
  • πŸ“Š Progress Tracking: Shows accurate completion status
# Clear checkpoint and start fresh
python main.py --clear-checkpoint

# Resume with explicit flag (default behavior)
python main.py --resume

πŸ› οΈ Troubleshooting

Common Issues

πŸ” Authentication Problems

# Verify credentials in .env file
cat .env | grep ZENFOLIO

# Test authentication
python main.py --list-galleries

Solutions:

  • Verify username and password in .env
  • Check account access to galleries
  • Ensure no special characters in credentials

⏱️ Download Timeouts

# Increase timeouts for large files
DOWNLOAD_TIMEOUT=120
REQUEST_TIMEOUT=180

Solutions:

  • Increase DOWNLOAD_TIMEOUT for large files
  • Reduce CONCURRENT_DOWNLOADS if experiencing network issues
  • Check network stability

πŸ“ Permission Errors

Solutions:

  • Ensure output directory is writable: chmod 755 ./downloads
  • Check disk space availability
  • Verify file permissions for existing files

πŸ—„οΈ Cache Issues

# Clear and rebuild cache
python main.py --clear-cache
python main.py --refresh-cache

Debug Tools

Enable Verbose Logging

# Set debug level in .env
LOG_LEVEL=DEBUG

# Or use command line
python main.py --log-level DEBUG

Debug Specific Downloads

# Debug single photo
python main.py --debug-download 1234567890

# Debug gallery
python main.py --debug-gallery 9876543210

Check Log Files

# Monitor logs in real-time
tail -f zenfolio_downloader.log

# Search for errors
grep -i error zenfolio_downloader.log

Performance Optimization

Optimize Concurrent Downloads

# For fast connections
CONCURRENT_DOWNLOADS=12

# For slower connections or to be gentle on servers
CONCURRENT_DOWNLOADS=4

Cache Optimization

# Longer cache for stable galleries
CACHE_TTL_HOURS=168  # 1 week

# Shorter cache for frequently updated content
CACHE_TTL_HOURS=24   # 1 day

πŸ”§ Development

Requirements

Key Dependencies

  • aiohttp: Async HTTP client for API communication
  • pydantic: Data validation and settings management
  • tqdm: Progress bars and status display
  • click: Command-line interface framework
  • loguru: Advanced logging capabilities
  • tenacity: Retry logic with exponential backoff
  • playwright: Browser automation for shared gallery downloads

Development Setup

# Install development dependencies (uncomment in requirements.txt)
pip install pytest pytest-asyncio black flake8 mypy

# Run code formatting
black .

# Run linting
flake8 .

# Run type checking
mypy .

Architecture

The application follows a modular architecture with clear separation of concerns:

  • πŸ”Œ API Layer: Handles Zenfolio API communication and authentication
  • πŸ“₯ Download Layer: Manages concurrent downloads and retry logic
  • πŸ’Ύ Storage Layer: Handles file system operations and integrity checking
  • πŸ“Š Progress Layer: Tracks progress, checkpoints, and statistics
  • πŸŽ›οΈ Interface Layer: Provides CLI and interactive menu interfaces
  • βš™οΈ Configuration Layer: Manages settings and environment variables

πŸ“š Additional Documentation

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Make your changes with proper testing
  4. Follow code style: Use black for formatting
  5. Add tests if applicable
  6. Update documentation as needed
  7. Submit a pull request

Code Style Guidelines

  • Follow PEP 8 conventions
  • Use type hints for all functions
  • Add docstrings for public methods
  • Keep functions focused and modular
  • Use meaningful variable names

πŸ“„ License

[Add your license information here]

πŸ†˜ Support

For support, please:

  1. Check the troubleshooting section above
  2. Review log files for detailed error information
  3. Search existing issues in the repository
  4. Create a new issue with detailed information including:
    • Error messages and log excerpts
    • Configuration details (without credentials)
    • Steps to reproduce the issue
    • System information (OS, Python version)

πŸ™ Acknowledgments

  • Zenfolio: For providing the API that makes this tool possible
  • Contributors: Thanks to all who have contributed to this project
  • Community: For feedback, bug reports, and feature suggestions

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages