File size: 3,205 Bytes
206183d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import openai
import time
import logging
from tenacity import retry, wait_exponential, stop_after_attempt
from PIL import Image
import requests
from io import BytesIO
import yaml

class FrameGenerator:
    def __init__(self, api_key, config_path='configs/frame_templates.yaml'):
        openai.api_key = api_key
        self.logger = logging.getLogger(__name__)
        self.templates = self._load_templates(config_path)
        self.rate_limit = 5  # Llamadas por minuto
        self.last_call = 0
        
    def _load_templates(self, config_path):
        try:
            with open(config_path) as f:
                return yaml.safe_load(f)['styles']
        except Exception as e:
            self.logger.error(f"Error loading templates: {str(e)}")
            return {}
            
    @retry(
        wait=wait_exponential(multiplier=1, min=4, max=60),
        stop=stop_after_attempt(3),
        reraise=True
    )
    def generate_frame(self, image_url, metadata):
        self._throttle_requests()
        style = metadata.get('style', 'minimalista')
        
        template = self.templates.get(style, self.templates['minimalista'])
        prompt = self._build_prompt(template, metadata)
        
        try:
            response = openai.images.generate(
                model="dall-e-3",
                prompt=prompt,
                size="1024x1024",
                quality="hd",
                n=1,
                response_format="url"
            )
            
            return self._composite_frame(
                image_url,
                response.data[0].url,
                template['mask_size']
            )
            
        except openai.RateLimitError:
            self.logger.warning("Rate limit exceeded, retrying...")
            time.sleep(60)
            raise
        except Exception as e:
            self.logger.error(f"Generation failed: {str(e)}")
            return None
            
    def _build_prompt(self, template, metadata):
        color_str = ", ".join(metadata['colors'][:3])
        return (
            f"High-quality frame for {metadata['style']} painting, "
            f"main colors: {color_str}. {template['prompt']} "
            "No text, no signatures, pure decorative frame."
        )
        
    def _throttle_requests(self):
        elapsed = time.time() - self.last_call
        if elapsed < 60 / self.rate_limit:
            time.sleep(60 / self.rate_limit - elapsed)
        self.last_call = time.time()
        
    def _composite_frame(self, original_url, frame_url, mask_size=800):
        try:
            original = Image.open(requests.get(original_url, stream=True).raw)
            frame = Image.open(requests.get(frame_url, stream=True).raw)
            
            original = original.resize((mask_size, mask_size))
            position = ((frame.width - original.width) // 2,
                       (frame.height - original.height) // 2)
            
            composite = frame.copy()
            composite.paste(original, position)
            
            return composite
            
        except Exception as e:
            self.logger.error(f"Compositing failed: {str(e)}")
            return None