Skip to content

kordless/zoto-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Zoto

A modern photo-sharing platform that revives the feature set of Zoto (2008) — albums, tags, comments, contacts, messaging, granular permissions — with an AI-powered assistant and OCR search pipeline.

Stack

  • Backend: Python 3.11+, FastAPI, SQLAlchemy 2.0 (async), PostgreSQL
  • Frontend: Jinja2 templates, HTMX, Fuse.js (client-side fuzzy search)
  • Image Processing: Pillow (renders/thumbnails), exifread (EXIF extraction), OpenCV + Tesseract (OCR)
  • AI: Claude API — vision analysis for auto-tagging, chat assistant with UI control

Features

  • Image Management — Upload, auto-generate thumbnails/renders, EXIF extraction, rotate, download
  • AI Auto-Tagging — Claude Vision analyzes uploads: generates title, description, and relevant tags. Cross-references existing tags for consistency.
  • Search — PostgreSQL full-text search (weighted: title > tags > description > OCR text) with ILIKE fallback, plus Fuse.js client-side instant search
  • OCR Pipeline — Extract text from scanned images via OpenCV preprocessing + Tesseract, searchable
  • Albums & Sets — Create albums, reorder images, organize albums into sets
  • Tags — Per-image tags with tag clouds, bulk tagging, rename across library
  • Comments — Threaded comments on images, visibility toggle
  • Contacts & Groups — Add contacts, create custom groups, mutual contact detection
  • Messages — Internal messaging with read/reply status tracking
  • Permissions — Granular 8-type permission system (view, tag, comment, print, download, geotag, vote, blog) with 5 access levels (private, public, specific groups, contacts only, inherit from account defaults)
  • AI Chat Assistant — Persistent chat widget that searches your library, controls the UI (shows images, navigates pages, displays inline previews), tags/describes images, creates albums
  • Fullscreen Lightbox — Double-click any image to view fullscreen, Escape to close

Quick Start

Prerequisites

  • Python 3.11+
  • Docker (for PostgreSQL)
  • Tesseract OCR (optional, for OCR pipeline)

Setup

# Clone and enter the project
cd zoto-revival

# Start PostgreSQL
docker-compose up -d

# Create a virtualenv and install
python -m venv .venv
source .venv/bin/activate  # or .venv\Scripts\activate on Windows
pip install -e .

# Configure environment
cp .env.example .env
# Edit .env with your SECRET_KEY

# Run database migrations
alembic upgrade head

# Start the server
uvicorn zoto.main:app --reload --port 8081

Open http://localhost:8081, register an account, and start uploading.

AI Features

To enable auto-tagging and the chat assistant, add your Claude API key in Settings (click your username in the nav bar).

Project Structure

src/zoto/
├── main.py                 # FastAPI app, lifespan, 404 handler
├── config.py               # pydantic-settings configuration
├── web.py                  # Browser routes (Jinja2 templates)
├── db/
│   ├── engine.py           # Async engine + session factory
│   └── models.py           # 16 SQLAlchemy models
├── api/
│   ├── deps.py             # Auth (JWT + cookie), permission checking
│   ├── auth.py             # Register, login, token
│   ├── users.py            # Profile CRUD
│   ├── images.py           # Upload, renders, analyze, CRUD
│   ├── albums.py           # Album CRUD, image management
│   ├── tags.py             # Tagging, bulk tag, rename, tag cloud
│   ├── comments.py         # Comments with visibility control
│   ├── contacts.py         # Contact management, groups
│   ├── messages.py         # Internal messaging
│   ├── sets.py             # Album set management
│   ├── search.py           # Full-text + Fuse.js index endpoint
│   ├── permissions.py      # Permission get/set
│   └── chat.py             # AI chat with tool use
├── services/
│   ├── storage.py          # Hash-based filesystem (originals + renders)
│   ├── render.py           # Pillow resize/crop/rotate
│   ├── exif.py             # EXIF metadata extraction
│   ├── ocr.py              # OpenCV + Tesseract OCR pipeline
│   ├── search.py           # PG full-text search + Fuse.js index builder
│   ├── vision.py           # Claude Vision auto-analysis
│   ├── chat.py             # Chat agent with data + UI tools
│   └── activity.py         # Activity logging
├── schemas/
│   └── __init__.py         # Pydantic request/response models
├── templates/              # Jinja2 HTML templates
│   ├── base.html
│   ├── auth/
│   ├── images/
│   ├── albums/
│   ├── search/
│   ├── users/
│   ├── errors/
│   └── partials/
└── static/
    ├── css/main.css        # Dark theme
    └── js/
        ├── htmx.min.js
        ├── fuse.min.js
        ├── search.js       # Client-side fuzzy search
        └── chat.js         # Chat widget with UI control

Database Models

Model Description
User Accounts with profile, quota, API key
Image Photos with EXIF, dimensions, GPS, fulltext index
ImagePermissions 8 permission types per image (view, tag, comment, etc.)
AccountPermissions Account-level permission defaults
Album Photo albums with display settings
AlbumImage Album-image association with ordering
AlbumPermissions Album-level view/comment permissions
AlbumSet Sets that group albums
AlbumSetXref Set-album association with ordering
Tag Image tags (composite key: image + tagger + name)
Comment Image comments with visibility flag
ContactGroup User contact groups (auto per-contact or custom)
ContactMember Group membership
Message Internal messages with send/receive status
ImageOCR OCR extraction results with text regions
ActivityLog Activity audit trail

Permission System

Inherited from the original Zoto platform. Each permission type (view, tag, comment, print, download, geotag, vote, blog) has a flag value:

Flag Meaning
0 Private (owner only)
1 Public (everyone)
2 Specific groups
3 Contacts only
4 Inherit from account defaults

Permissions cascade: image-level overrides account-level defaults (flag=4 triggers inheritance).

Origins

Built by combining:

  • Zoto Server (2008) — Original Flickr-era photo platform (Python/Twisted/PostgreSQL). The original source is preserved in archive/.
  • Gordon Landreth Photography (github.com/arts-link/gordon-landreth-photography) by Benjamin Strawbridge — OCR pipeline and Fuse.js search implementation.

License

See LICENSE.

About

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors