JSenkCC commited on
Commit
7b1b6cd
·
verified ·
1 Parent(s): b0baba9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +57 -159
app.py CHANGED
@@ -11,9 +11,6 @@ import requests
11
  from fpdf import FPDF
12
  import markdown
13
  import tempfile
14
- import re
15
- import spacy
16
- from collections import defaultdict
17
 
18
 
19
  # Database setup
@@ -81,8 +78,8 @@ def main():
81
  project_view_page()
82
  elif st.session_state.page == "generate_documentation":
83
  generate_documentation_page()
84
- elif st.session_state.page == "saved_documentation":
85
- saved_documentation_page()
86
 
87
  def login_page():
88
  st.subheader("Please Log In or Register to Continue")
@@ -101,7 +98,7 @@ def login_page():
101
  st.session_state.page = "workspace"
102
  else:
103
  st.error("Invalid username or password. Please try again.")
104
-
105
  elif auth_mode == "Register":
106
  st.subheader("Register")
107
  username = st.text_input("Create Username", key="register_username")
@@ -208,6 +205,8 @@ def workspace_page():
208
  except Exception as e:
209
  st.error(f"Failed to clone repository: {e}")
210
 
 
 
211
 
212
  # Configure Gemini API
213
  gemini = os.getenv("GEMINI")
@@ -249,15 +248,14 @@ def generate_prompt(file_contents, functionality_description):
249
 
250
  for file_path, content in file_contents.items():
251
  prompt += f"File: {os.path.basename(file_path)}\n{content}\n\n"
252
-
253
  prompt += "For each relevant function, provide:\n"
254
  prompt += "1. Which file the function is found in.\n"
255
  prompt += "2. The function name.\n"
256
  prompt += "3. Dependencies on other functions or modules.\n"
257
 
258
- prompt += """
259
  Return your output in the following format providing no commentary:
260
-
261
  Project Summary:
262
  <A summary of the project>
263
  Functionality:
@@ -275,16 +273,16 @@ def identify_required_functions(project_path, functionality_description):
275
  """Identifies required functions for a specified functionality."""
276
  # Gather all file paths in the project directory
277
  file_paths = read_project_files(project_path)
278
-
279
  # Read file contents
280
  file_contents = read_files(file_paths)
281
-
282
  # Generate a refined prompt for Gemini
283
  prompt = generate_prompt(file_contents, functionality_description)
284
-
285
  # Call the Gemini model
286
  response = model.generate_content(prompt)
287
-
288
  # Process and return the response
289
  return response.text
290
 
@@ -339,9 +337,7 @@ def generate_detailed_documentation(file_contents, functionality_description):
339
  """
340
  prompt = f"""
341
  The following code files are provided. Analyze their contents and generate comprehensive documentation.
342
-
343
  Functionality description: '{functionality_description}'
344
-
345
  Tasks:
346
  1. Generate a project summary:
347
  '
@@ -375,7 +371,6 @@ def generate_detailed_documentation(file_contents, functionality_description):
375
  - Example Usage: <Example demonstrating usage>
376
  '
377
  Please return only the required documentation in the specified format.
378
-
379
  Code files:
380
  """
381
  for file_path, content in file_contents.items():
@@ -387,28 +382,28 @@ def generate_detailed_documentation(file_contents, functionality_description):
387
  def process_gemini_output(output):
388
  """
389
  Processes the raw output from Gemini to format it appropriately.
390
-
391
  - Removes ``` at the top and bottom of the output.
392
  - Removes all pairs of **.
393
  - Replaces ` used as a quote with '.
394
  - Replaces leading '*' with '-' for lists.
395
-
396
  Args:
397
  output (str): The raw Gemini output.
398
-
399
  Returns:
400
  str: The processed and cleaned output.
401
  """
402
  # Remove leading and trailing ```
403
  if output.startswith("```") and output.endswith("```"):
404
  output = output[3:-3].strip()
405
-
406
  # Remove all pairs of **
407
  output = output.replace("**", "")
408
-
409
  # Replace ` with '
410
  output = output.replace("`", "'")
411
-
412
  # Replace leading '*' with '-' for list items
413
  lines = output.splitlines()
414
  processed_lines = []
@@ -419,9 +414,9 @@ def process_gemini_output(output):
419
  processed_lines.append(line.replace("*", "-", 1))
420
  else:
421
  processed_lines.append(line)
422
-
423
  return "\n".join(processed_lines)
424
-
425
  def generate_documentation_page():
426
  # Sidebar with "Log Out" and "Back to Project" buttons
427
  st.sidebar.title(f"Project: {st.session_state.current_project}")
@@ -469,26 +464,6 @@ def generate_documentation_page():
469
  # Display the final documentation
470
  st.success("Documentation generated successfully!")
471
  st.text_area("Generated Documentation", documentation, height=600)
472
-
473
- #---------------------------------------------------------------------------
474
- # Example Gemini output for testing
475
- test_gemini_output = """
476
- Functionality Summary:
477
- Authenticate the user by verifying their credentials. Once authenticated, fetch user-specific data such as preferences and usage history. Handle errors during both authentication and data retrieval.
478
-
479
- Project Summary:
480
- <Some project details>
481
-
482
- Functionality Flow:
483
- <Flow details>
484
- """
485
-
486
- # Streamlit testing
487
- if "page" not in st.session_state or st.session_state.page == "test_functionality":
488
- st.title("Test Functionality Extraction")
489
- display_functionality_analysis(test_gemini_output)
490
- #---------------------------------------------------------------------------
491
-
492
  except Exception as e:
493
  st.error(f"An error occurred: {e}")
494
  else:
@@ -496,8 +471,6 @@ def generate_documentation_page():
496
  else:
497
  st.error("Please enter the functionality to analyze.")
498
 
499
-
500
-
501
  # Add export/download buttons if documentation is available
502
  if "generated_documentation" in st.session_state and st.session_state.generated_documentation:
503
  documentation = st.session_state.generated_documentation
@@ -588,7 +561,6 @@ def generate_pdf(documentation, pdf_path):
588
  def generate_markdown_file(documentation, output_path):
589
  """
590
  Generates a markdown file from the documentation with structured formatting.
591
-
592
  Args:
593
  documentation (str): The documentation content to format and save.
594
  output_path (str): Path to save the generated markdown file.
@@ -610,121 +582,47 @@ def generate_markdown_file(documentation, output_path):
610
  with open(output_path, "w") as f:
611
  f.write("\n".join(formatted_lines))
612
 
613
- #---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
614
-
615
- # Load the NLP model (use the small model for speed)
616
- nlp = spacy.load("en_core_web_sm")
617
-
618
- def extract_functionality_and_relationships(gemini_output):
619
- """
620
- Extracts functionality descriptions and sub-functionality relationships from Gemini output.
621
- Args:
622
- gemini_output (str): The raw output from Gemini.
623
- Returns:
624
- dict: A dictionary with functionality and its relationships.
625
- """
626
- functionality_summary = None
627
- relationships = defaultdict(list)
628
-
629
- # Extract the 'Functionality Summary' section
630
- functionality_match = re.search(r"Functionality Summary:\n(.*?)\n\n", gemini_output, re.DOTALL)
631
- if functionality_match:
632
- functionality_summary = functionality_match.group(1).strip()
633
-
634
- # Parse the functionality summary with NLP
635
- if functionality_summary:
636
- doc = nlp(functionality_summary)
637
-
638
- # Extract relationships between sub-functionalities
639
- for sentence in doc.sents:
640
- sub_functionalities = []
641
- for token in sentence:
642
- # Capture sub-functionalities using noun chunks or proper nouns
643
- if token.dep_ in {"nsubj", "dobj", "pobj"} or token.ent_type_ in {"ORG", "PRODUCT"}:
644
- sub_functionalities.append(token.text)
645
- if len(sub_functionalities) > 1:
646
- # Create relationships between identified sub-functionalities
647
- main_functionality = sub_functionalities[0]
648
- for related in sub_functionalities[1:]:
649
- relationships[main_functionality].append(related)
650
-
651
- return functionality_summary, dict(relationships)
652
-
653
-
654
- def display_functionality_analysis(gemini_output):
655
- """
656
- Extracts and displays functionality analysis for testing purposes.
657
- Args:
658
- gemini_output (str): The raw output from Gemini.
659
- """
660
- # Extract functionality and relationships
661
- functionality, relationships = extract_functionality_and_relationships(gemini_output)
662
-
663
- # Display extracted functionality
664
- st.subheader("Extracted Functionality Summary")
665
- if functionality:
666
- st.text_area("Functionality Summary", functionality, height=200)
667
- else:
668
- st.error("No functionality summary found in the Gemini output.")
669
-
670
- # Display extracted relationships
671
- st.subheader("Extracted Relationships")
672
- if relationships:
673
- for main, related in relationships.items():
674
- st.write(f"**{main}** is related to: {', '.join(related)}")
675
- else:
676
- st.info("No relationships between sub-functionalities identified.")
677
-
678
-
679
-
680
 
681
 
682
  #------------------------------------------------------------------------------------------------------------------------------------------------------------------------
683
- def saved_documentation_page():
684
- # Sidebar with "Back to Project" and "Log Out" buttons
685
- st.sidebar.title(f"Project: {st.session_state.current_project}")
686
- if st.sidebar.button("Back to Project"):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
687
  st.session_state.page = "project_view"
688
  st.rerun()
689
- if st.sidebar.button("Log Out"):
690
- st.session_state.authenticated = False
691
- st.session_state.username = None
692
- st.session_state.page = "login"
693
- st.rerun()
694
-
695
- st.subheader(f"Saved Documentation for {st.session_state.current_project}")
696
- st.write("Below is a list of saved documentation for this project. Click to download.")
697
-
698
- # Define paths for generated files
699
- user_folder = os.path.join("user_projects", st.session_state.username)
700
- pdf_path = os.path.join(user_folder, f"{st.session_state.current_project}_Documentation.pdf")
701
- markdown_path = os.path.join(user_folder, f"{st.session_state.current_project}_Documentation.md")
702
-
703
- # Check if files exist
704
- pdf_exists = os.path.exists(pdf_path)
705
- markdown_exists = os.path.exists(markdown_path)
706
-
707
- # Display available documentation
708
- if not pdf_exists and not markdown_exists:
709
- st.info("No documentation has been generated yet. Please go to the 'Generate Documentation' page.")
710
- else:
711
- if pdf_exists:
712
- with open(pdf_path, "rb") as pdf_file:
713
- st.download_button(
714
- label="Download PDF Documentation",
715
- data=pdf_file.read(),
716
- file_name=f"{st.session_state.current_project}_Documentation.pdf",
717
- mime="application/pdf",
718
- )
719
-
720
- if markdown_exists:
721
- with open(markdown_path, "rb") as markdown_file:
722
- st.download_button(
723
- label="Download Markdown Documentation",
724
- data=markdown_file.read(),
725
- file_name=f"{st.session_state.current_project}_Documentation.md",
726
- mime="text/markdown",
727
- )
728
 
729
 
730
 
@@ -749,8 +647,8 @@ def project_view_page():
749
  st.session_state.page = "generate_documentation"
750
  st.rerun()
751
 
752
- if st.button("Saved Documentation"):
753
- st.session_state.page = "saved_documentation"
754
  st.rerun()
755
 
756
  # Toggle file structure display (if required)
 
11
  from fpdf import FPDF
12
  import markdown
13
  import tempfile
 
 
 
14
 
15
 
16
  # Database setup
 
78
  project_view_page()
79
  elif st.session_state.page == "generate_documentation":
80
  generate_documentation_page()
81
+ elif st.session_state.page == "view_documentation":
82
+ view_documentation_page()
83
 
84
  def login_page():
85
  st.subheader("Please Log In or Register to Continue")
 
98
  st.session_state.page = "workspace"
99
  else:
100
  st.error("Invalid username or password. Please try again.")
101
+
102
  elif auth_mode == "Register":
103
  st.subheader("Register")
104
  username = st.text_input("Create Username", key="register_username")
 
205
  except Exception as e:
206
  st.error(f"Failed to clone repository: {e}")
207
 
208
+ #------------------------------------------------------------------------------------------------------------------------------------------------------------------------
209
+
210
 
211
  # Configure Gemini API
212
  gemini = os.getenv("GEMINI")
 
248
 
249
  for file_path, content in file_contents.items():
250
  prompt += f"File: {os.path.basename(file_path)}\n{content}\n\n"
251
+
252
  prompt += "For each relevant function, provide:\n"
253
  prompt += "1. Which file the function is found in.\n"
254
  prompt += "2. The function name.\n"
255
  prompt += "3. Dependencies on other functions or modules.\n"
256
 
257
+ prompt += """
258
  Return your output in the following format providing no commentary:
 
259
  Project Summary:
260
  <A summary of the project>
261
  Functionality:
 
273
  """Identifies required functions for a specified functionality."""
274
  # Gather all file paths in the project directory
275
  file_paths = read_project_files(project_path)
276
+
277
  # Read file contents
278
  file_contents = read_files(file_paths)
279
+
280
  # Generate a refined prompt for Gemini
281
  prompt = generate_prompt(file_contents, functionality_description)
282
+
283
  # Call the Gemini model
284
  response = model.generate_content(prompt)
285
+
286
  # Process and return the response
287
  return response.text
288
 
 
337
  """
338
  prompt = f"""
339
  The following code files are provided. Analyze their contents and generate comprehensive documentation.
 
340
  Functionality description: '{functionality_description}'
 
341
  Tasks:
342
  1. Generate a project summary:
343
  '
 
371
  - Example Usage: <Example demonstrating usage>
372
  '
373
  Please return only the required documentation in the specified format.
 
374
  Code files:
375
  """
376
  for file_path, content in file_contents.items():
 
382
  def process_gemini_output(output):
383
  """
384
  Processes the raw output from Gemini to format it appropriately.
385
+
386
  - Removes ``` at the top and bottom of the output.
387
  - Removes all pairs of **.
388
  - Replaces ` used as a quote with '.
389
  - Replaces leading '*' with '-' for lists.
390
+
391
  Args:
392
  output (str): The raw Gemini output.
393
+
394
  Returns:
395
  str: The processed and cleaned output.
396
  """
397
  # Remove leading and trailing ```
398
  if output.startswith("```") and output.endswith("```"):
399
  output = output[3:-3].strip()
400
+
401
  # Remove all pairs of **
402
  output = output.replace("**", "")
403
+
404
  # Replace ` with '
405
  output = output.replace("`", "'")
406
+
407
  # Replace leading '*' with '-' for list items
408
  lines = output.splitlines()
409
  processed_lines = []
 
414
  processed_lines.append(line.replace("*", "-", 1))
415
  else:
416
  processed_lines.append(line)
417
+
418
  return "\n".join(processed_lines)
419
+
420
  def generate_documentation_page():
421
  # Sidebar with "Log Out" and "Back to Project" buttons
422
  st.sidebar.title(f"Project: {st.session_state.current_project}")
 
464
  # Display the final documentation
465
  st.success("Documentation generated successfully!")
466
  st.text_area("Generated Documentation", documentation, height=600)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
467
  except Exception as e:
468
  st.error(f"An error occurred: {e}")
469
  else:
 
471
  else:
472
  st.error("Please enter the functionality to analyze.")
473
 
 
 
474
  # Add export/download buttons if documentation is available
475
  if "generated_documentation" in st.session_state and st.session_state.generated_documentation:
476
  documentation = st.session_state.generated_documentation
 
561
  def generate_markdown_file(documentation, output_path):
562
  """
563
  Generates a markdown file from the documentation with structured formatting.
 
564
  Args:
565
  documentation (str): The documentation content to format and save.
566
  output_path (str): Path to save the generated markdown file.
 
582
  with open(output_path, "w") as f:
583
  f.write("\n".join(formatted_lines))
584
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
585
 
586
 
587
  #------------------------------------------------------------------------------------------------------------------------------------------------------------------------
588
+ def view_documentation_page():
589
+ st.subheader(f"View Documentation for {st.session_state.current_project}")
590
+ st.write("This page displays the generated documentation for the selected project.")
591
+
592
+ # Check if files are available in session state
593
+ pdf_path = st.session_state.get("pdf_file_path")
594
+ markdown_path = st.session_state.get("markdown_file_path")
595
+
596
+ # Display PDF file if it exists
597
+ if pdf_path and os.path.exists(pdf_path):
598
+ st.write("### PDF Documentation")
599
+ with open(pdf_path, "rb") as pdf_file:
600
+ pdf_data = pdf_file.read()
601
+ st.download_button(
602
+ label="Download PDF",
603
+ data=pdf_data,
604
+ file_name=os.path.basename(pdf_path),
605
+ mime="application/pdf",
606
+ )
607
+ st.write("View PDF Documentation below:")
608
+ st.pdf_viewer(pdf_path)
609
+
610
+ # Display Markdown file if it exists
611
+ if markdown_path and os.path.exists(markdown_path):
612
+ st.write("### Markdown Documentation")
613
+ with open(markdown_path, "r") as md_file:
614
+ markdown_content = md_file.read()
615
+ st.download_button(
616
+ label="Download Markdown",
617
+ data=markdown_content,
618
+ file_name=os.path.basename(markdown_path),
619
+ mime="text/markdown",
620
+ )
621
+ st.markdown(f"```\n{markdown_content}\n```", unsafe_allow_html=True)
622
+
623
+ if st.button("Back to Project"):
624
  st.session_state.page = "project_view"
625
  st.rerun()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
626
 
627
 
628
 
 
647
  st.session_state.page = "generate_documentation"
648
  st.rerun()
649
 
650
+ if st.button("View Documentation"):
651
+ st.session_state.page = "view_documentation"
652
  st.rerun()
653
 
654
  # Toggle file structure display (if required)