Spaces:
Running
Running
Upload 3 files
Browse files- app.py +13 -60
- generate_mindmap.py +5 -23
- requirements.txt +0 -6
app.py
CHANGED
@@ -1,27 +1,15 @@
|
|
1 |
-
import os
|
2 |
import sys
|
3 |
-
from generate_markdown import load_llm_model, generate_markdown, sanitize_markdown
|
4 |
from generate_mindmap import generate_mindmap
|
5 |
import gradio as gr
|
6 |
import subprocess
|
7 |
|
8 |
-
def generate(
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
while unformatted_markdown:
|
16 |
-
if mindmap_markdown.startswith("#") and '-' in mindmap_markdown:
|
17 |
-
unformatted_markdown = False
|
18 |
-
mindmap_svg, mindmap_pdf = generate_mindmap(mindmap_markdown)
|
19 |
-
else:
|
20 |
-
unformatted_markdown = True
|
21 |
-
mindmap_markdown = sanitize_markdown(llm, mindmap_markdown)
|
22 |
-
|
23 |
-
print("Mindmap generated successfully")
|
24 |
-
return summary, mindmap_markdown, mindmap_svg, mindmap_svg, mindmap_pdf, mindmap_pdf
|
25 |
|
26 |
theme = gr.themes.Soft(
|
27 |
primary_hue="purple",
|
@@ -32,47 +20,15 @@ theme = gr.themes.Soft(
|
|
32 |
|
33 |
with gr.Blocks(theme=theme, title="Binary Biology") as app:
|
34 |
with gr.Row():
|
35 |
-
file = gr.File(file_count='single', label='Upload Research Paper PDF file', file_types=['.pdf'])
|
36 |
with gr.Column():
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
with gr.Row():
|
41 |
-
summary = gr.TextArea(label='Summary', lines=5, interactive=False, show_copy_button=True)
|
42 |
-
markdown_mindmap = gr.Textbox(label='Mindmap', lines=5, interactive=False, show_copy_button=True)
|
43 |
-
|
44 |
-
with gr.Row():
|
45 |
-
with gr.Column():
|
46 |
-
svg_mindmap = gr.File(label='Graphical SVG Mindmap', interactive=False)
|
47 |
-
download_svg_mindmap = gr.File(label='Download SVG Mindmap', interactive=False)
|
48 |
-
|
49 |
with gr.Column():
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
submit.click(
|
54 |
-
generate,
|
55 |
-
inputs=[file],
|
56 |
-
outputs=[summary, markdown_mindmap, svg_mindmap, download_svg_mindmap, pdf_mindmap, download_pdf_mindmap],
|
57 |
-
scroll_to_output=True,
|
58 |
-
show_progress='minimal',
|
59 |
-
queue=True,
|
60 |
-
)
|
61 |
-
|
62 |
-
clear.click(
|
63 |
-
lambda: (None, None, None, None, None, None),
|
64 |
-
inputs=[file],
|
65 |
-
outputs=[summary, markdown_mindmap, svg_mindmap, download_svg_mindmap, pdf_mindmap, download_pdf_mindmap]
|
66 |
-
)
|
67 |
|
68 |
if __name__ == "__main__":
|
69 |
-
try:
|
70 |
-
env = os.environ.copy()
|
71 |
-
env["CMAKE_ARGS"] = "-DGGML_BLAS=ON -DGGML_BLAS_VENDOR=OpenBLAS"
|
72 |
-
subprocess.run(["pip", "install", "llama-cpp-python"], env=env)
|
73 |
-
except Exception as e:
|
74 |
-
print(f"Failed to install llama-cpp-python: {e}")
|
75 |
-
|
76 |
try:
|
77 |
subprocess.run(['apt', 'install', '-y', 'graphviz'])
|
78 |
print("Graphviz installed successfully")
|
@@ -83,8 +39,5 @@ if __name__ == "__main__":
|
|
83 |
except:
|
84 |
print("Graphviz installation failed")
|
85 |
sys.exit(1)
|
86 |
-
|
87 |
print("Graphviz loaded successfully")
|
88 |
-
|
89 |
-
print("Model loaded successfully")
|
90 |
-
app.queue(default_concurrency_limit=1).launch(show_error=True)
|
|
|
|
|
1 |
import sys
|
|
|
2 |
from generate_mindmap import generate_mindmap
|
3 |
import gradio as gr
|
4 |
import subprocess
|
5 |
|
6 |
+
def generate(mindmap_markdown):
|
7 |
+
mindmap_svg, mindmap_pdf = generate_mindmap(mindmap_markdown)
|
8 |
+
with open(mindmap_svg, 'wb') as f:
|
9 |
+
svg_mindmap = f.read()
|
10 |
+
with open(mindmap_pdf, 'wb') as f:
|
11 |
+
pdf_mindmap = f.read
|
12 |
+
return svg_mindmap, pdf_mindmap
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
theme = gr.themes.Soft(
|
15 |
primary_hue="purple",
|
|
|
20 |
|
21 |
with gr.Blocks(theme=theme, title="Binary Biology") as app:
|
22 |
with gr.Row():
|
|
|
23 |
with gr.Column():
|
24 |
+
mindmap_markdown = gr.Textbox(label="Mindmap Markdown", placeholder="Enter the markdown for the mindmap", lines=10)
|
25 |
+
generate_mindmap = gr.Button(value="Generate Mindmap")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
with gr.Column():
|
27 |
+
svg_mindmap = gr.TextArea(label="SVG Mindmap", placeholder="The SVG representation of the mindmap", lines=10, readonly=True)
|
28 |
+
pdf_mindmap = gr.TextArea(label="PDF Mindmap", placeholder="The PDF representation of the mindmap", lines=10, readonly=True)
|
29 |
+
generate_mindmap.click(generate, inputs=[mindmap_markdown], outputs=[svg_mindmap, pdf_mindmap])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
|
31 |
if __name__ == "__main__":
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
try:
|
33 |
subprocess.run(['apt', 'install', '-y', 'graphviz'])
|
34 |
print("Graphviz installed successfully")
|
|
|
39 |
except:
|
40 |
print("Graphviz installation failed")
|
41 |
sys.exit(1)
|
|
|
42 |
print("Graphviz loaded successfully")
|
43 |
+
app.queue(default_concurrency_limit=25).launch(show_error=True)
|
|
|
|
generate_mindmap.py
CHANGED
@@ -30,64 +30,48 @@ generated_colors = set()
|
|
30 |
def generate_random_color():
|
31 |
"""Generate a random color that hasn't been generated before."""
|
32 |
while True:
|
33 |
-
# Generate a random color in hex format
|
34 |
color = "#{:02x}{:02x}{:02x}".format(random.randint(128, 255), random.randint(128, 255), random.randint(128, 255))
|
35 |
-
# If the color is not in the set, it's unique
|
36 |
if color not in generated_colors:
|
37 |
-
generated_colors.add(color)
|
38 |
-
return color
|
39 |
else:
|
40 |
-
continue
|
41 |
|
42 |
def brighten_color(color, factor=0.15):
|
43 |
"""Brighten the color by a certain factor (default 10%)"""
|
44 |
-
# Remove the '#' symbol
|
45 |
color = color.lstrip('#')
|
46 |
-
|
47 |
-
# Convert hex to RGB
|
48 |
r, g, b = [int(color[i:i+2], 16) for i in (0, 2, 4)]
|
49 |
-
|
50 |
-
# Increase each component by the factor, but clamp to 255
|
51 |
r = min(255, int(r * (1 + factor)))
|
52 |
g = min(255, int(g * (1 + factor)))
|
53 |
b = min(255, int(b * (1 + factor)))
|
54 |
-
|
55 |
-
# Convert back to hex
|
56 |
return "#{:02x}{:02x}{:02x}".format(r, g, b)
|
57 |
|
58 |
def add_nodes_to_graph(graph, node, parent_id=None, font_size=9, parent_color=None):
|
59 |
node_id = str(id(node))
|
60 |
title = node['title']
|
61 |
if parent_color is None:
|
62 |
-
node_color = "#ADD8E6"
|
63 |
-
border_color = "#000000"
|
64 |
parent_color = "#ADD8E6"
|
65 |
elif parent_color == "#ADD8E6":
|
66 |
node_color = generate_random_color()
|
67 |
border_color = "#808080"
|
68 |
parent_color = node_color
|
69 |
else:
|
70 |
-
# Child node and its descendants with the same random color
|
71 |
node_color = brighten_color(parent_color, factor=0.15)
|
72 |
border_color = "#808080"
|
73 |
-
# Check for markdown links
|
74 |
url_match = re.search(r'\[(.*?)\]\((.*?)\)', title)
|
75 |
if url_match:
|
76 |
prefix_text = title[:url_match.start()].strip()
|
77 |
display_text = url_match.group(1)
|
78 |
url = url_match.group(2)
|
79 |
-
|
80 |
label = f'{prefix_text} {display_text}'
|
81 |
graph.node(node_id, label=label, shape="box", style="rounded,filled", color=border_color, fontcolor="black", fillcolor=node_color, href=url, tooltip=title, fontsize=str(font_size))
|
82 |
else:
|
83 |
graph.node(node_id, title, shape="box", style="rounded,filled", color=border_color, fontcolor="black", fillcolor=node_color, tooltip=title, fontsize=str(font_size))
|
84 |
-
|
85 |
if parent_id:
|
86 |
graph.edge(parent_id, node_id)
|
87 |
-
|
88 |
-
# Recurse to children, passing down color for the child and its descendants
|
89 |
for child in node.get('children', []):
|
90 |
-
# Assign a random color to each child node (no inheritance from parent)
|
91 |
add_nodes_to_graph(graph, child, node_id, font_size=max(8, font_size - 1), parent_color=parent_color)
|
92 |
|
93 |
def generate_mindmap_pdf(svg_file):
|
@@ -105,9 +89,7 @@ def generate_mindmap_svg(md_text):
|
|
105 |
graph.attr('node', fontname="Arial", fontsize="9")
|
106 |
add_nodes_to_graph(graph, mindmap_dict)
|
107 |
svg_content = graph.pipe(format='svg').decode('utf-8')
|
108 |
-
# Replace %3 with the sanitized filename in the SVG content
|
109 |
svg_content = svg_content.replace("%3", root_title)
|
110 |
-
# Save the modified SVG content to a file
|
111 |
with open(output_filename, 'w') as f:
|
112 |
f.write(svg_content)
|
113 |
return output_filename
|
|
|
30 |
def generate_random_color():
|
31 |
"""Generate a random color that hasn't been generated before."""
|
32 |
while True:
|
|
|
33 |
color = "#{:02x}{:02x}{:02x}".format(random.randint(128, 255), random.randint(128, 255), random.randint(128, 255))
|
|
|
34 |
if color not in generated_colors:
|
35 |
+
generated_colors.add(color)
|
36 |
+
return color
|
37 |
else:
|
38 |
+
continue
|
39 |
|
40 |
def brighten_color(color, factor=0.15):
|
41 |
"""Brighten the color by a certain factor (default 10%)"""
|
|
|
42 |
color = color.lstrip('#')
|
|
|
|
|
43 |
r, g, b = [int(color[i:i+2], 16) for i in (0, 2, 4)]
|
|
|
|
|
44 |
r = min(255, int(r * (1 + factor)))
|
45 |
g = min(255, int(g * (1 + factor)))
|
46 |
b = min(255, int(b * (1 + factor)))
|
|
|
|
|
47 |
return "#{:02x}{:02x}{:02x}".format(r, g, b)
|
48 |
|
49 |
def add_nodes_to_graph(graph, node, parent_id=None, font_size=9, parent_color=None):
|
50 |
node_id = str(id(node))
|
51 |
title = node['title']
|
52 |
if parent_color is None:
|
53 |
+
node_color = "#ADD8E6"
|
54 |
+
border_color = "#000000"
|
55 |
parent_color = "#ADD8E6"
|
56 |
elif parent_color == "#ADD8E6":
|
57 |
node_color = generate_random_color()
|
58 |
border_color = "#808080"
|
59 |
parent_color = node_color
|
60 |
else:
|
|
|
61 |
node_color = brighten_color(parent_color, factor=0.15)
|
62 |
border_color = "#808080"
|
|
|
63 |
url_match = re.search(r'\[(.*?)\]\((.*?)\)', title)
|
64 |
if url_match:
|
65 |
prefix_text = title[:url_match.start()].strip()
|
66 |
display_text = url_match.group(1)
|
67 |
url = url_match.group(2)
|
|
|
68 |
label = f'{prefix_text} {display_text}'
|
69 |
graph.node(node_id, label=label, shape="box", style="rounded,filled", color=border_color, fontcolor="black", fillcolor=node_color, href=url, tooltip=title, fontsize=str(font_size))
|
70 |
else:
|
71 |
graph.node(node_id, title, shape="box", style="rounded,filled", color=border_color, fontcolor="black", fillcolor=node_color, tooltip=title, fontsize=str(font_size))
|
|
|
72 |
if parent_id:
|
73 |
graph.edge(parent_id, node_id)
|
|
|
|
|
74 |
for child in node.get('children', []):
|
|
|
75 |
add_nodes_to_graph(graph, child, node_id, font_size=max(8, font_size - 1), parent_color=parent_color)
|
76 |
|
77 |
def generate_mindmap_pdf(svg_file):
|
|
|
89 |
graph.attr('node', fontname="Arial", fontsize="9")
|
90 |
add_nodes_to_graph(graph, mindmap_dict)
|
91 |
svg_content = graph.pipe(format='svg').decode('utf-8')
|
|
|
92 |
svg_content = svg_content.replace("%3", root_title)
|
|
|
93 |
with open(output_filename, 'w') as f:
|
94 |
f.write(svg_content)
|
95 |
return output_filename
|
requirements.txt
CHANGED
@@ -1,9 +1,3 @@
|
|
1 |
gradio==5.5.0
|
2 |
-
langchain==0.3.7
|
3 |
-
langchain-community==0.3.7
|
4 |
graphviz==0.20.3
|
5 |
-
llama-cpp-python==0.3.1
|
6 |
-
pypdf==5.1.0
|
7 |
-
llama-cpp-agent==0.2.35
|
8 |
-
huggingface-hub==0.26.2
|
9 |
cairosvg==2.7.1
|
|
|
1 |
gradio==5.5.0
|
|
|
|
|
2 |
graphviz==0.20.3
|
|
|
|
|
|
|
|
|
3 |
cairosvg==2.7.1
|