Published at: August 10, 2026
Category: projects

Ro-Photo

Static gallery generator with EXIF data

Ro-Photo

Ro-Photo

Go console application that generates a static photo gallery by scanning source directories, extracting EXIF metadata, and organizing photos into a date-based directory structure.

Overview

Ro-Photo reads from one or more source directories containing photos, parses EXIF data from each image, and produces a structured static gallery. The output is organized into a hierarchical directory layout based on the date each photo was taken:

output/
  thumbnails/
    2024/03/15/IMG_1234.jpg
  2024/
    03/
      15/
        IMG_1234.JPG
        IMG_1235.JPG
      22/
        DSC_0001.CR2
    07/
      01/
        P1000042.JPG
  Unsorted/
    IMG_0001.HEIC
  cameras/
  about.html
  index.html

Features

SQLite Database

During scanning, all photo metadata is stored in a SQLite database (photos.db by default). This provides:

Schema overview:

Column Description
file_path Original source path
file_name Base filename
file_size Size in bytes
date_taken DateTimeOriginal from EXIF
camera_make Camera manufacturer
camera_model Camera model
lens_model Lens identifier
focal_length Focal length in mm
aperture F-number
shutter_speed Exposure time
iso ISO sensitivity
gps_lat GPS latitude
gps_lon GPS longitude
width Image width in pixels
height Image height in pixels
output_path Path in the generated gallery
thumbnail_path Path to the generated thumbnail

Supported Formats

Standard Image Formats

Format Extensions
JPEG .jpg, .jpeg
TIFF .tif, .tiff
HEIF .heic, .heif

RAW Formats

Brand Extensions
Canon .cr2, .cr3
Nikon .nef, .nrw
Sony .arw, .srf, .sr2
Fujifilm .raf
Olympus .orf
Panasonic .rw2
Pentax .pef
Samsung .srw
Sigma .x3f
Leica .rwl
Hasselblad .3fr, .fff
Phase One .iiq
Kodak .kdc, .dcr
Epson .erf
Mamiya .mef
Minolta .mrw
Leaf .mos
Adobe / Generic .dng

The static gallery is built with Tailwind CSS, producing a responsive, modern interface that works on desktop and mobile. The generated HTML files reference a bundled Tailwind CSS build, so the gallery can be served from any static file host or opened directly from disk.

Generated pages include:

Configuration

The application is configured via a YAML file:

title: My Photo Gallery           # gallery title shown in header, footer, and about page
author: John Doe                   # author name shown on the about page

sources:                           # one or more directories to scan for photos
  - /path/to/photos/camera
  - /path/to/photos/phone
  - /mnt/external/photos

output: /path/to/gallery           # directory where the gallery and organized photos are written
database: /path/to/photos.db       # SQLite database path (default: "photos.db")
templates: /path/to/templates      # path to HTML templates directory (default: "./templates")
Setting Required Default Description
title No Photo Gallery Gallery name displayed in header, footer, and page titles
author No Author name shown on the about page
sources Yes List of directories to scan for photos
output Yes Output directory for organized photos and gallery
database No photos.db Path to the SQLite metadata database
templates No ./templates Path to the HTML template files

Usage

ro-photo --config config.yaml

Command-line Flags

Flag Default Description
--config config.yaml Path to the YAML configuration file
--gallery-only false Skip scanning/copying, only regenerate gallery from the existing database

Examples

Full run — scan sources, extract EXIF, copy files, generate thumbnails, build gallery:

ro-photo --config config.yaml

Regenerate gallery only (useful after editing templates):

ro-photo --config config.yaml --gallery-only

Building

go build -o ro-photo .

Requirements

Comments