Files
ubuntu-post-install/paintplus/scripts/import_saved_eyes.py
T
Claude 084922afaa paintplus: vendor the app source and rename from EditmaskwithAI
Bring the full EditmaskwithAI application into the repo under paintplus/
(429 files) so the service is self-contained — the installer copies the
vendored source to ~/docker/paintplus/src instead of cloning at runtime.

Rename to PaintPlus (service + branding; app logic untouched):
- services/editmaskwithai.sh -> services/paintplus.sh (register_service
  paintplus, install_paintplus, ~/docker/paintplus, Caddy paintplus:8000,
  Authelia option preserved)
- container names -> paintplus across docker-compose*.yml; dev network
  -> paintplus-network
- browser <title> -> "PaintPlus - AI Image Editor"; README heading ->
  PaintPlus with upstream provenance note
- README utilities table: editmaskwithai -> paintplus

Backend/frontend code (help strings referencing the old container name,
the ai_photo_edit.db filename) is intentionally left as-is to avoid
touching application logic.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nb2vJ8W7bHKx1JXVvpCraH
2026-06-26 05:48:43 +00:00

168 lines
4.9 KiB
Python

#!/usr/bin/env python3
"""
Import previously saved eye images into the patch library.
This script reads eye images from a directory (along with metadata.json)
and imports them into the patch library database.
Usage:
python scripts/import_saved_eyes.py /path/to/saved/eyes
This script must be run with backend dependencies available
(e.g., inside the backend container).
"""
import os
import sys
import json
import argparse
from pathlib import Path
# Add parent directory to path for imports
sys.path.insert(0, str(Path(__file__).parent.parent / "backend"))
from PIL import Image
from sqlalchemy.orm import Session
from app.database import SessionLocal, engine, Base
from app.models.patch import Patch
from app.services.patch_library import PatchLibraryService
def import_from_directory(source_dir: Path, db: Session, patch_service: PatchLibraryService) -> int:
"""
Import eye images from a directory.
Args:
source_dir: Directory containing eye images and metadata.json
db: Database session
patch_service: PatchLibraryService instance
Returns:
Number of successfully imported images
"""
metadata_path = source_dir / "metadata.json"
if not metadata_path.exists():
print(f"Error: metadata.json not found in {source_dir}")
print("Scanning for PNG files instead...")
# Fallback: import all PNG files with default metadata
png_files = list(source_dir.glob("*.png"))
metadata = []
for png_file in png_files:
img = Image.open(png_file)
metadata.append({
'filename': png_file.name,
'name': png_file.stem.replace('_', ' ').title(),
'description': f'Imported eye image: {png_file.name}',
'tags': 'eye,imported',
'width': img.width,
'height': img.height
})
else:
with open(metadata_path, 'r') as f:
metadata = json.load(f)
imported = 0
for item in metadata:
try:
filename = item['filename']
filepath = source_dir / filename
if not filepath.exists():
print(f" Skipping (file not found): {filename}")
continue
name = item['name']
description = item.get('description', '')
tags = item.get('tags', 'eye,imported')
# Check if already exists
existing = db.query(Patch).filter(Patch.name == name).first()
if existing:
print(f" Skipping (exists): {name}")
continue
# Load image
img = Image.open(filepath)
# Create database record
patch = Patch(
name=name,
description=description,
source_type="imported",
width=img.width,
height=img.height,
tags=tags,
category="eye",
is_public=True,
file_path="",
thumbnail_path=""
)
db.add(patch)
db.flush()
# Save to patch library
patch_path = patch_service.get_patch_path(patch.id)
img.save(patch_path, 'PNG')
# Create thumbnail
thumb_path = patch_service.get_thumbnail_path(patch.id)
patch_service.create_thumbnail(patch_path, thumb_path)
# Update paths
patch.file_path = f"patch_library/{patch.id}.png"
patch.thumbnail_path = f"patch_library/{patch.id}_thumb.png"
db.commit()
imported += 1
print(f" Imported: {name} (ID: {patch.id})")
except Exception as e:
db.rollback()
print(f" Error importing {item.get('filename', 'unknown')}: {e}")
return imported
def main():
parser = argparse.ArgumentParser(description='Import saved eye images to patch library')
parser.add_argument('source_dir', help='Directory containing eye images and metadata.json')
args = parser.parse_args()
source_dir = Path(args.source_dir)
if not source_dir.exists():
print(f"Error: Directory not found: {source_dir}")
sys.exit(1)
print("=" * 60)
print("Eye Image Importer")
print("=" * 60)
# Initialize database
print("\nInitializing database...")
Base.metadata.create_all(bind=engine)
db = SessionLocal()
# Initialize patch library
data_dir = os.environ.get("DATA_DIR", str(Path(__file__).parent.parent / "data"))
patch_service = PatchLibraryService(data_dir)
print(f"Source directory: {source_dir}")
print(f"Patch library: {patch_service.patch_library_dir}")
# Import
print("\nImporting eyes...")
imported = import_from_directory(source_dir, db, patch_service)
print("\n" + "=" * 60)
print(f"Import Complete! Imported {imported} eyes.")
print("=" * 60)
db.close()
if __name__ == "__main__":
main()