- PHP 87%
- CSS 12.3%
- Dockerfile 0.7%
Weekend
Weekend is a simple (simplistic even), self-hosted photo publishing application built with PHP. It features automatic thumbnail generation, EXIF data extraction, download tracking, and RAW file support. Weekend was written over a weekend (hence the name) with help of Cline, Claude, DeepSeek and Gwen3 Coder as a learning exercise and for my own personal use.
Advantages
- Built with PHP, HTML, and CSS (with a smidgen of JavaScript): All solid, tried-and-true stuff
- No exotic dependencies: Uses only standard PHP extensions (GD, EXIF, SQLite)
- Simple and lightweight: Only a handful of files with minimal overhead
- Flexible deployment: Can be deployed on any web server with PHP or using Docker containers
- GDPR-compliant: No external tracking, no third-party services, all data stays on your server
Features
- Automatic Photo Processing: Scans directories and subdirectories and automatically generates thumbnails
- EXIF Data Extraction: Extracts and displays EXIF metadata from photos
- Custom descriptions: .txt files with the same filenames as photos replace the default descriptions from the
ImageDescriptionEXIF field. - RAW File Support: Detects and manages RAW camera files alongside JPEGs
- Thumbnail Generation: Creates optimized thumbnails for fast browsing
- Search Functionality: Search photos by their filenames and by image description from EXIF data
- Download Tracking: Tracks photo and RAW file downloads
- Photo Deletion: Secure password-protected photo deletion with associated files cleanup
- Responsive Design: Works on desktop and mobile devices
- Dark Theme: Modern dark interface with smooth animations
- Keyboard Navigation: Arrow keys for easy photo browsing
- GPS Location: Displays photo locations on OpenStreetMap (if available in EXIF)
- Photo Calendar: Monthly calendar view with expandable photo links per day
- RSS Feed: Automatically generates an RSS feed with recently published photos
- Random Photo Display: Displays random photos with EXIF information and auto-refresh capability
- Photo Statistics: Detailed EXIF data statistics with pretty charts
- Maintenance: A dedicated PHP script for keeping the photo gallery tidy and healthy
Requirements
- PHP 7.4 or higher
- PHP Extensions:
gd(for image processing)exif(for EXIF data extraction)pdo_sqlite(for database)
- Web server (Apache, Nginx, or built-in PHP server)
- Write permissions for thumbnail and database directories
Installation
Installation on a Web Server with PHP
- Download or clone the application to your web server directory
- Create a directory outside the web root for security:
mkdir ../photos chmod 755 ../photos - Upload your photos to the
../photosdirectory - Ensure proper permissions:
chmod 755 thumbnails/ chmod 644 *.php *.css - Access the application through your web browser
Docker Installation
- Install Docker on your system if not already installed
- Create a directory for your images:
mkdir photos - Place your photos in the
photosdirectory - Edit the
config.phpfile - Build and run the application using Docker Compose:
docker-compose up -d - Access the application at
http://localhost:8000
Alternatively, you can use a direct docker command to create a container with volumes for persistent data.
First build the container image:
docker build -t weekend .
Create a container:
docker run -d --name weekend -p 8000:80 \
-v $(pwd)/photos:/var/www/photos \
-v $(pwd)/thumbnails:/var/www/html/thumbnails \
-v $(pwd)/config.php:/var/www/html/config.php \
--restart unless-stopped weekend
The Docker setup does the following:
- Installs all required PHP extensions
- Configures the Apache web server
- Sets correct file permissions
- Mounts the
photosdirectory as a volume - Mounts the
data.dbdatabase file as a volume for persistence - Mounts the
config.phpconfiguration file as a volume for customization - Exposes the application on port 8000
- Automatically restarts the container unless stopped
Configuration
Edit config.php to customize your gallery:
Basic Settings
'gallery_title' => 'Title goes here', // Gallery title
'footer_text' => "© 2025 Your Name", // Footer text
Directory Settings
'photo_dir' => '../photos', // Photos directory (outside web root)
'thumbnail_dir' => 'thumbnails', // Thumbnails directory
'db_path' => 'data.db', // SQLite database file
File Support
- Add/remove supported photo formats in
photo_extensions - Add/remove RAW formats in
raw_extensions - Supports all major camera RAW formats (NEF, CR2, ARW, etc.)
Display Settings
'photos_per_page' => 12, // Photos per page
'thumbnail_size' => 300, // Thumbnail size in pixels
Security Settings
'delete_password' => '2ドルy12ドル$EsAuHH6pViqroTUede273eQrQ2DIgvFvYAzCoretK6QMDZKiBjicW', // Hashed password for delete functionality
Navigation
- Use
Left ArrowandRight Arrowto go to the next and previous photo respectively. - Use the
Escapekey to return to the grid view.
File Structure
weekend/
├── index.php # Main gallery page
├── view.php # Individual photo view
├── calendar.php # Monthly calendar with photo links
├── catalog.php # Photo catalog with descriptions and RAW info
├── delete.php # Photo deletion script with password authentication
├── config.php # Configuration settings
├── style.css # Stylesheet
├── maintenance.php # Maintenance tools
├── random-photo.php # Random photo display with EXIF info
├── stats.php # Photo statistics with charts
├── rss.php # RSS feed generator
├── docker-compose.yml # Docker Compose configuration
├── Dockerfile # Docker container definition
├── .dockerignore # Docker ignore patterns
├── .gitignore # Git ignore patterns
├── LICENSE # GPLv3 license
├── SECURITY.md # Security policy
├── favicon.png # Favicon (PNG)
├── favicon.svg # Favicon (SVG)
├── data/ # SQLite database directory (auto-created)
├── thumbnails/ # Generated thumbnails
└── ../photos/ # Original photos (outside web root)
Usage
Adding Photos
- Place photos in the
../photosdirectory - The application automatically:
- Detects new photos
- Generates thumbnails
- Extracts EXIF data
- Stores information in the database
- Finds matching RAW files
Browsing Photos
- Main Gallery: Browse all photos with pagination
- Search: Use the search bar to find photos by description
- Individual View: Click any photo to view details and EXIF data
- Navigation: Use arrow keys or on-screen buttons to navigate between photos
Photo Calendar
The calendar.php page displays a monthly calendar where each day shows how many photos were taken on that date:
- Access: Navigate to
calendar.phpor use the Calendar link on the main gallery page - Features:
- Monthly calendar grid (Monday-Sunday) with previous/next month navigation
- Days with photos show a green count badge (e.g., "3 photos")
- Click a count badge to expand a list of photo filenames, each linking to
view.php - Today's date number is highlighted in green
Photo Catalog
The catalog.php script provides a comprehensive overview of all photos with their descriptions and RAW file availability:
-
Access: Navigate to
catalog.phpin your web browser -
Features:
- Displays photo descriptions (from .txt files or EXIF ImageDescription)
- Shows RAW file availability with format-specific badges
- Provides direct links to view individual photos
- Paginated display with user-configurable items per page (10, 20, 50, or 100)
- Text filtering to search for specific descriptions
- Dark theme styling consistent with the main gallery
-
Usage:
- Use the dropdown to select number of items per page
- Use the filter field to search for specific text in photo descriptions
- Click "Apply Filter" to filter results or "Clear Filter" to remove filtering
- Click "View Photo" links to open individual photos
- Navigate through pages using pagination controls
- RAW file badges show available formats (NEF, CR2, ARW, etc.)
Downloading Files
- Photo Download: Download the original photo file
- RAW Download: Download the matching RAW file (if available)
- Download Tracking: All downloads are tracked and displayed
Deleting Photos
The application includes a secure photo deletion feature accessible through the Photo Catalog:
- Access: Navigate to
catalog.phpand click the "Delete" button next to any photo - Authentication: Requires a password configured in
config.php - Comprehensive Cleanup: Deletes the photo, associated RAW files, .txt description files, thumbnails, and database entries
- Security: Password is hashed using PHP's
password_hash()function for secure storage
Configuration:
- Set a delete password in
config.php:
// Generate a hashed password (run this once in a PHP script)
$deletePassword = password_hash('your_secure_password', PASSWORD_DEFAULT);
// Add to config.php
'delete_password' => '2ドルy12ドル$EsAuHH6pViqroTUede273eQrQ2DIgvFvYAzCoretK6QMDZKiBjicW', // Your hashed password
Usage:
- Browse to
catalog.phpin your web browser - Click the "Delete" button next to any photo
- Enter the configured password in the modal dialog
- Confirm deletion to remove the photo and all associated files
Security Notes:
- The delete password should be different from any other system passwords
- Passwords are transmitted securely via HTTPS (recommended for production)
- Deletion is permanent and cannot be undone
EXIF Data Support
The application extracts and displays the following EXIF information:
- Camera Model
- Date and Time
- Exposure Settings (Shutter Speed, Aperture, ISO)
- Focal Length
- Image Dimensions
- Software and Author information
- GPS Location (with OpenStreetMap link)
Managing photo descriptions
If the show_descriptions option in config.php is set to true, the content of the ImageDescription EXIF field is displayed for each photo in the grid. To disable descriptions in the grid, set show_descriptions to false.
To override a description from the ImageDescription EXIF field, edit the respective .txt file (create the file, if necessary) in the photos directory. This approach allows you to specify custom descriptions, without editing the EXIF metadata.
Random Photo Display
The application includes a random photo display feature that shows a random photo from your gallery with EXIF information. This is useful for digital photo frames, screensavers, or simply enjoying your photos in a random order.
Accessing Random Photos
- Navigate to
random-photo.phpin your web browser - Example:
http://your-domain.com/weekend/random-photo.php
Features
- Displays a random photo from your gallery database
- Shows EXIF information including camera settings, date, and description
- Auto-refresh capability with configurable intervals
- Clean, full-screen display optimized for photo viewing
- Manual refresh button for instant new random photo
Configuration
In config.php, you can customize the random photo behavior:
'random_photo_refresh' => 30, // Auto-refresh interval in seconds (0 to disable)
Set the value to 0 to disable auto-refresh, or specify the number of seconds between automatic refreshes.
Photo Statistics
The application includes a comprehensive photo statistics feature that analyzes EXIF data from your photo collection and provides visual insights into your camera usage patterns.
Accessing Photo Statistics
- Navigate to
stats.phpin your web browser - Example:
http://your-domain.com/weekend/stats.php
Features
- EXIF Data Analysis: Analyzes focal length, aperture, and ISO settings from your photos
- Interactive Charts: Bar charts showing distribution of camera settings
- Top 5 Statistics: Lists the most frequently used settings for each category
- Dark Theme Integration: Uses the same dark theme styling as the main gallery
- Supported Formats: Processes JPEG, HEIC, and HEIF files
- Configurable Directory: Reads photos from the directory specified in
config.php
Statistics Provided
- Focal Length Distribution: Shows how often you use different focal lengths
- Aperture Distribution: Displays your preferred aperture settings
- ISO Distribution: Analyzes your ISO sensitivity usage patterns
- Total Photos Analyzed: Count of photos with valid EXIF data
- Unique Settings: Number of distinct focal lengths, apertures, and ISO values used
Usage
- Ensure you have photos with EXIF data in the configured photo directory
- Access
stats.phpthrough your web browser - View the interactive charts and statistics
- Analyze your photography habits and preferences
Configuration
The statistics feature automatically uses the photo directory specified in config.php:
'photo_dir' => '../photos', // Photos directory for statistics analysis
Supported File Formats
- JPEG (.jpg, .jpeg, .JPG, .JPEG)
- HEIC (.heic, .HEIC) - iPhone and modern camera format
- HEIF (.heif, .HEIF) - High Efficiency Image Format
Maintenance
The maintenance.php file provides the following maintenance options:
maintenance.php --thumbnailsRegenerate all thumbnails from scratchmaintenance.php --thumbnail IDRegenerate thumbnail for a specific photo by IDmaintenance.php --optimizeOptimize the SQLite database by reclaiming unused space and improving performancemaintenance.php --cleanRemove database records, thumbnails, and RAW files for photos that have been manually deleted from the photos directorymaintenance.php --fullRuns all of the above
Examples:
php maintenance.php --thumbnail 33- Regenerate thumbnail for photo ID 33php maintenance.php --thumbnails- Regenerate all thumbnails
To run the maintenance script in a container, use the following command:
docker exec -it weekend php /var/www/maintenance.php <OPTION>
Customization
Styling
Edit style.css to customize the appearance:
- Color scheme
- Layout and spacing
- Responsive breakpoints
- Animation effects
Functionality
Modify the PHP classes to add new features:
PhotoGalleryclass inindex.phpPhotoViewerclass inview.php
Security Considerations
- Photos are stored outside the web root for security
- File uploads are not supported (add photos via FTP/SFTP)
- Input validation and sanitization is implemented
- SQLite database uses parameterized queries
Database Schema
The SQLite database (data.db) contains:
CREATETABLEphotos(idINTEGERPRIMARYKEYAUTOINCREMENT,filenameTEXTUNIQUENOTNULL,thumbnail_pathTEXT,exif_dataTEXT,-- JSON-encoded EXIF data
image_descriptionTEXT,-- From EXIF ImageDescription
has_rawINTEGERDEFAULT0,raw_filenameTEXT,photo_downloadsINTEGERDEFAULT0,raw_downloadsINTEGERDEFAULT0,date_addedDATETIMEDEFAULTCURRENT_TIMESTAMP);Performance Tips
- Use PHP opcache for better performance
- Configure proper memory limits in
config.php - Use a CDN for thumbnail delivery in production
- Regularly optimize the SQLite database
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
License
This project is available under the GPLv3 License.
Troubleshooting
Common Issues
-
Photos not appearing:
- Check directory permissions
- Verify photo directory path in
config.php - Ensure PHP has read access to photos directory
-
Thumbnails not generating:
- Check GD extension is installed
- Verify write permissions on thumbnails directory
-
EXIF data not showing:
- Check EXIF extension is installed
- Verify photos contain EXIF metadata
-
Database errors:
- Check write permissions on database directory
- Verify PDO SQLite extension is installed
Debug Mode
For debugging, you can enable error reporting by adding to config.php:
error_reporting(E_ALL);
ini_set('display_errors', 1);
Support
For issues and questions:
- Check the troubleshooting section above
- Review PHP error logs
- Ensure all required extensions are installed
- Verify file and directory permissions
Authors
- Idea, specifications, code review and testing: Dmitri Popov (me@dmpop.xyz)
- Coding: DeepSeek and Gwen3 Coder