arif670 commited on
Commit
e33b0b5
·
verified ·
1 Parent(s): 6c68c73

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +23 -22
app.py CHANGED
@@ -23,7 +23,7 @@ def process_uploaded_file(file):
23
  return None
24
  return file
25
 
26
- # If file is a dict, expect the "data" key to contain the file content.
27
  if isinstance(file, dict):
28
  if "data" in file and file["data"]:
29
  temp_path = "/tmp/uploaded.csv"
@@ -48,16 +48,9 @@ def process_uploaded_file(file):
48
  return None
49
 
50
  # -------------------------
51
- # HTML Org Chart Generation
52
  # -------------------------
53
  def build_tree(df):
54
- """
55
- Build a tree structure from CSV data.
56
- Returns:
57
- - employees: dict mapping employee name to HTML-formatted label
58
- - children: dict mapping manager name to list of subordinate names.
59
- - roots: list of root node names.
60
- """
61
  employees = {}
62
  children = {}
63
  all_emps = set()
@@ -83,18 +76,25 @@ def build_tree(df):
83
  roots = [df.iloc[0]["Name"].strip()]
84
  return employees, children, roots
85
 
86
- def generate_node_html(node, employees, children):
87
- """
88
- Recursively generate HTML for a node and its children using nested <ul> tags.
89
- """
 
 
 
 
 
 
90
  label = employees.get(node, node)
91
  html = f"<li><div class='node'>{label}</div>"
92
  if node in children and children[node]:
93
  html += "<ul>"
94
  for child in children[node]:
95
- html += generate_node_html(child, employees, children)
96
  html += "</ul>"
97
  html += "</li>"
 
98
  return html
99
 
100
  def generate_org_chart_html(df, title):
@@ -116,7 +116,7 @@ def generate_org_chart_html(df, title):
116
  margin: 20px;
117
  }}
118
  .org-chart ul {{
119
- padding-top: 20px;
120
  position: relative;
121
  display: inline-block;
122
  }}
@@ -171,10 +171,10 @@ def generate_org_chart_html(df, title):
171
  return html_content
172
 
173
  # -------------------------
174
- # Main Function: Generate Chart & PDF
175
  # -------------------------
176
  def generate_chart(file, title):
177
- logging.info(f"generate_chart called with file: {file} and title: {title}")
178
  if not file:
179
  return None, "Please upload a CSV file."
180
  file_path = process_uploaded_file(file)
@@ -185,6 +185,7 @@ def generate_chart(file, title):
185
  return None, "Uploaded file is a directory. Please upload a valid CSV file."
186
  try:
187
  df = pd.read_csv(file_path)
 
188
  except Exception as e:
189
  logging.error(f"Error reading CSV: {e}")
190
  return None, f"Error reading CSV: {e}"
@@ -192,13 +193,14 @@ def generate_chart(file, title):
192
  if not expected_columns.issubset(set(df.columns)):
193
  return None, "CSV must contain Name, Role, and Reporting To columns."
194
 
195
- # Generate the HTML org chart.
196
  html_content = generate_org_chart_html(df, title)
197
 
198
  # Generate PDF using WeasyPrint.
199
  pdf_path = "/tmp/chart.pdf"
200
  try:
201
  HTML(string=html_content).write_pdf(pdf_path)
 
202
  except Exception as e:
203
  logging.error(f"Error generating PDF: {e}")
204
  dummy_pdf = "/tmp/no_pdf.pdf"
@@ -208,10 +210,12 @@ def generate_chart(file, title):
208
 
209
  # Convert PDF to PNG for preview using pdf2image.
210
  try:
 
211
  images = convert_from_path(pdf_path, dpi=150)
212
  if images and len(images) > 0:
213
  image_path = "/tmp/chart.png"
214
  images[0].save(image_path, 'PNG')
 
215
  else:
216
  image_path = ""
217
  except Exception as e:
@@ -221,7 +225,7 @@ def generate_chart(file, title):
221
  return image_path, pdf_path
222
 
223
  # -------------------------
224
- # Template Download Helper
225
  # -------------------------
226
  def download_template():
227
  template_path = "/tmp/template.csv"
@@ -247,17 +251,14 @@ with gr.Blocks() as demo:
247
  "Upload a CSV file (with columns: **Name, Role, Reporting To**) to generate an interactive organization chart. "
248
  "Use the button below to download a CSV template."
249
  )
250
-
251
  with gr.Row():
252
  template_button = gr.Button("Download CSV Template")
253
  file_input = gr.File(label="Upload CSV File")
254
  title_input = gr.Textbox(label="Enter PDF Title", placeholder="Company Org Chart")
255
  submit_button = gr.Button("Generate Chart")
256
-
257
  image_output = gr.Image(label="Generated Chart (PNG)")
258
  pdf_output = gr.File(label="Download PDF")
259
  template_output = gr.File(label="CSV Template")
260
-
261
  template_button.click(download_template, outputs=template_output)
262
  submit_button.click(generate_chart, inputs=[file_input, title_input], outputs=[image_output, pdf_output])
263
 
 
23
  return None
24
  return file
25
 
26
+ # If file is a dict, expect the "data" key to contain file content.
27
  if isinstance(file, dict):
28
  if "data" in file and file["data"]:
29
  temp_path = "/tmp/uploaded.csv"
 
48
  return None
49
 
50
  # -------------------------
51
+ # Build tree structure from CSV
52
  # -------------------------
53
  def build_tree(df):
 
 
 
 
 
 
 
54
  employees = {}
55
  children = {}
56
  all_emps = set()
 
76
  roots = [df.iloc[0]["Name"].strip()]
77
  return employees, children, roots
78
 
79
+ # -------------------------
80
+ # Recursive HTML generation with cycle detection
81
+ # -------------------------
82
+ def generate_node_html(node, employees, children, visited=None):
83
+ if visited is None:
84
+ visited = set()
85
+ if node in visited:
86
+ # Cycle detected; indicate with a note.
87
+ return f"<li><div class='node'>{employees.get(node, node)} (cycle)</div></li>"
88
+ visited.add(node)
89
  label = employees.get(node, node)
90
  html = f"<li><div class='node'>{label}</div>"
91
  if node in children and children[node]:
92
  html += "<ul>"
93
  for child in children[node]:
94
+ html += generate_node_html(child, employees, children, visited)
95
  html += "</ul>"
96
  html += "</li>"
97
+ visited.remove(node)
98
  return html
99
 
100
  def generate_org_chart_html(df, title):
 
116
  margin: 20px;
117
  }}
118
  .org-chart ul {{
119
+ padding-top: 20px;
120
  position: relative;
121
  display: inline-block;
122
  }}
 
171
  return html_content
172
 
173
  # -------------------------
174
+ # Main function: Generate Chart & PDF
175
  # -------------------------
176
  def generate_chart(file, title):
177
+ logging.info("Starting chart generation...")
178
  if not file:
179
  return None, "Please upload a CSV file."
180
  file_path = process_uploaded_file(file)
 
185
  return None, "Uploaded file is a directory. Please upload a valid CSV file."
186
  try:
187
  df = pd.read_csv(file_path)
188
+ logging.info(f"CSV read successfully with {df.shape[0]} rows.")
189
  except Exception as e:
190
  logging.error(f"Error reading CSV: {e}")
191
  return None, f"Error reading CSV: {e}"
 
193
  if not expected_columns.issubset(set(df.columns)):
194
  return None, "CSV must contain Name, Role, and Reporting To columns."
195
 
196
+ # Generate HTML org chart.
197
  html_content = generate_org_chart_html(df, title)
198
 
199
  # Generate PDF using WeasyPrint.
200
  pdf_path = "/tmp/chart.pdf"
201
  try:
202
  HTML(string=html_content).write_pdf(pdf_path)
203
+ logging.info("PDF generated successfully.")
204
  except Exception as e:
205
  logging.error(f"Error generating PDF: {e}")
206
  dummy_pdf = "/tmp/no_pdf.pdf"
 
210
 
211
  # Convert PDF to PNG for preview using pdf2image.
212
  try:
213
+ from pdf2image import convert_from_path
214
  images = convert_from_path(pdf_path, dpi=150)
215
  if images and len(images) > 0:
216
  image_path = "/tmp/chart.png"
217
  images[0].save(image_path, 'PNG')
218
+ logging.info("PDF converted to PNG successfully.")
219
  else:
220
  image_path = ""
221
  except Exception as e:
 
225
  return image_path, pdf_path
226
 
227
  # -------------------------
228
+ # Template download helper
229
  # -------------------------
230
  def download_template():
231
  template_path = "/tmp/template.csv"
 
251
  "Upload a CSV file (with columns: **Name, Role, Reporting To**) to generate an interactive organization chart. "
252
  "Use the button below to download a CSV template."
253
  )
 
254
  with gr.Row():
255
  template_button = gr.Button("Download CSV Template")
256
  file_input = gr.File(label="Upload CSV File")
257
  title_input = gr.Textbox(label="Enter PDF Title", placeholder="Company Org Chart")
258
  submit_button = gr.Button("Generate Chart")
 
259
  image_output = gr.Image(label="Generated Chart (PNG)")
260
  pdf_output = gr.File(label="Download PDF")
261
  template_output = gr.File(label="CSV Template")
 
262
  template_button.click(download_template, outputs=template_output)
263
  submit_button.click(generate_chart, inputs=[file_input, title_input], outputs=[image_output, pdf_output])
264