dina1 commited on
Commit
d016a63
Β·
verified Β·
1 Parent(s): ad01bea

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +64 -66
app.py CHANGED
@@ -1,6 +1,6 @@
1
  # =========================================================
2
- # Intelligent PowerApps Mockup Generator (with Section Grouping)
3
- # From Business Requirement PDF β†’ Multi-Screen, Grouped PowerApps-Style Mockups
4
  # =========================================================
5
 
6
  import google.generativeai as genai
@@ -11,7 +11,6 @@ import uuid
11
  import os
12
  import re
13
  import time
14
- import json
15
 
16
  # -----------------------
17
  # Configure Gemini API
@@ -108,46 +107,51 @@ SVG_FLUENT = {
108
  }
109
 
110
  # -----------------------
111
- # Sidebar Generator (Grouped + Icons + Active Highlight)
112
  # -----------------------
113
- def generate_sidebar(app_title, grouped_screens, active_label="Dashboard"):
 
 
 
114
  """
115
- Builds a dynamic sidebar with section groupings, icons, and active highlight.
 
116
  """
 
 
117
  SCREEN_ICONS = [
118
- """<svg viewBox="0 0 24 24"><path fill="#c5c5c5" d="M3 13h2v-2H3v2zm4 0h14v-2H7v2zm-4 5h2v-2H3v2zm4 0h14v-2H7v2zM3 8h2V6H3v2zm4 0h14V6H7v2z"/></svg>""",
119
- """<svg viewBox="0 0 24 24"><path fill="#c5c5c5" d="M19 3H5a2 2 0 0 0-2 2v14l4-4h12a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z"/></svg>""",
120
- """<svg viewBox="0 0 24 24"><path fill="#c5c5c5" d="M3 3h18v4H3V3zm0 7h18v4H3v-4zm0 7h18v4H3v-4z"/></svg>""",
121
- """<svg viewBox="0 0 24 24"><path fill="#c5c5c5" d="M12 2a10 10 0 1 0 10 10A10.011 10.011 0 0 0 12 2zm1 15h-2v-2h2zm0-4h-2V7h2z"/></svg>""",
122
- """<svg viewBox="0 0 24 24"><path fill="#c5c5c5" d="M12 4a8 8 0 0 0 0 16 8 8 0 1 0 0-16zm1 11h-2v-2h2zm0-4h-2V7h2z"/></svg>""",
123
- """<svg viewBox="0 0 24 24"><path fill="#c5c5c5" d="M12 2L2 7l10 5 10-5-10-5zm0 7l10 5-10 5-10-5 10-5zm0 7l10 5-10 5-10-5 10-5z"/></svg>"""
124
  ]
125
 
126
  sidebar_html = "<div class='sidebar'>"
127
  sidebar_html += f"<div class='sidebar-header'>{SVG_FLUENT['hamburger']} {app_title}</div>"
128
 
129
- # Default static items
130
  defaults = [("home", "Home"), ("recent", "Recent"), ("pinned", "Pinned")]
131
  for key, label in defaults:
132
  sidebar_html += f"<div class='sidebar-item'>{SVG_FLUENT[key]}<span>{label}</span></div>"
133
 
134
- # Grouped section rendering
135
- for group in grouped_screens:
136
- section = group.get("section", "My Work")
137
- sidebar_html += f"<div class='sidebar-section'>{section}</div>"
138
- for i, screen in enumerate(group.get("screens", [])):
139
- screen_name = screen.get("screen_name", f"Screen {i+1}")
140
- active_class = "active" if screen_name == active_label else ""
141
- icon_svg = SCREEN_ICONS[i % len(SCREEN_ICONS)]
142
- if active_class:
143
- icon_svg = icon_svg.replace("#c5c5c5", "#fff")
144
- sidebar_html += f"<div class='sidebar-item {active_class}'>{icon_svg}<span>{screen_name}</span></div>"
145
 
146
  sidebar_html += "</div>"
147
  return sidebar_html
148
 
149
  # -----------------------
150
- # Analyze Business PDF β†’ Generate Grouped Screens
151
  # -----------------------
152
  def analyze_business_pdf(pdf_file):
153
  text = ""
@@ -166,55 +170,49 @@ def analyze_business_pdf(pdf_file):
166
  except Exception:
167
  app_title = "PowerApp Solution"
168
 
169
- # Step 2: Detect grouped screen structure
170
  try:
171
  response = model.generate_content(
172
- "You are a PowerApps UI/UX architect. Analyze the following business requirements and design a multi-screen PowerApp. "
173
- "Detect logical section groupings if present (for example: 'Metadata', 'Templates', 'Settings', 'User Management'). "
174
- "Return structured JSON ONLY, in this format:\n\n"
175
- "[{\n"
176
- " \"section\": \"Templates\",\n"
177
- " \"screens\": [\n"
178
- " {\"screen_name\": \"Document Templates\", \"html\": \"<div>...</div>\"}\n"
179
- " ]\n"
180
- "}]\n\n"
181
- "Each screen should contain realistic PowerApps-like HTML components (cards, forms, grids, buttons, etc.). "
182
- "Do not include explanations or text outside JSON."
183
  + "\n\n" + text
184
  )
185
  cleaned = re.sub(r"```(?:json)?|```", "", response.text.strip())
186
- grouped_screens = json.loads(cleaned)
 
 
 
 
187
  except Exception as e:
188
- print("⚠️ Gemini failed to create groupings:", e)
189
- grouped_screens = [{
190
- "section": "My Work",
191
- "screens": [{"screen_name": "Dashboard", "html": "<h2>Error</h2><p>Unable to parse screens.</p>"}]
192
- }]
193
 
194
- return app_title, grouped_screens
195
 
196
  # -----------------------
197
  # Generate HTML + Image per Screen
198
  # -----------------------
199
- def generate_mockups(app_title, grouped_screens):
200
  image_paths = []
201
- for group in grouped_screens:
202
- for screen in group.get("screens", []):
203
- label = screen.get("screen_name", "Screen")
204
- html_content = screen.get("html", "<h2>Empty Screen</h2>")
205
-
206
- sidebar_html = generate_sidebar(app_title, grouped_screens, active_label=label)
207
- full_html = BASE_TEMPLATE.replace("{user_sidebar}", sidebar_html)\
208
- .replace("{user_content}", html_content)\
209
- .replace("{app_title}", app_title)
210
-
211
- uid = str(uuid.uuid4())[:8]
212
- html_path = f"mockup_{label.replace(' ', '_')}_{uid}.html"
213
- img_path = f"mockup_{label.replace(' ', '_')}_{uid}.png"
214
- with open(html_path, "w", encoding="utf-8") as f:
215
- f.write(full_html)
216
- hti.screenshot(html_file=html_path, save_as=img_path)
217
- image_paths.append(img_path)
218
 
219
  return image_paths
220
 
@@ -224,8 +222,8 @@ def generate_mockups(app_title, grouped_screens):
224
  def generate_from_pdf(pdf_file):
225
  for attempt in range(3):
226
  try:
227
- app_title, grouped_screens = analyze_business_pdf(pdf_file)
228
- image_paths = generate_mockups(app_title, grouped_screens)
229
  return image_paths
230
  except Exception as e:
231
  if "429" in str(e) or "quota" in str(e).lower():
@@ -239,8 +237,8 @@ def generate_from_pdf(pdf_file):
239
  # Gradio UI
240
  # -----------------------
241
  with gr.Blocks() as demo:
242
- gr.Markdown("## 🧩 Intelligent PowerApps Mockup Generator (with Section Grouping)")
243
- gr.Markdown("Upload a **Business Requirement PDF**. Gemini 2.5 Pro will infer grouped sections, screens, and layouts β€” then render PowerApps-style mockup images for each screen.")
244
  pdf_input = gr.File(label="πŸ“„ Upload Business Requirement PDF", file_types=[".pdf"])
245
  generate_btn = gr.Button("πŸš€ Generate Mockups")
246
  gallery_output = gr.Gallery(label="Generated Screens", show_label=True, columns=2)
 
1
  # =========================================================
2
+ # Intelligent PowerApps Mockup Generator
3
+ # From Business Requirement PDF β†’ Multi-Screen PowerApps-Style Mockup Images
4
  # =========================================================
5
 
6
  import google.generativeai as genai
 
11
  import os
12
  import re
13
  import time
 
14
 
15
  # -----------------------
16
  # Configure Gemini API
 
107
  }
108
 
109
  # -----------------------
110
+ # Sidebar Generator
111
  # -----------------------
112
+ # -----------------------
113
+ # Sidebar Generator (Enhanced with unique icons)
114
+ # -----------------------
115
+ def generate_sidebar(app_title, screens, active_label="Dashboard"):
116
  """
117
+ Dynamically builds the sidebar with unique icons for each screen.
118
+ The current screen (active_label) is highlighted in blue.
119
  """
120
+
121
+ # Additional Fluent-style icons for screens
122
  SCREEN_ICONS = [
123
+ """<svg viewBox="0 0 24 24"><path fill="#c5c5c5" d="M3 13h2v-2H3v2zm4 0h14v-2H7v2zm-4 5h2v-2H3v2zm4 0h14v-2H7v2zM3 8h2V6H3v2zm4 0h14V6H7v2z"/></svg>""", # list-style
124
+ """<svg viewBox="0 0 24 24"><path fill="#c5c5c5" d="M19 3H5a2 2 0 0 0-2 2v14l4-4h12a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z"/></svg>""", # message/note
125
+ """<svg viewBox="0 0 24 24"><path fill="#c5c5c5" d="M3 3h18v4H3V3zm0 7h18v4H3v-4zm0 7h18v4H3v-4z"/></svg>""", # stacked docs
126
+ """<svg viewBox="0 0 24 24"><path fill="#c5c5c5" d="M12 2a10 10 0 1 0 10 10A10.011 10.011 0 0 0 12 2zm1 15h-2v-2h2zm0-4h-2V7h2z"/></svg>""", # info icon
127
+ """<svg viewBox="0 0 24 24"><path fill="#c5c5c5" d="M12 4a8 8 0 0 0 0 16 8 8 0 1 0 0-16zm1 11h-2v-2h2zm0-4h-2V7h2z"/></svg>""", # alert-like
128
+ """<svg viewBox="0 0 24 24"><path fill="#c5c5c5" d="M12 2L2 7l10 5 10-5-10-5zm0 7l10 5-10 5-10-5 10-5zm0 7l10 5-10 5-10-5 10-5z"/></svg>""" # layered archive
129
  ]
130
 
131
  sidebar_html = "<div class='sidebar'>"
132
  sidebar_html += f"<div class='sidebar-header'>{SVG_FLUENT['hamburger']} {app_title}</div>"
133
 
134
+ # Default static options
135
  defaults = [("home", "Home"), ("recent", "Recent"), ("pinned", "Pinned")]
136
  for key, label in defaults:
137
  sidebar_html += f"<div class='sidebar-item'>{SVG_FLUENT[key]}<span>{label}</span></div>"
138
 
139
+ # Dynamic section
140
+ sidebar_html += "<div class='sidebar-section'>My Work</div>"
141
+ for i, screen in enumerate(screens):
142
+ screen_name = screen.get("screen_name", f"Screen {i+1}")
143
+ active_class = "active" if screen_name == active_label else ""
144
+ icon_svg = SCREEN_ICONS[i % len(SCREEN_ICONS)]
145
+ if active_class:
146
+ # Make active icon blue
147
+ icon_svg = icon_svg.replace("#c5c5c5", "#fff")
148
+ sidebar_html += f"<div class='sidebar-item {active_class}'>{icon_svg}<span>{screen_name}</span></div>"
 
149
 
150
  sidebar_html += "</div>"
151
  return sidebar_html
152
 
153
  # -----------------------
154
+ # Analyze Business PDF β†’ Generate Multi-Screen HTML
155
  # -----------------------
156
  def analyze_business_pdf(pdf_file):
157
  text = ""
 
170
  except Exception:
171
  app_title = "PowerApp Solution"
172
 
173
+ # Step 2: Ask Gemini to identify screens and their HTML layouts
174
  try:
175
  response = model.generate_content(
176
+ "You are a PowerApps UI designer. Analyze the following business requirements and infer multiple PowerApps screens if applicable. "
177
+ "Return structured JSON like this:\n"
178
+ "[{\"screen_name\": \"Dashboard\", \"html\": \"<div>...</div>\"}, {\"screen_name\": \"Reports\", \"html\": \"<div>...</div>\"}]\n\n"
179
+ "Each HTML should represent a PowerApps-style UI (forms, tables, charts, buttons, labels). "
180
+ "Do not include explanations. Return valid JSON only."
 
 
 
 
 
 
181
  + "\n\n" + text
182
  )
183
  cleaned = re.sub(r"```(?:json)?|```", "", response.text.strip())
184
+ screens = []
185
+ try:
186
+ screens = eval(cleaned) if cleaned.strip().startswith("[") else []
187
+ except Exception:
188
+ screens = [{"screen_name": "Dashboard", "html": "<h2>Fallback Layout</h2><p>Unable to parse screen data.</p>"}]
189
  except Exception as e:
190
+ print("⚠️ Gemini failed to create screens:", e)
191
+ screens = [{"screen_name": "Dashboard", "html": "<h2>Error</h2><p>Gemini failed to process this PDF.</p>"}]
 
 
 
192
 
193
+ return app_title, screens
194
 
195
  # -----------------------
196
  # Generate HTML + Image per Screen
197
  # -----------------------
198
+ def generate_mockups(app_title, screens):
199
  image_paths = []
200
+ for screen in screens:
201
+ label = screen.get("screen_name", "Screen")
202
+ html_content = screen.get("html", "<h2>Empty Screen</h2>")
203
+
204
+ sidebar_html = generate_sidebar(app_title, screens, active_label=label)
205
+ full_html = BASE_TEMPLATE.replace("{user_sidebar}", sidebar_html)\
206
+ .replace("{user_content}", html_content)\
207
+ .replace("{app_title}", app_title)
208
+
209
+ uid = str(uuid.uuid4())[:8]
210
+ html_path = f"mockup_{label.replace(' ', '_')}_{uid}.html"
211
+ img_path = f"mockup_{label.replace(' ', '_')}_{uid}.png"
212
+ with open(html_path, "w", encoding="utf-8") as f:
213
+ f.write(full_html)
214
+ hti.screenshot(html_file=html_path, save_as=img_path)
215
+ image_paths.append(img_path)
 
216
 
217
  return image_paths
218
 
 
222
  def generate_from_pdf(pdf_file):
223
  for attempt in range(3):
224
  try:
225
+ app_title, screens = analyze_business_pdf(pdf_file)
226
+ image_paths = generate_mockups(app_title, screens)
227
  return image_paths
228
  except Exception as e:
229
  if "429" in str(e) or "quota" in str(e).lower():
 
237
  # Gradio UI
238
  # -----------------------
239
  with gr.Blocks() as demo:
240
+ gr.Markdown("## 🧩 Intelligent PowerApps Mockup Generator (Multi-Screen Mode)")
241
+ gr.Markdown("Upload a **Business Requirement PDF**. Gemini 2.5 Pro will infer all screens, UI elements, and layouts β€” then render separate PowerApps-style mockup images for each screen.")
242
  pdf_input = gr.File(label="πŸ“„ Upload Business Requirement PDF", file_types=[".pdf"])
243
  generate_btn = gr.Button("πŸš€ Generate Mockups")
244
  gallery_output = gr.Gallery(label="Generated Screens", show_label=True, columns=2)