AkashKumarave commited on
Commit
ddf0b73
·
verified ·
1 Parent(s): 3f24782

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +44 -49
app.py CHANGED
@@ -1,4 +1,3 @@
1
-
2
  import os
3
  import json
4
  import requests
@@ -8,6 +7,7 @@ from flask_cors import CORS
8
  import cssutils
9
  import re
10
  from urllib.parse import urlparse, urljoin
 
11
 
12
  app = Flask(__name__)
13
  CORS(app) # Enable CORS for all routes
@@ -26,12 +26,13 @@ def convert_website():
26
  url = data['url']
27
 
28
  try:
29
- # Fetch the website content
30
  website_data = fetch_website(url)
31
 
32
  # Parse and convert website to Figma-compatible format
33
  figma_data = convert_to_figma_format(website_data, url)
34
 
 
35
  return jsonify({
36
  "success": True,
37
  "data": figma_data
@@ -45,15 +46,14 @@ def convert_website():
45
  }), 500
46
 
47
  def fetch_website(url):
48
- """Fetch website HTML content"""
49
- headers = {
50
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
51
- }
52
-
53
- response = requests.get(url, headers=headers)
54
- response.raise_for_status()
55
-
56
- return response.text
57
 
58
  def convert_to_figma_format(html_content, base_url):
59
  """Convert website HTML to Figma-compatible format"""
@@ -91,7 +91,6 @@ def parse_element(element, base_url, depth=0):
91
 
92
  elements = []
93
 
94
- # Process only element nodes (skip text nodes, etc.)
95
  for child in element.children:
96
  if not hasattr(child, 'name') or not child.name:
97
  continue
@@ -100,7 +99,7 @@ def parse_element(element, base_url, depth=0):
100
  if child.name in ['script', 'style', 'meta', 'link', 'noscript']:
101
  continue
102
 
103
- # Get element style
104
  style = extract_style(child)
105
 
106
  element_data = {
@@ -111,7 +110,9 @@ def parse_element(element, base_url, depth=0):
111
 
112
  # Handle text content
113
  if element_data["type"] == "text":
114
- element_data["content"] = child.get_text().strip()
 
 
115
 
116
  # Handle image elements
117
  if child.name == 'img' and child.get('src'):
@@ -143,19 +144,12 @@ def parse_element(element, base_url, depth=0):
143
 
144
  def determine_element_type(element):
145
  """Determine the Figma element type based on HTML element"""
146
- # Text elements
147
  if element.name in ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'span', 'a', 'label', 'li']:
148
  return "text"
149
-
150
- # Image elements
151
  if element.name == 'img':
152
  return "image"
153
-
154
- # Button elements
155
  if element.name == 'button' or (element.name == 'input' and element.get('type') in ['submit', 'button']):
156
  return "button"
157
-
158
- # Default to container
159
  return "container"
160
 
161
  def extract_style(element):
@@ -164,42 +158,43 @@ def extract_style(element):
164
 
165
  # Extract inline styles
166
  if element.get('style'):
167
- inline_styles = cssutils.parseStyle(element.get('style'))
168
- for prop in inline_styles:
169
- style[prop.name] = prop.value
170
-
171
- # Extract dimensions and position from attributes
172
- if element.get('width'):
173
- style['width'] = f"{element.get('width')}px"
174
- if element.get('height'):
175
- style['height'] = f"{element.get('height')}px"
176
-
177
- # Set default dimensions for certain elements
178
  if element.name in ['div', 'section', 'article', 'main']:
179
- if 'width' not in style:
180
- style['width'] = '100%'
181
- if 'height' not in style:
182
- style['height'] = 'auto'
183
 
184
- # Extract colors
185
  if element.get('color'):
186
- style['color'] = element.get('color')
187
  elif element.name in ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']:
188
- style['color'] = '#000000'
189
 
190
  # Extract font sizes
191
  if element.name == 'h1':
192
- style['fontSize'] = '32px'
193
  elif element.name == 'h2':
194
- style['fontSize'] = '24px'
195
  elif element.name == 'h3':
196
- style['fontSize'] = '18px'
197
  elif element.name in ['p', 'span', 'a', 'li']:
198
- style['fontSize'] = '16px'
199
 
200
- return style
201
-
202
- if __name__ == '__main__':
203
- # Get port from environment variable or use default
204
- port = int(os.environ.get('PORT', 7860))
205
- app.run(host='0.0.0.0', port=port)
 
 
 
 
 
 
 
1
  import os
2
  import json
3
  import requests
 
7
  import cssutils
8
  import re
9
  from urllib.parse import urlparse, urljoin
10
+ from playwright.sync_api import sync_playwright
11
 
12
  app = Flask(__name__)
13
  CORS(app) # Enable CORS for all routes
 
26
  url = data['url']
27
 
28
  try:
29
+ # Fetch the website content with Playwright for dynamic content
30
  website_data = fetch_website(url)
31
 
32
  # Parse and convert website to Figma-compatible format
33
  figma_data = convert_to_figma_format(website_data, url)
34
 
35
+ print("Figma data:", json.dumps(figma_data, indent=2)) # Debug log
36
  return jsonify({
37
  "success": True,
38
  "data": figma_data
 
46
  }), 500
47
 
48
  def fetch_website(url):
49
+ """Fetch website HTML content using Playwright for rendered DOM"""
50
+ with sync_playwright() as p:
51
+ browser = p.chromium.launch(headless=True)
52
+ page = browser.new_page()
53
+ page.goto(url, wait_until="networkidle")
54
+ html_content = page.content()
55
+ browser.close()
56
+ return html_content
 
57
 
58
  def convert_to_figma_format(html_content, base_url):
59
  """Convert website HTML to Figma-compatible format"""
 
91
 
92
  elements = []
93
 
 
94
  for child in element.children:
95
  if not hasattr(child, 'name') or not child.name:
96
  continue
 
99
  if child.name in ['script', 'style', 'meta', 'link', 'noscript']:
100
  continue
101
 
102
+ # Get element style (inline and computed)
103
  style = extract_style(child)
104
 
105
  element_data = {
 
110
 
111
  # Handle text content
112
  if element_data["type"] == "text":
113
+ text_content = child.get_text().strip()
114
+ if text_content:
115
+ element_data["content"] = text_content
116
 
117
  # Handle image elements
118
  if child.name == 'img' and child.get('src'):
 
144
 
145
  def determine_element_type(element):
146
  """Determine the Figma element type based on HTML element"""
 
147
  if element.name in ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'span', 'a', 'label', 'li']:
148
  return "text"
 
 
149
  if element.name == 'img':
150
  return "image"
 
 
151
  if element.name == 'button' or (element.name == 'input' and element.get('type') in ['submit', 'button']):
152
  return "button"
 
 
153
  return "container"
154
 
155
  def extract_style(element):
 
158
 
159
  # Extract inline styles
160
  if element.get('style'):
161
+ try:
162
+ inline_styles = cssutils.parseStyle(element['style'])
163
+ for prop in inline_styles:
164
+ style[prop.name] = prop.value
165
+ except Exception as e:
166
+ print(f"Error parsing inline styles for {element.name}: {e}")
167
+
168
+ # Add default styles for specific elements
 
 
 
169
  if element.name in ['div', 'section', 'article', 'main']:
170
+ style.setdefault('width', '100%')
171
+ style.setdefault('height', 'auto')
172
+ style.setdefault('display', 'block')
 
173
 
174
+ # Extract colors and backgrounds
175
  if element.get('color'):
176
+ style['color'] = element['color']
177
  elif element.name in ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']:
178
+ style.setdefault('color', '#000000')
179
 
180
  # Extract font sizes
181
  if element.name == 'h1':
182
+ style.setdefault('fontSize', '32px')
183
  elif element.name == 'h2':
184
+ style.setdefault('fontSize', '24px')
185
  elif element.name == 'h3':
186
+ style.setdefault('fontSize', '18px')
187
  elif element.name in ['p', 'span', 'a', 'li']:
188
+ style.setdefault('fontSize', '16px')
189
 
190
+ # Add layout-related styles
191
+ style.setdefault('position', 'relative')
192
+ style.setdefault('margin', '0')
193
+ style.setdefault('padding', '0')
194
+ style.setdefault('boxSizing', 'border-box')
195
+
196
+ # Add computed styles (simulated)
197
+ if element.name in ['div', 'section', 'article']:
198
+ style.setdefault('backgroundColor', 'transparent')
199
+
200
+ return style