anu151105 commited on
Commit
3bb5012
·
verified ·
1 Parent(s): 96ee6f0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +347 -217
app.py CHANGED
@@ -1,239 +1,369 @@
1
- import random
2
- import os
3
- import uuid
4
- from datetime import datetime
5
  import gradio as gr
6
  import numpy as np
7
- import spaces
8
- import torch
 
 
 
 
 
 
9
  from diffusers import DiffusionPipeline
10
- from PIL import Image
11
- from huggingface_hub import login
12
-
13
- # ---------- Authentication ----------
14
- hf_token = os.environ.get("HF_TOKEN") # For HF Spaces or .env setups
15
- if hf_token:
16
- login(token=hf_token)
17
- else:
18
- print("⚠️ Warning: Hugging Face token not set. Cannot access gated models.")
19
-
20
- # ---------- 초기 설정 및 모델 로드 ----------
21
- SAVE_DIR = "saved_images"
22
- if not os.path.exists(SAVE_DIR):
23
- os.makedirs(SAVE_DIR, exist_ok=True)
24
 
 
25
  device = "cuda" if torch.cuda.is_available() else "cpu"
26
- repo_id = "black-forest-labs/FLUX.1-dev"
27
- adapter_id = "openfree/pepe"
28
 
29
- pipeline = DiffusionPipeline.from_pretrained(repo_id, torch_dtype=torch.bfloat16)
30
- pipeline.load_lora_weights(adapter_id)
31
- pipeline = pipeline.to(device)
32
 
33
  MAX_SEED = np.iinfo(np.int32).max
34
  MAX_IMAGE_SIZE = 1024
35
 
36
- def save_generated_image(image, prompt):
37
- timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
38
- unique_id = str(uuid.uuid4())[:8]
39
- filename = f"{timestamp}_{unique_id}.png"
40
- filepath = os.path.join(SAVE_DIR, filename)
41
- image.save(filepath)
42
-
43
- metadata_file = os.path.join(SAVE_DIR, "metadata.txt")
44
- with open(metadata_file, "a", encoding="utf-8") as f:
45
- f.write(f"{filename}|{prompt}|{timestamp}\n")
46
-
47
- return filepath
48
-
49
- def load_generated_images():
50
- if not os.path.exists(SAVE_DIR):
51
- return []
52
- image_files = [
53
- os.path.join(SAVE_DIR, f)
54
- for f in os.listdir(SAVE_DIR)
55
- if f.endswith(('.png', '.jpg', '.jpeg', '.webp'))
56
- ]
57
- image_files.sort(key=lambda x: os.path.getctime(x), reverse=True)
58
- return image_files
59
-
60
- def load_predefined_images():
61
- return []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
 
63
  css = """
64
- body {
65
- font-family: 'Open Sans', sans-serif;
66
- background: linear-gradient(135deg, #f5f7fa, #c3cfe2);
67
- margin: 0;
68
- padding: 0;
69
- }
70
- .title {
71
- font-size: 1.8em;
72
- font-weight: bold;
73
- text-align: center;
74
- margin: 20px 0;
75
- }
76
- footer {
77
- visibility: hidden;
78
  }
79
  """
80
 
81
- @spaces.GPU(duration=120)
82
- def inference(
83
- prompt: str,
84
- seed: int,
85
- randomize_seed: bool,
86
- width: int,
87
- height: int,
88
- guidance_scale: float,
89
- num_inference_steps: int,
90
- lora_scale: float,
91
- progress: gr.Progress = gr.Progress(track_tqdm=True),
92
- ):
93
- try:
94
- if randomize_seed:
95
- seed = random.randint(0, MAX_SEED)
96
- generator = torch.Generator(device=device).manual_seed(seed)
97
-
98
- image = pipeline(
99
- prompt=prompt,
100
- guidance_scale=guidance_scale,
101
- num_inference_steps=num_inference_steps,
102
- width=width,
103
- height=height,
104
- generator=generator,
105
- joint_attention_kwargs={"scale": lora_scale},
106
- ).images[0]
107
-
108
- filepath = save_generated_image(image, prompt)
109
- return image, seed, load_generated_images()
110
- except Exception as e:
111
- print(f"🚨 Generation error: {e}")
112
- return Image.new("RGB", (width, height), "white"), seed, load_generated_images()
113
-
114
- examples = [
115
- "Pepe the frog playing fetch with a golden retriever in a sunny park...",
116
- "Pepe the frog dressed in full military gear...",
117
- "A medieval Pepe knight in gleaming armor...",
118
- "A charismatic Pepe the frog addressing a crowd from a podium...",
119
- "Pepe the frog enjoying a peaceful morning at home...",
120
- "Businessman Pepe walking confidently through a sleek office lobby...",
121
- ]
122
-
123
- with gr.Blocks(css=css, theme=gr.themes.Soft(primary_hue="emerald"), analytics_enabled=False) as demo:
124
- gr.HTML('<div class="title">PEPE Meme Generator</div>')
125
-
126
- gr.HTML("""
127
- <a href="https://visitorbadge.io/status?path=https%3A%2F%2Fopenfree-pepe.hf.space">
128
- <img src="https://api.visitorbadge.io/api/visitors?path=https%3A%2F%2Fopenfree-pepe.hf.space&countColor=%23263759" />
129
- </a>
130
- """)
131
-
132
- with gr.Tabs() as tabs:
133
- with gr.Tab("Generation"):
134
- with gr.Column():
135
- with gr.Row():
136
- prompt = gr.Text(
137
- label="Prompt",
138
- show_label=False,
139
- max_lines=1,
140
- placeholder="Enter your prompt",
141
- container=False,
142
- )
143
- run_button = gr.Button("Run", scale=0)
144
-
145
- result = gr.Image(label="Result", show_label=False)
146
-
147
- with gr.Accordion("Advanced Settings", open=False):
148
- seed = gr.Slider(
149
- label="Seed",
150
- minimum=0,
151
- maximum=MAX_SEED,
152
- step=1,
153
- value=42,
154
- )
155
- randomize_seed = gr.Checkbox(
156
- label="Randomize seed",
157
- value=True
158
- )
159
-
160
- with gr.Row():
161
- width = gr.Slider(
162
- label="Width",
163
- minimum=256,
164
- maximum=MAX_IMAGE_SIZE,
165
- step=32,
166
- value=1024,
167
- )
168
- height = gr.Slider(
169
- label="Height",
170
- minimum=256,
171
- maximum=MAX_IMAGE_SIZE,
172
- step=32,
173
- value=768,
174
- )
175
-
176
- with gr.Row():
177
- guidance_scale = gr.Slider(
178
- label="Guidance scale",
179
- minimum=0.0,
180
- maximum=10.0,
181
- step=0.1,
182
- value=3.5,
183
- )
184
- num_inference_steps = gr.Slider(
185
- label="Number of inference steps",
186
- minimum=1,
187
- maximum=50,
188
- step=1,
189
- value=30,
190
- )
191
- lora_scale = gr.Slider(
192
- label="LoRA scale",
193
- minimum=0.0,
194
- maximum=1.0,
195
- step=0.1,
196
- value=1.0,
197
- )
198
-
199
- gr.Examples(
200
- examples=examples,
201
- inputs=[prompt],
202
- outputs=[result, seed],
203
- )
204
-
205
- with gr.Tab("Gallery"):
206
- gr.Markdown("### Generated Images Gallery")
207
- generated_gallery = gr.Gallery(
208
- label="Generated Images",
209
- columns=6,
210
- show_label=False,
211
- value=load_generated_images(),
212
- elem_id="generated_gallery",
213
- height="auto"
214
  )
215
- refresh_btn = gr.Button("🔄 Refresh Gallery")
216
 
217
- def refresh_gallery():
218
- return load_generated_images()
 
219
 
220
- refresh_btn.click(
221
- fn=refresh_gallery,
222
- inputs=None,
223
- outputs=generated_gallery,
224
- )
 
 
 
 
225
 
226
  run_button.click(
227
- fn=inference,
228
- inputs=[prompt, seed, randomize_seed, width, height, guidance_scale, num_inference_steps, lora_scale],
229
- outputs=[result, seed, generated_gallery],
230
- )
231
-
232
- prompt.submit(
233
- fn=inference,
234
- inputs=[prompt, seed, randomize_seed, width, height, guidance_scale, num_inference_steps, lora_scale],
235
- outputs=[result, seed, generated_gallery],
236
  )
237
 
238
- demo.queue()
239
- demo.launch()
 
 
 
 
 
1
  import gradio as gr
2
  import numpy as np
3
+ import random
4
+ import requests
5
+ import io
6
+ import re
7
+ from datetime import datetime
8
+ from PIL import Image, ImageDraw, ImageFont
9
+ import textwrap
10
+ import google.generativeai as genai
11
  from diffusers import DiffusionPipeline
12
+ import torch
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
+ # Set device and model for SDXL-Turbo
15
  device = "cuda" if torch.cuda.is_available() else "cpu"
16
+ model_repo_id = "stabilityai/sdxl-turbo"
17
+ torch_dtype = torch.float16 if torch.cuda.is_available() else torch.float32
18
 
19
+ # Initialize SDXL-Turbo pipeline
20
+ pipe = DiffusionPipeline.from_pretrained(model_repo_id, torch_dtype=torch_dtype)
21
+ pipe = pipe.to(device)
22
 
23
  MAX_SEED = np.iinfo(np.int32).max
24
  MAX_IMAGE_SIZE = 1024
25
 
26
+ class CurrentAffairsGenerator:
27
+ def __init__(self, gemini_api_key, news_api_key=None, logo_url=None):
28
+ self.gemini_api_key = gemini_api_key
29
+ self.news_api_key = news_api_key
30
+ self.logo_url = logo_url
31
+ self.newsapi_base_url = "https://newsapi.org/v2/everything"
32
+
33
+ if self.gemini_api_key:
34
+ try:
35
+ genai.configure(api_key=self.gemini_api_key)
36
+ self.gemini_model = genai.GenerativeModel('gemini-2.5-flash')
37
+ except Exception as e:
38
+ gr.Warning(f"Could not configure Gemini API: {e}.")
39
+ self.gemini_model = None
40
+ else:
41
+ self.gemini_model = None
42
+
43
+ self.brand_colors = {
44
+ 'primary': '#0F172A',
45
+ 'accent': '#F59E0B',
46
+ 'text': '#FFFFFF',
47
+ 'text_shadow': '#000000',
48
+ }
49
+
50
+ def fetch_latest_news(self, category):
51
+ if self.news_api_key:
52
+ gr.Info(f"Searching for live news about '{category}'...")
53
+ try:
54
+ news_data = self._search_with_newsapi(category)
55
+ if news_data:
56
+ gr.Info("Successfully fetched live news!")
57
+ return news_data
58
+ gr.Warning("Could not find relevant live news. Using a sample article.")
59
+ except Exception as e:
60
+ gr.Error(f"News API Error: {e}. Using a sample article.")
61
+
62
+ return self._get_sample_news(category)
63
+
64
+ def _search_with_newsapi(self, category):
65
+ params = {
66
+ 'q': f'"{category}" AND "India"',
67
+ 'language': 'en',
68
+ 'sortBy': 'publishedAt',
69
+ 'pageSize': 10,
70
+ 'apiKey': self.news_api_key
71
+ }
72
+ response = requests.get(self.newsapi_base_url, params=params)
73
+ response.raise_for_status()
74
+ articles = response.json().get('articles', [])
75
+
76
+ for article in articles:
77
+ content = article.get('content')
78
+ description = article.get('description')
79
+ full_content = content if content and len(content) > 10 else description
80
+
81
+ if full_content:
82
+ full_content_cleaned = re.sub(r'\[\s*\+\d+\s*chars\s*\]$', '', full_content).strip()
83
+ if len(full_content_cleaned) > 50:
84
+ return {
85
+ 'title': article['title'],
86
+ 'full_content': full_content_cleaned,
87
+ 'source': article['source']['name'],
88
+ 'category': category
89
+ }
90
+ return None
91
+
92
+ def _get_sample_news(self, topic=None):
93
+ sample_news = [
94
+ {'title': 'ISRO Confirms Gaganyaan Crew Module is Flight-Ready', 'full_content': 'The Indian Space Research Organisation has successfully completed all qualification tests for its first crewed space mission. This milestone includes rigorous vibration tests, acoustic assessments, and a series of parachute deployment simulations. The crew module is now officially certified for flight, bringing India one step closer to sending its own astronauts into space.', 'source': 'ISRO', 'category': 'Science'},
95
+ {'title': 'India Launches "Bharat AI" Research Supercluster', 'full_content': 'In a major push for artificial intelligence, the government has funded a new initiative to build a world-class AI ecosystem. This supercluster will connect top research institutions and startups, providing them with immense computing power and a platform for collaboration to solve India-specific challenges.', 'source': 'Ministry of Technology', 'category': 'Technology'},
96
+ {'title': 'UPI Transactions Cross 10 Billion Mark in a Single Month', 'full_content': 'India\'s Unified Payments Interface (UPI) has set a new global benchmark for digital payments, crossing the 10 billion transaction mark in a single month. This reflects the rapid and widespread adoption of digital finance across both urban and rural India, transforming the nation\'s economic landscape.', 'source': 'Reserve Bank of India', 'category': 'Economy'}
97
+ ]
98
+ if topic:
99
+ topic_lower = topic.lower()
100
+ filtered_news = [news for news in sample_news if topic_lower in news['category'].lower()]
101
+ if filtered_news: return random.choice(filtered_news)
102
+ return random.choice(sample_news)
103
+
104
+ def generate_llm_content(self, news_data):
105
+ if not self.gemini_model:
106
+ return news_data['title'], [f"Key Update: {news_data['full_content']}"]
107
+
108
+ prompt = f"""
109
+ Act as an expert social media analyst. Analyze this news:
110
+ Title: "{news_data['title']}"
111
+ Content: "{news_data['full_content']}"
112
+
113
+ Your Task:
114
+ 1. Create one short, impactful headline (under 10 words).
115
+ 2. Generate 3 highly informative bullet points.
116
+ 3. IMPORTANT: For the bullet points, provide ONLY the text. DO NOT include any leading emojis or symbols like '☐', '-', or '*'.
117
+
118
+ Output Format (Strictly follow this):
119
+ HEADLINE: [Your headline here]
120
+ BULLETS:
121
+ [Your first insightful bullet point text]
122
+ [Your second insightful bullet point text]
123
+ [Your third insightful bullet point text]
124
+ """
125
+ try:
126
+ response = self.gemini_model.generate_content(prompt)
127
+ clean_text = re.sub(r'[\*#]', '', response.text)
128
+
129
+ headline = clean_text.split("HEADLINE:")[1].split("BULLETS:")[0].strip()
130
+ bullets_str = clean_text.split("BULLETS:")[1].strip()
131
+ bullets = [line.strip().lstrip('- ') for line in bullets_str.split('\n') if line.strip()]
132
+
133
+ return headline, bullets[:3]
134
+ except Exception as e:
135
+ gr.Warning(f"Gemini content generation failed: {e}. Using fallback.")
136
+ return news_data['title'], [news_data['full_content']]
137
+
138
+ def create_image_prompt(self, news_data):
139
+ category = news_data.get('category', 'General').lower()
140
+ prompts = {
141
+ 'technology': [
142
+ "Futuristic cityscape with holographic data streams and glowing circuits, cinematic lighting, deep blue and gold palette, 4K hyper-detailed digital art.",
143
+ "Abstract visualization of a neural network, glowing nodes connected by light trails, dark background, symbolizing AI and connectivity.",
144
+ "Sleek server room with a liquid cooling system, neon blue lights reflecting on polished surfaces, representing high-performance computing.",
145
+ "Digital art of a human brain merging with a glowing circuit board, illustrating the concept of human-computer interface.",
146
+ ],
147
+ 'economy': [
148
+ "Abstract visualization of a bullish stock market graph turning into a growing tree with coin-like leaves, against a modern city skyline.",
149
+ "A dynamic 3D render of the Indian Rupee symbol glowing brightly, surrounded by upward-trending financial charts and graphs.",
150
+ "A bustling, modern marketplace where digital transactions are visualized as light flowing between people and vendors, symbolizing a digital economy.",
151
+ "Photorealistic image of a new infrastructure project like a bridge or highway, bathed in golden morning light, representing national growth.",
152
+ ],
153
+ 'science': [
154
+ "A stunning view of a satellite orbiting Earth with the Indian subcontinent visible below, against a cosmic background of nebulae and stars.",
155
+ "A clean, modern laboratory with scientists working with holographic displays showing DNA strands and molecular structures, high-tech aesthetic.",
156
+ "Digital painting of the Gaganyaan spacecraft soaring through the upper atmosphere, leaving a trail of fire and smoke.",
157
+ "Microscopic view of new material discovery, with crystalline structures glowing with internal light, abstract and beautiful.",
158
+ ],
159
+ 'environment': [
160
+ "Lush green Indian landscape integrating futuristic eco-technology like solar panels that follow the sun and artistic wind turbines.",
161
+ "A pristine river flowing through a regenerated forest, with clear water and abundant wildlife, symbolizing ecological restoration.",
162
+ "Concept art of a 'vertical forest' skyscraper in an Indian city, covered in plants and trees, promoting urban greening.",
163
+ "A split view showing a polluted city on one side and a clean, green city on the other, highlighting the choice for a sustainable future.",
164
+ ],
165
+ }
166
+ prompt_list = prompts.get(category, prompts['technology'])
167
+ base_prompt = random.choice(prompt_list)
168
+ return f"{base_prompt}, professional design, high resolution, visually striking for social media."
169
+
170
+ def generate_background_image(self, news_data, seed, randomize_seed, width=1024, height=1024, guidance_scale=0.0, num_inference_steps=2):
171
+ prompt = self.create_image_prompt(news_data)
172
+ gr.Info(f"🎨 Generating a unique image with prompt: \"{prompt}\"")
173
+
174
+ if randomize_seed:
175
+ seed = random.randint(0, MAX_SEED)
176
+
177
+ generator = torch.Generator().manual_seed(seed)
178
+
179
+ try:
180
+ image = pipe(
181
+ prompt=prompt,
182
+ negative_prompt="",
183
+ guidance_scale=guidance_scale,
184
+ num_inference_steps=num_inference_steps,
185
+ width=width,
186
+ height=height,
187
+ generator=generator,
188
+ ).images[0]
189
+ return image, seed
190
+ except Exception as e:
191
+ gr.Error(f"Image generation failed: {e}. Using fallback image.")
192
+ return self._create_fallback_image(), seed
193
+
194
+ def _create_fallback_image(self):
195
+ img = Image.new('RGB', (1080, 1080))
196
+ draw = ImageDraw.Draw(img)
197
+ for i in range(1080):
198
+ r, g, b = int(15 + 15 * (i/1080)), int(23 + 18 * (i/1080)), int(42 + 17 * (i/1080))
199
+ draw.line([(0, i), (1080, i)], fill=(r, g, b))
200
+ return img
201
+
202
+ def _get_logo(self, size=60):
203
+ if self.logo_url:
204
+ try:
205
+ response = requests.get(self.logo_url)
206
+ response.raise_for_status()
207
+ logo_img = Image.open(io.BytesIO(response.content)).convert("RGBA")
208
+ logo_img.thumbnail((size, size))
209
+ return logo_img
210
+ except Exception as e:
211
+ gr.Warning(f"Failed to load logo from URL: {e}. Using fallback.")
212
+ logo = Image.new('RGBA', (size, size), (0, 0, 0, 0))
213
+ draw = ImageDraw.Draw(logo)
214
+ draw.ellipse([0, 0, size, size], fill=self.brand_colors['accent'])
215
+ try:
216
+ font = ImageFont.truetype("seguibld.ttf", int(size * 0.7))
217
+ except IOError:
218
+ font = ImageFont.load_default()
219
+ draw.text((size/2, size/2), "P", font=font, fill='white', anchor="mm")
220
+ return logo
221
+
222
+ def _draw_text_with_outline(self, draw, position, text, font, fill_color, shadow_color):
223
+ x, y = position
224
+ outline = 2
225
+ for dx in range(-outline, outline + 1):
226
+ for dy in range(-outline, outline + 1):
227
+ if dx != 0 or dy != 0:
228
+ draw.text((x + dx, y + dy), text, font=font, fill=shadow_color)
229
+ draw.text(position, text, font=font, fill=fill_color)
230
+
231
+ def create_instagram_post(self, category, seed, randomize_seed, width=1024, height=1024, guidance_scale=0.0, num_inference_steps=2):
232
+ news_data = self.fetch_latest_news(category)
233
+ if not news_data:
234
+ gr.Error("Could not retrieve any news story. Please try again.")
235
+ return None, None, None, seed
236
+
237
+ headline, bullet_points = self.generate_llm_content(news_data)
238
+ bg_image, seed = self.generate_background_image(news_data, seed, randomize_seed, width, height, guidance_scale, num_inference_steps)
239
+ bg_image = bg_image.resize((1080, 1080))
240
+
241
+ overlay = Image.new('RGBA', (1080, 1080), (0, 0, 0, 0))
242
+ draw = ImageDraw.Draw(overlay)
243
+ draw.rectangle([0, 0, 1080, 1080], fill=(0, 0, 0, 80))
244
+
245
+ try:
246
+ title_font = ImageFont.truetype("impact.ttf", 85)
247
+ bullet_font = ImageFont.truetype("verdana.ttf", 36)
248
+ brand_font = ImageFont.truetype("verdana.ttf", 28)
249
+ date_font = ImageFont.truetype("verdanab.ttf", 24)
250
+ except IOError:
251
+ gr.Warning("Custom fonts not found. Using default fonts.")
252
+ title_font, bullet_font, brand_font, date_font = (ImageFont.load_default(),)*4
253
+
254
+ draw.text((60, 60), "TODAY'S UPDATE", font=date_font, fill=self.brand_colors['accent'])
255
+
256
+ y_pos = 150
257
+ for line in textwrap.wrap(headline.upper(), width=25):
258
+ self._draw_text_with_outline(draw, (60, y_pos), line, title_font, self.brand_colors['text'], self.brand_colors['text_shadow'])
259
+ y_pos += 95
260
+
261
+ y_pos = 480
262
+ content_area_end_y = 930
263
+ stop_drawing = False
264
+
265
+ for point_text in bullet_points:
266
+ if stop_drawing:
267
+ break
268
+
269
+ bullet_radius = 6
270
+ bullet_x = 70
271
+ first_line_height = bullet_font.getbbox('A')[3]
272
+ bullet_y = y_pos + (first_line_height / 2) - bullet_radius
273
+
274
+ if bullet_y > content_area_end_y:
275
+ break
276
+
277
+ draw.ellipse(
278
+ (bullet_x, bullet_y, bullet_x + bullet_radius*2, bullet_y + bullet_radius*2),
279
+ fill=self.brand_colors['accent']
280
+ )
281
+
282
+ text_x = bullet_x + bullet_radius*2 + 20
283
+ wrapped_text = textwrap.wrap(point_text, width=40)
284
+
285
+ line_y = y_pos
286
+ for line in wrapped_text:
287
+ if line_y + first_line_height > content_area_end_y:
288
+ stop_drawing = True
289
+ break
290
+
291
+ self._draw_text_with_outline(draw, (text_x, line_y), line, bullet_font, self.brand_colors['text'], self.brand_colors['text_shadow'])
292
+ line_y += 45
293
+
294
+ y_pos = line_y + 20
295
+
296
+ draw.rectangle([0, 950, 1080, 1080], fill=self.brand_colors['primary'])
297
+ logo = self._get_logo(size=100)
298
+
299
+ final_image = Image.alpha_composite(bg_image.convert('RGBA'), overlay)
300
+ final_image.paste(logo, (940, 965), logo)
301
+
302
+ draw_final = ImageDraw.Draw(final_image)
303
+ draw_final.text((60, 990), "+91 9354253889", font=brand_font, fill=self.brand_colors['text'], anchor="lm")
304
+ draw_final.text((920, 990), "pragzo.com", font=brand_font, fill=self.brand_colors['accent'], anchor="rm")
305
+
306
+ return final_image, headline, news_data, seed
307
+
308
+ # Gradio Interface
309
+ def generate_post(gemini_api_key, news_api_key, logo_url, category, seed, randomize_seed, width, height, guidance_scale, num_inference_steps, progress=gr.Progress(track_tqdm=True)):
310
+ if not gemini_api_key:
311
+ gr.Error("Please provide a Gemini API key.")
312
+ return None, None, None, seed
313
+
314
+ generator = CurrentAffairsGenerator(gemini_api_key, news_api_key, logo_url)
315
+ image, headline, news_data, seed = generator.create_instagram_post(category, seed, randomize_seed, width, height, guidance_scale, num_inference_steps)
316
+
317
+ if image:
318
+ img_buffer = io.BytesIO()
319
+ image.save(img_buffer, format='PNG')
320
+ return image, headline, f"**Original Title:** {news_data['title']}\n**Source:** {news_data['source']}\n**Content Analyzed by AI:**\n\n> {news_data['full_content']}", seed
321
+ return None, None, None, seed
322
 
323
  css = """
324
+ #col-container {
325
+ margin: 0 auto;
326
+ max-width: 800px;
 
 
 
 
 
 
 
 
 
 
 
327
  }
328
  """
329
 
330
+ with gr.Blocks(css=css) as demo:
331
+ gr.Markdown("# 🚀 Pragzo | AI Current Affairs Post Generator")
332
+ gr.Markdown("Instantly create stunning, unique Instagram posts from live news, powered by AI and SDXL-Turbo.")
333
+
334
+ with gr.Column(elem_id="col-container"):
335
+ with gr.Row():
336
+ gemini_api_key = gr.Textbox(label="Gemini API Key", type="password", placeholder="Enter your Gemini API key")
337
+ news_api_key = gr.Textbox(label="News API Key (Optional)", type="password", placeholder="Enter your News API key")
338
+ logo_url = gr.Textbox(label="Logo URL (Optional)", placeholder="https://.../logo.png")
339
+
340
+ with gr.Row():
341
+ category = gr.Dropdown(
342
+ label="News Category",
343
+ choices=["Technology", "Economy", "Science", "Environment", "Sports", "Education"],
344
+ value="Technology"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
345
  )
346
+ run_button = gr.Button("🛰️ Generate Post", variant="primary")
347
 
348
+ result = gr.Image(label="Generated Instagram Post", show_label=True)
349
+ headline = gr.Textbox(label="AI-Generated Headline", interactive=False)
350
+ news_content = gr.Markdown(label="Source News Content")
351
 
352
+ with gr.Accordion("Advanced Image Settings", open=False):
353
+ seed = gr.Slider(label="Seed", minimum=0, maximum=MAX_SEED, step=1, value=0)
354
+ randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
355
+ with gr.Row():
356
+ width = gr.Slider(label="Width", minimum=256, maximum=MAX_IMAGE_SIZE, step=32, value=1024)
357
+ height = gr.Slider(label="Height", minimum=256, maximum=MAX_IMAGE_SIZE, step=32, value=1024)
358
+ with gr.Row():
359
+ guidance_scale = gr.Slider(label="Guidance scale", minimum=0.0, maximum=10.0, step=0.1, value=0.0)
360
+ num_inference_steps = gr.Slider(label="Number of inference steps", minimum=1, maximum=50, step=1, value=2)
361
 
362
  run_button.click(
363
+ fn=generate_post,
364
+ inputs=[gemini_api_key, news_api_key, logo_url, category, seed, randomize_seed, width, height, guidance_scale, num_inference_steps],
365
+ outputs=[result, headline, news_content, seed]
 
 
 
 
 
 
366
  )
367
 
368
+ if __name__ == "__main__":
369
+ demo.launch()