AkashKumarave commited on
Commit
5ad001d
·
verified ·
1 Parent(s): a8621bc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +45 -46
app.py CHANGED
@@ -4,50 +4,51 @@ import logging
4
  from fastapi import FastAPI, File, UploadFile
5
  from fastapi.middleware.cors import CORSMiddleware
6
 
7
- logging.basicConfig(level=logging.INFO)
8
- logger = logging.getLogger(__name__)
9
-
10
  app = FastAPI()
11
 
12
  app.add_middleware(
13
  CORSMiddleware,
14
  allow_origins=["*"],
15
- allow_credentials=True,
16
  allow_methods=["*"],
17
  allow_headers=["*"],
18
  )
19
 
 
 
 
 
 
 
 
 
 
20
  def normalize_color(color):
21
- """Safely converts any PDF color format to Figma RGB format."""
 
 
 
22
  try:
23
- # If the PDF doesn't define a color for this element, return None
24
- # This tells Figma not to apply a fill or stroke
25
- if color is None:
26
- return None
27
-
28
- # Handle integer colors (e.g., 16711680 for Red)
29
  if isinstance(color, int):
30
  color = fitz.utils.getColor(color)
31
 
32
- # Ensure it's a list/tuple of numbers
33
  if not isinstance(color, (list, tuple)):
34
  return {"r": 0, "g": 0, "b": 0}
35
 
36
- # Convert to 0.0 - 1.0 range based on component count
37
- if len(color) == 1: # Grayscale
38
- val = float(color[0])
39
- return {"r": val, "g": val, "b": val}
40
- elif len(color) >= 3: # RGB or CMYK (taking first 3)
41
- return {"r": float(color[0]), "g": float(color[1]), "b": float(color[2])}
42
-
43
- return {"r": 0, "g": 0, "b": 0}
44
- except Exception as e:
45
- logger.error(f"Color error: {e}")
 
46
  return {"r": 0, "g": 0, "b": 0}
47
-
48
- @app.get("/")
49
- async def root():
50
- return {"status": "PDF Converter is Online"}
51
 
52
  @app.post("/convert")
53
  async def convert_pdf(file: UploadFile = File(...)):
@@ -58,63 +59,61 @@ async def convert_pdf(file: UploadFile = File(...)):
58
 
59
  for page in doc:
60
  page_dict = {
61
- "width": float(page.rect.width),
62
- "height": float(page.rect.height),
63
  "elements": []
64
  }
65
 
66
- # 1. Text and Images
67
  raw_dict = page.get_text("dict")
68
- for block in raw_dict["blocks"]:
69
  if block.get("type") == 0: # TEXT
70
  for line in block.get("lines", []):
71
  for span in line.get("spans", []):
72
  page_dict["elements"].append({
73
  "type": "TEXT",
74
  "content": span.get("text", ""),
75
- "x": float(span["bbox"][0]),
76
- "y": float(span["bbox"][1]),
77
- "size": float(span.get("size", 12)),
78
  "color": normalize_color(span.get("color"))
79
  })
80
  elif block.get("type") == 1: # IMAGE
81
  page_dict["elements"].append({
82
  "type": "IMAGE",
83
  "bytes": base64.b64encode(block["image"]).decode("utf-8"),
84
- "x": float(block["bbox"][0]),
85
- "y": float(block["bbox"][1]),
86
- "width": float(block["bbox"][2] - block["bbox"][0]),
87
- "height": float(block["bbox"][3] - block["bbox"][1])
88
  })
89
 
90
  # 2. Vector Drawings
91
  for path in page.get_drawings():
92
- svg_path = ""
93
  for item in path.get("items", []):
94
  if item[0] == "l":
95
- svg_path += f"M {item[1].x} {item[1].y} L {item[2].x} {item[2].y} "
96
  elif item[0] == "c":
97
- svg_path += f"M {item[1].x} {item[1].y} C {item[2].x} {item[2].y} {item[3].x} {item[3].y} {item[4].x} {item[4].y} "
98
  elif item[0] == "re":
99
  r = item[1]
100
- svg_path += f"M {r.x0} {r.y0} L {r.x1} {r.y0} L {r.x1} {r.y1} L {r.x0} {r.y1} Z "
101
 
102
- if svg_path:
103
  page_dict["elements"].append({
104
  "type": "VECTOR",
105
- "path": svg_path.strip(),
106
  "fill": normalize_color(path.get("fill")),
107
  "stroke": normalize_color(path.get("color")),
108
- "strokeWeight": float(path.get("width", 1))
109
  })
110
 
111
  pages_data.append(page_dict)
112
 
113
  doc.close()
114
  return {"pages": pages_data}
115
-
116
  except Exception as e:
117
- logger.error(f"Global Error: {str(e)}")
118
  return {"error": str(e)}
119
 
120
  if __name__ == "__main__":
 
4
  from fastapi import FastAPI, File, UploadFile
5
  from fastapi.middleware.cors import CORSMiddleware
6
 
 
 
 
7
  app = FastAPI()
8
 
9
  app.add_middleware(
10
  CORSMiddleware,
11
  allow_origins=["*"],
 
12
  allow_methods=["*"],
13
  allow_headers=["*"],
14
  )
15
 
16
+ def safe_float(value, default=0.0):
17
+ """Guards against NoneType conversion errors."""
18
+ try:
19
+ if value is None:
20
+ return default
21
+ return float(value)
22
+ except (TypeError, ValueError):
23
+ return default
24
+
25
  def normalize_color(color):
26
+ """Safely converts PDF color components to Figma 0-1 RGB."""
27
+ if color is None:
28
+ return None # Signal to Figma that there is no fill/stroke
29
+
30
  try:
31
+ # If it's an integer, convert to RGB tuple first
 
 
 
 
 
32
  if isinstance(color, int):
33
  color = fitz.utils.getColor(color)
34
 
35
+ # Ensure we are working with a list or tuple
36
  if not isinstance(color, (list, tuple)):
37
  return {"r": 0, "g": 0, "b": 0}
38
 
39
+ # Normalize based on color space
40
+ if len(color) == 1: # Grayscale
41
+ c = safe_float(color[0])
42
+ return {"r": c, "g": c, "b": c}
43
+ elif len(color) >= 3: # RGB or CMYK
44
+ return {
45
+ "r": safe_float(color[0]),
46
+ "g": safe_float(color[1]),
47
+ "b": safe_float(color[2])
48
+ }
49
+ except Exception:
50
  return {"r": 0, "g": 0, "b": 0}
51
+ return None
 
 
 
52
 
53
  @app.post("/convert")
54
  async def convert_pdf(file: UploadFile = File(...)):
 
59
 
60
  for page in doc:
61
  page_dict = {
62
+ "width": safe_float(page.rect.width),
63
+ "height": safe_float(page.rect.height),
64
  "elements": []
65
  }
66
 
67
+ # 1. Text & Images
68
  raw_dict = page.get_text("dict")
69
+ for block in raw_dict.get("blocks", []):
70
  if block.get("type") == 0: # TEXT
71
  for line in block.get("lines", []):
72
  for span in line.get("spans", []):
73
  page_dict["elements"].append({
74
  "type": "TEXT",
75
  "content": span.get("text", ""),
76
+ "x": safe_float(span["bbox"][0]),
77
+ "y": safe_float(span["bbox"][1]),
78
+ "size": safe_float(span.get("size"), 12),
79
  "color": normalize_color(span.get("color"))
80
  })
81
  elif block.get("type") == 1: # IMAGE
82
  page_dict["elements"].append({
83
  "type": "IMAGE",
84
  "bytes": base64.b64encode(block["image"]).decode("utf-8"),
85
+ "x": safe_float(block["bbox"][0]),
86
+ "y": safe_float(block["bbox"][1]),
87
+ "width": safe_float(block["bbox"][2] - block["bbox"][0]),
88
+ "height": safe_float(block["bbox"][3] - block["bbox"][1])
89
  })
90
 
91
  # 2. Vector Drawings
92
  for path in page.get_drawings():
93
+ d_path = ""
94
  for item in path.get("items", []):
95
  if item[0] == "l":
96
+ d_path += f"M {item[1].x} {item[1].y} L {item[2].x} {item[2].y} "
97
  elif item[0] == "c":
98
+ d_path += f"M {item[1].x} {item[1].y} C {item[2].x} {item[2].y} {item[3].x} {item[3].y} {item[4].x} {item[4].y} "
99
  elif item[0] == "re":
100
  r = item[1]
101
+ d_path += f"M {r.x0} {r.y0} L {r.x1} {r.y0} L {r.x1} {r.y1} L {r.x0} {r.y1} Z "
102
 
103
+ if d_path:
104
  page_dict["elements"].append({
105
  "type": "VECTOR",
106
+ "path": d_path.strip(),
107
  "fill": normalize_color(path.get("fill")),
108
  "stroke": normalize_color(path.get("color")),
109
+ "strokeWeight": safe_float(path.get("width"), 1.0)
110
  })
111
 
112
  pages_data.append(page_dict)
113
 
114
  doc.close()
115
  return {"pages": pages_data}
 
116
  except Exception as e:
 
117
  return {"error": str(e)}
118
 
119
  if __name__ == "__main__":