Spaces:
Sleeping
Sleeping
import gradio as gr | |
import os | |
import json | |
import asyncio | |
import base64 | |
import matplotlib.pyplot as plt | |
import numpy as np | |
import pandas as pd | |
from handler import AudioLoop | |
import plotly.express as px | |
import plotly.graph_objects as go | |
from typing import Dict, List, Any, Optional, Tuple | |
# Utility functions for repository analysis and visualization | |
def analyze_repository_data(repo_data: Dict[str, Any]) -> Dict[str, Any]: | |
""" | |
Analyze repository data and prepare metrics for visualization | |
""" | |
results = { | |
"language_stats": {}, | |
"commit_history": [], | |
"contributor_stats": [], | |
"code_quality": {}, | |
"issue_stats": {} | |
} | |
# This would normally process real data from the Gemini response | |
# Placeholder data for demonstration | |
results["language_stats"] = { | |
"JavaScript": 45, | |
"Python": 30, | |
"HTML": 15, | |
"CSS": 10 | |
} | |
results["commit_history"] = [ | |
{"date": "2023-01", "commits": 12}, | |
{"date": "2023-02", "commits": 18}, | |
{"date": "2023-03", "commits": 7}, | |
{"date": "2023-04", "commits": 15}, | |
{"date": "2023-05", "commits": 22} | |
] | |
results["contributor_stats"] = [ | |
{"name": "User1", "commits": 45, "additions": 2300, "deletions": 1200}, | |
{"name": "User2", "commits": 32, "additions": 1800, "deletions": 900}, | |
{"name": "User3", "commits": 27, "additions": 1500, "deletions": 700} | |
] | |
return results | |
def create_language_pie_chart(language_stats: Dict[str, float]) -> go.Figure: | |
""" | |
Create a pie chart for language distribution | |
""" | |
labels = list(language_stats.keys()) | |
values = list(language_stats.values()) | |
fig = go.Figure(data=[go.Pie( | |
labels=labels, | |
values=values, | |
hole=.3, | |
marker_colors=px.colors.sequential.Plasma | |
)]) | |
fig.update_layout( | |
title_text="Repository Language Distribution", | |
showlegend=True, | |
legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1) | |
) | |
return fig | |
def create_commit_history_chart(commit_history: List[Dict[str, Any]]) -> go.Figure: | |
""" | |
Create a line chart for commit history | |
""" | |
dates = [item["date"] for item in commit_history] | |
commits = [item["commits"] for item in commit_history] | |
fig = go.Figure() | |
fig.add_trace(go.Scatter( | |
x=dates, | |
y=commits, | |
mode='lines+markers', | |
name='Commits', | |
line=dict(color='rgba(75, 0, 130, 0.8)', width=3), | |
marker=dict(size=8, color='rgba(138, 43, 226, 1)') | |
)) | |
fig.update_layout( | |
title="Commit Activity Over Time", | |
xaxis_title="Month", | |
yaxis_title="Number of Commits", | |
template="plotly_dark", | |
plot_bgcolor='rgba(26, 32, 58, 0.3)', | |
paper_bgcolor='rgba(26, 32, 58, 0.3)', | |
font=dict(color='#e0e0e0') | |
) | |
return fig | |
def create_contributors_chart(contributor_stats: List[Dict[str, Any]]) -> go.Figure: | |
""" | |
Create a bar chart for contributor statistics | |
""" | |
names = [item["name"] for item in contributor_stats] | |
commits = [item["commits"] for item in contributor_stats] | |
fig = go.Figure() | |
fig.add_trace(go.Bar( | |
x=names, | |
y=commits, | |
marker_color='rgba(138, 43, 226, 0.7)', | |
marker_line_color='rgba(138, 43, 226, 1.0)', | |
marker_line_width=1.5, | |
opacity=0.8 | |
)) | |
fig.update_layout( | |
title="Top Contributors", | |
xaxis_title="Contributor", | |
yaxis_title="Number of Commits", | |
template="plotly_dark", | |
plot_bgcolor='rgba(26, 32, 58, 0.3)', | |
paper_bgcolor='rgba(26, 32, 58, 0.3)', | |
font=dict(color='#e0e0e0') | |
) | |
return fig | |
# Main Gradio application | |
class GradioRepoAnalysis: | |
def __init__(self): | |
self.audio_loop = None | |
self.current_repo = None | |
self.analysis_results = None | |
def init_audio_loop(self): | |
"""Initialize the AudioLoop from your handler module""" | |
if self.audio_loop is None: | |
self.audio_loop = AudioLoop() | |
# This would normally connect to Gemini API | |
# For demo purposes, we'll simulate this | |
async def process_query(self, repo_url: str, query: str) -> Tuple[str, go.Figure, go.Figure, go.Figure]: | |
""" | |
Process a user query about a repository and return analysis results | |
""" | |
# In a real implementation, this would send the query to Gemini | |
# and process the response | |
# For demo purposes, we'll simulate a response | |
if not repo_url.startswith("https://github.com/"): | |
return "Please enter a valid GitHub repository URL", None, None, None | |
if not query: | |
return "Please enter a query about the repository", None, None, None | |
# Simulate a delay for processing | |
await asyncio.sleep(2) | |
# For demo, we'll generate simulated repository data | |
repo_name = repo_url.split("/")[-1] | |
repo_owner = repo_url.split("/")[-2] | |
repo_data = { | |
"name": repo_name, | |
"owner": repo_owner, | |
"url": repo_url, | |
# Other simulated data would go here | |
} | |
# Analyze the repository data | |
self.analysis_results = analyze_repository_data(repo_data) | |
# Create the visualization charts | |
language_chart = create_language_pie_chart(self.analysis_results["language_stats"]) | |
commit_chart = create_commit_history_chart(self.analysis_results["commit_history"]) | |
contributor_chart = create_contributors_chart(self.analysis_results["contributor_stats"]) | |
# Generate a text response | |
response = f"Analysis of {repo_owner}/{repo_name}:\n\n" | |
response += f"This repository is primarily written in {max(self.analysis_results['language_stats'], key=self.analysis_results['language_stats'].get)}, " | |
response += f"with {sum(item['commits'] for item in self.analysis_results['commit_history'])} commits in the last 5 months. " | |
response += f"The most active contributor is {self.analysis_results['contributor_stats'][0]['name']} with {self.analysis_results['contributor_stats'][0]['commits']} commits." | |
return response, language_chart, commit_chart, contributor_chart | |
def build_interface(self): | |
""" | |
Build and launch the Gradio interface | |
""" | |
with gr.Blocks(theme=gr.themes.Monochrome()) as interface: | |
gr.Markdown("# GitHub Repository Analysis with G.E.N.I.E.") | |
gr.Markdown("Analyze GitHub repositories using natural language queries") | |
with gr.Row(): | |
with gr.Column(scale=3): | |
repo_url = gr.Textbox( | |
label="GitHub Repository URL", | |
placeholder="https://github.com/owner/repo", | |
info="Enter the URL of the GitHub repository you want to analyze" | |
) | |
query = gr.Textbox( | |
label="Your Query", | |
placeholder="What are the main languages used in this repo?", | |
info="Ask a question about the repository" | |
) | |
with gr.Row(): | |
submit_btn = gr.Button("Analyze Repository", variant="primary") | |
clear_btn = gr.Button("Clear", variant="secondary") | |
response = gr.Markdown(label="Analysis Results") | |
with gr.Column(scale=2): | |
with gr.Tab("Voice Chat"): | |
audio_input = gr.Audio(source="microphone", type="numpy", label="Voice Input") | |
audio_output = gr.Audio(label="G.E.N.I.E. Response") | |
with gr.Tabs(): | |
with gr.Tab("Language Distribution"): | |
language_chart = gr.Plot(label="Repository Language Distribution") | |
with gr.Tab("Commit History"): | |
commit_chart = gr.Plot(label="Commit Activity Over Time") | |
with gr.Tab("Contributors"): | |
contributor_chart = gr.Plot(label="Top Contributors") | |
# Set up event handlers | |
submit_btn.click( | |
fn=lambda repo, q: asyncio.run(self.process_query(repo, q)), | |
inputs=[repo_url, query], | |
outputs=[response, language_chart, commit_chart, contributor_chart] | |
) | |
clear_btn.click( | |
fn=lambda: ( | |
"", | |
"https://github.com/user/repo", | |
"What are the main languages used in this repo?", | |
None, None, None | |
), | |
inputs=None, | |
outputs=[response, repo_url, query, language_chart, commit_chart, contributor_chart] | |
) | |
return interface | |
# Initialize and launch the application | |
def main(): | |
app = GradioRepoAnalysis() | |
interface = app.build_interface() | |
interface.launch(share=True) | |
if __name__ == "__main__": | |
main() | |