Keyurjotaniya007 commited on
Commit
b4cb782
·
verified ·
1 Parent(s): 7f101d9

Update chatbot.py

Browse files
Files changed (1) hide show
  1. chatbot.py +123 -92
chatbot.py CHANGED
@@ -1,102 +1,136 @@
1
  import time
2
  import base64
3
  import io
4
- import cssutils
5
  from PIL import Image
6
  from bs4 import BeautifulSoup
7
  from langchain_google_genai import ChatGoogleGenerativeAI
8
  from langchain_core.messages import HumanMessage
9
 
10
- def resize_and_encode_image(image_file, max_size=(400, 400)):
11
  img = Image.open(image_file)
12
- img.thumbnail(max_size)
13
  buffered = io.BytesIO()
14
- img.save(buffered, format="JPEG")
15
  image_bytes = buffered.getvalue()
16
  base64_str = base64.b64encode(image_bytes).decode("utf-8")
17
- return f"data:image/jpeg;base64,{base64_str}"
18
 
19
  def beautify_html(html_code):
20
  soup = BeautifulSoup(html_code, "html.parser")
21
  return soup.prettify()
22
 
23
- def apply_css_rules(soup, css_code):
24
- sheet = cssutils.parseString(css_code)
25
- for rule in sheet:
26
- if rule.type == rule.STYLE_RULE:
27
- selector = rule.selectorText.strip()
28
- styles = rule.style.cssText
29
- if selector.startswith('.'):
30
- class_name = selector[1:]
31
- elements = soup.find_all(class_=class_name)
32
- for el in elements:
33
- if 'display: none' in styles:
34
- el.decompose()
35
- else:
36
- el['style'] = styles
37
- elif selector.startswith('#'):
38
- id_name = selector[1:]
39
- el = soup.find(id=id_name)
40
- if el:
41
- if 'display: none' in styles:
42
- el.decompose()
43
- else:
44
- el['style'] = styles
45
- return soup
46
-
47
  def generate_html_css_from_image(image_file):
48
  image_data_url = resize_and_encode_image(image_file)
49
 
50
  prompt_text = """
51
- You are an expert front-end developer.
52
-
53
- The input is a screenshot of a website UI. Carefully analyze its layout and generate accurate, semantic, and maintainable HTML and CSS.
54
-
55
- [TRUNCATED for brevity in this view — keep full original prompt_text block unchanged]
56
-
57
- Follow these professional guidelines:
58
-
59
- 1) Structure & Semantics:
60
- - Use HTML5 semantic tags that match the visual hierarchy (e.g., <header>, <nav>, <main>, <section>, <article>, <aside>, <footer>)
61
- - Reflect layout grouping using appropriate containers and divs where needed
62
-
63
- 2) Layout & Responsiveness:
64
- - Use Flexbox or CSS Grid for layout
65
- - Include responsive breakpoints (mobile-first) with at least one media query
66
- - Ensure layout adapts well to mobile screen sizes
67
-
68
- 3) CSS Practices:
69
- - Keep CSS in a <style> block or separate file (no inline styles)
70
- - Use class names that follow a clean naming convention (e.g., BEM or descriptive naming)
71
- - Group CSS rules logically (layout, typography, components)
72
-
73
- 4) Accessibility & UX:
74
- - Add accessible markup: alt text, ARIA roles, labels
75
- - Ensure good contrast and keyboard navigability
76
-
77
- 5) Content & Comments:
78
- - Use meaningful placeholder text (not lorem ipsum)
79
- - Add short code comments to explain each major section
80
-
81
- 6) Output:
82
- - The output should be a complete single HTML file with embedded CSS
83
- - Preserve the visual structure and content flow of the original screenshot as closely as possible
84
- - Do not skip or summarize any sections
85
-
86
- Assume this is for real production-ready front-end code generation from a web UI screenshot.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  """
88
 
89
  prompt = [
90
  HumanMessage(
91
  content=[
92
  {"type": "text", "text": prompt_text},
93
- {"type": "image_url", "image_url": {"url": image_data_url, "mime_type": "image/jpeg"}}
94
  ]
95
  )
96
  ]
97
 
98
  llm = ChatGoogleGenerativeAI(model="gemini-2.5-flash", temperature=0)
99
- max_retries = 3
100
  generated_code = None
101
 
102
  for attempt in range(max_retries):
@@ -112,35 +146,32 @@ Assume this is for real production-ready front-end code generation from a web UI
112
  .strip()
113
  )
114
 
115
- break
116
- except Exception as e:
117
- if "ResourceExhausted" in str(e) or "429" in str(e):
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  time.sleep(30 * (attempt + 1))
119
  else:
120
- raise e
 
121
 
122
  if generated_code:
123
- soup = BeautifulSoup(generated_code, "html.parser")
124
- style_tag = soup.find("style")
125
- css_code = style_tag.string if style_tag else ""
126
- html_without_style = str(soup).replace(str(style_tag), "") if style_tag else str(soup)
127
-
128
- soup = apply_css_rules(BeautifulSoup(html_without_style, "html.parser"), css_code)
129
- cleaned_html = beautify_html(str(soup))
130
-
131
- final_output = f"""<!DOCTYPE html>
132
- <html lang="en">
133
- <head>
134
- <meta charset="UTF-8">
135
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
136
- <style>
137
- {css_code}
138
- </style>
139
- </head>
140
- <body>
141
- {cleaned_html}
142
- </body>
143
- </html>"""
144
 
145
  return final_output
146
  else:
 
1
  import time
2
  import base64
3
  import io
 
4
  from PIL import Image
5
  from bs4 import BeautifulSoup
6
  from langchain_google_genai import ChatGoogleGenerativeAI
7
  from langchain_core.messages import HumanMessage
8
 
9
+ def resize_and_encode_image(image_file, max_size=(768, 768)):
10
  img = Image.open(image_file)
11
+ img.thumbnail(max_size, Image.Resampling.LANCZOS)
12
  buffered = io.BytesIO()
13
+ img.save(buffered, format="PNG")
14
  image_bytes = buffered.getvalue()
15
  base64_str = base64.b64encode(image_bytes).decode("utf-8")
16
+ return f"data:image/png;base64,{base64_str}"
17
 
18
  def beautify_html(html_code):
19
  soup = BeautifulSoup(html_code, "html.parser")
20
  return soup.prettify()
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  def generate_html_css_from_image(image_file):
23
  image_data_url = resize_and_encode_image(image_file)
24
 
25
  prompt_text = """
26
+ You are an expert front-end developer tasked with converting a UI screenshot into a single, production-ready HTML file with embedded CSS.
27
+ Analyze the provided screenshot meticulously and generate the corresponding HTML and CSS code.
28
+
29
+ Here are the strict guidelines you must follow:
30
+
31
+ 1. *Complete HTML Structure*:
32
+ * Generate a full HTML5 document including ⁠ <!DOCTYPE html> ⁠, ⁠ <html> ⁠, ⁠ <head> ⁠, ⁠ <body> ⁠.
33
+ * Include essential meta tags: ⁠ charset="UTF-8" ⁠, ⁠ name="viewport" ⁠, ⁠ initial-scale=1.0" ⁠.
34
+ * The CSS MUST be embedded within a ⁠ <style> ⁠ tag inside the ⁠ <head> ⁠ section. DO NOT use inline styles.
35
+ * Use semantic HTML5 tags (e.g., ⁠ <header> ⁠, ⁠ <nav> ⁠, ⁠ <main> ⁠, ⁠ <section> ⁠, ⁠ <article> ⁠, ⁠ <aside> ⁠, ⁠ <footer> ⁠, ⁠ <button> ⁠, ⁠ <a> ⁠, ⁠ <h1> ⁠ to ⁠ <h6> ⁠, ⁠ <p> ⁠) to accurately reflect the visual hierarchy and content purpose.
36
+ * Organize content logically with ⁠ <div> ⁠ elements where semantic tags are not appropriate, using classes for styling.
37
+
38
+ 2. *Layout and Responsiveness*:
39
+ * Employ modern CSS layout techniques: primarily *Flexbox* or *CSS Grid* for main layouts and component arrangements.
40
+ * Implement *mobile-first responsive design*. Include at least one ⁠ @media ⁠ query to adapt the layout for larger screens (e.g., tablets and desktops).
41
+ * Ensure elements maintain their relative positions, sizing, and spacing as seen in the screenshot across different screen sizes. Pay close attention to padding, margins, and alignment.
42
+
43
+ 3. *Visual Fidelity (Pixel-Perfect Approach)*:
44
+ * Match the colors (backgrounds, text, buttons), font styles (font-family, font-size, font-weight), text alignment, and spacing (padding, margin, gap) as precisely as possible to the screenshot.
45
+ * Accurately reproduce element dimensions (width, height) where visually apparent.
46
+ * Replicate borders, shadows, and any other visual effects.
47
+ * If specific fonts are not easily identifiable, use common web-safe fonts like Arial, Helvetica, or sans-serif, but prioritize replicating the visual weight and size.
48
+ * For icons or images, use placeholder ⁠ <div>`s with appropriate dimensions and background colors/gradients, or `<img> ⁠ tags with ⁠ alt ⁠ attributes and placeholder ⁠ src ⁠ if specific image content isn't clearly inferable (though try to match the shape and size).
49
+
50
+ 4. *CSS Best Practices*:
51
+ * Use descriptive and consistent class names (e.g., following a BEM-like convention or clear, semantic names like ⁠ header-nav ⁠, ⁠ hero-section ⁠, ⁠ feature-card ⁠).
52
+ * Group related CSS properties together (e.g., layout, then typography, then colors).
53
+ * Add concise CSS comments for major sections or complex styles.
54
+ * Avoid redundant or unnecessary CSS.
55
+
56
+ 5. *Content Accuracy*:
57
+ * Reproduce all visible text content verbatim from the screenshot.
58
+ * For interactive elements (buttons, links), ensure they have appropriate tags (⁠<button> ⁠, ⁠<a>) and placeholder text.
59
+
60
+ 6. *Code Quality*:
61
+ * The generated code must be clean, well-formatted, and easy to read.
62
+ * Do not include any JavaScript unless explicitly requested (and it's not requested here).
63
+ * The output must be ONLY the HTML and CSS, without any conversational text or explanations. Wrap the entire output in a single Markdown HTML block (⁠  html...  ⁠).
64
+
65
+ 7. *Example Output Format (Strictly Adhere to this structure)*:
66
+ ⁠```html
67
+ <!DOCTYPE html>
68
+ <html lang="en">
69
+ <head>
70
+ <meta charset="UTF-8">
71
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
72
+ <title>Generated UI</title>
73
+ <style>
74
+ /* Global styles */
75
+ body {
76
+ font-family: Arial, sans-serif;
77
+ margin: 0;
78
+ padding: 0;
79
+ box-sizing: border-box;
80
+ background-color: #ffffff; /* Adjust based on screenshot */
81
+ }
82
+
83
+ /* Header styles */
84
+ .header {
85
+ /* ... CSS for header ... */
86
+ }
87
+
88
+ /* Hero section styles */
89
+ .hero-section {
90
+ /* ... CSS for hero section ... */
91
+ }
92
+
93
+ /* Features section styles */
94
+ .features-section {
95
+ /* ... CSS for features section ... */
96
+ }
97
+
98
+ /* Media queries for responsiveness */
99
+ @media (min-width: 768px) {
100
+ /* ... responsive styles ... */
101
+ }
102
+ </style>
103
+ </head>
104
+ <body>
105
+ <header class="header">
106
+ </header>
107
+
108
+ <main>
109
+ <section class="hero-section">
110
+ </section>
111
+
112
+ <section class="features-section">
113
+ </section>
114
+ </main>
115
+
116
+ <footer class="footer">
117
+ </footer>
118
+ </body>
119
+ </html>
120
+ ```
121
  """
122
 
123
  prompt = [
124
  HumanMessage(
125
  content=[
126
  {"type": "text", "text": prompt_text},
127
+ {"type": "image_url", "image_url": {"url": image_data_url, "mime_type": "image/png"}}
128
  ]
129
  )
130
  ]
131
 
132
  llm = ChatGoogleGenerativeAI(model="gemini-2.5-flash", temperature=0)
133
+ max_retries = 5
134
  generated_code = None
135
 
136
  for attempt in range(max_retries):
 
146
  .strip()
147
  )
148
 
149
+ elif generated_code.strip().startswith("<!DOCTYPE html>"):
150
+ pass
151
+ else:
152
+ start_index = generated_code.find("<!DOCTYPE html>")
153
+ if start_index != -1:
154
+ generated_code = generated_code[start_index:].strip()
155
+
156
+ if "<html" in generated_code.lower() and "<body" in generated_code.lower():
157
+ break
158
+ else:
159
+ print(f"Attempt {attempt+1}: Generated code missing HTML/BODY tags. Retrying...")
160
+ time.sleep(5)
161
+
162
+ except Exception as e:
163
+ if "ResourceExhausted" in str(e) or "429" in str(e) or "500" in str(e):
164
+ print(f"Attempt {attempt+1}: Rate limit or server error. Retrying in {30 * (attempt + 1)} seconds...")
165
  time.sleep(30 * (attempt + 1))
166
  else:
167
+ print(f"Attempt {attempt+1}: Unexpected error: {e}. Retrying...")
168
+ time.sleep(5)
169
 
170
  if generated_code:
171
+ final_output = beautify_html(generated_code)
172
+
173
+ if not final_output.strip().startswith("<!DOCTYPE html>"):
174
+ final_output = "<!DOCTYPE html>\n" + final_output
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
 
176
  return final_output
177
  else: