"""Krita integration routes for ORA Editor.""" import os import shutil import time import zipfile from pathlib import Path from flask import Blueprint, request, jsonify from PIL import Image, ImageDraw from ora_editor.config import TEMP_DIR import logging logger = logging.getLogger(__name__) krita_bp = Blueprint('krita', __name__) @krita_bp.route('/api/krita/open', methods=['POST']) def api_krita_open(): """Open in Krita - behavior depends on mode. Review mode: Open the full ORA file for layer editing. Add mode: Export base image with polygon overlay for manual annotation. """ data = request.get_json() if not data or 'ora_path' not in data: return jsonify({'success': False, 'error': 'Missing ora_path parameter'}), 400 ora_path = data['ora_path'] try: if data.get('open_full_ora'): timestamp = str(int(time.time())) temp_file = TEMP_DIR / f"edit_{timestamp}.ora" shutil.copy2(ora_path, temp_file) return jsonify({ 'success': True, 'file_url': f'file://{temp_file}', 'temp_path': str(temp_file), 'base_mtime': os.path.getmtime(temp_file) }) elif data.get('open_base_with_polygon'): from ora_editor.services import polygon_storage points = data.get('points', []) color = data.get('color', '#FF0000') width = data.get('width', 2) with zipfile.ZipFile(ora_path, 'r') as zf: img = Image.open(zf.open('mergedimage.png')).convert('RGBA') if points and len(points) >= 3: w, h = img.size pixel_points = [(int(p['x'] * w), int(p['y'] * h)) for p in points] draw = ImageDraw.Draw(img) hex_color = color if len(color) == 7 else color + 'FF' draw.polygon(pixel_points, outline=hex_color, width=width) timestamp = str(int(time.time())) temp_file = TEMP_DIR / f"annotation_{timestamp}.png" img.save(str(temp_file), format='PNG') return jsonify({ 'success': True, 'file_url': f'file://{temp_file}', 'temp_path': str(temp_file), 'base_mtime': os.path.getmtime(temp_file) }) else: return jsonify({'success': False, 'error': 'Invalid request - specify open_full_ora or open_base_with_polygon'}), 400 except Exception as e: import traceback logger.error(f"[KRITA OPEN] Error: {e}") traceback.print_exc() return jsonify({'success': False, 'error': str(e)}), 500 @krita_bp.route('/api/krita/status/') def api_krita_status(layer_name): """Check if a Krita temp file has been modified.""" temp_files = list(TEMP_DIR.glob(f"{layer_name}_*.png")) if not temp_files: return jsonify({'success': False, 'error': 'No temp file found'}), 404 temp_file = max(temp_files, key=lambda f: f.stat().st_mtime) mtime = temp_file.stat().st_mtime stored_mtime = request.args.get('stored_mtime') if stored_mtime: modified = float(stored_mtime) != mtime else: modified = True return jsonify({ 'success': True, 'modified': modified, 'mtime': mtime, 'file_url': f'file://{temp_file}' })