import dash from dash import dcc, html, Input, Output, State import dash_bootstrap_components as dbc from dash.exceptions import PreventUpdate import google.generativeai as genai from github import Github import gitlab import requests import tempfile import docx import os import logging import threading from huggingface_hub import HfApi from flask import send_file # Configure logging logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') logger = logging.getLogger(__name__) # Initialize Dash app app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP]) server = app.server # Expose the Flask server # Hugging Face API setup hf_api = HfApi() # Get Hugging Face variables GITHUB_TOKEN = os.environ.get('GITHUB_TOKEN') GEMINI_API_KEY = os.environ.get('GEMINI_API_KEY') # ... (rest of the functions remain unchanged) # App layout app.layout = dbc.Container([ dbc.Navbar( dbc.Container([ html.A( dbc.Row([ dbc.Col(html.Img(src="/assets/logo.png", height="30px")), dbc.Col(dbc.NavbarBrand("Automated Guide Generator", className="ms-2")), ], align="center", className="g-0", ), href="/", style={"textDecoration": "none"}, ) ]), color="primary", dark=True, ), dbc.Row([ dbc.Col([ html.H1("Automated Guide Generator", className="text-center my-4"), html.P("Generate a user guide or administration guide based on the UI-related code in a Git repository using Gemini AI. Select a Git provider, enter repository details, choose the guide type, and let AI create a comprehensive guide.", className="text-center mb-4"), dbc.Card([ dbc.CardBody([ dbc.Form([ dbc.Select( id="git-provider", options=[ {"label": "GitHub", "value": "GitHub"}, {"label": "GitLab", "value": "GitLab"}, {"label": "Gitea", "value": "Gitea"} ], placeholder="Select Git Provider", ), dbc.Input(id="repo-url", type="text", placeholder="Repository URL (owner/repo)"), dbc.RadioItems( id="guide-type", options=[ {"label": "User Guide", "value": "User Guide"}, {"label": "Administration Guide", "value": "Administration Guide"} ], inline=True, ), dbc.Input(id="exclude-folders", type="text", placeholder="Exclude Folders (comma-separated)"), dbc.Button("Generate Guide", id="generate-button", color="primary", className="mt-3"), ]) ]) ], className="mb-4"), dbc.Spinner( dbc.Card([ dbc.CardBody([ html.H4("Generated Guide", className="card-title"), html.Div([ dbc.Button("Download DOCX", id="download-docx", color="secondary", className="me-2"), dbc.Button("Download Markdown", id="download-md", color="secondary"), ], className="mt-3"), dcc.Download(id="download-docx-file"), dcc.Download(id="download-md-file"), ]) ], className="mt-4"), color="primary", ), ], width=6), dbc.Col([ dbc.Card([ dbc.CardBody([ html.H4("Preview", className="card-title"), html.Div(id="generated-guide", style={"whiteSpace": "pre-wrap", "height": "400px", "overflowY": "auto"}), ]) ], className="mt-4"), ], width=6), ]) ], fluid=True) @app.callback( [Output("generated-guide", "children"), Output("download-docx", "n_clicks"), Output("download-md", "n_clicks")], [Input("generate-button", "n_clicks")], [State("git-provider", "value"), State("repo-url", "value"), State("guide-type", "value"), State("exclude-folders", "value")] ) def update_output(n_clicks, git_provider, repo_url, guide_type, exclude_folders): if n_clicks is None: raise PreventUpdate def generate_guide_thread(): nonlocal guide_text, docx_path, md_path guide_text, docx_path, md_path = generate_guide(git_provider, repo_url, guide_type, exclude_folders) guide_text, docx_path, md_path = None, None, None thread = threading.Thread(target=generate_guide_thread) thread.start() thread.join() return guide_text, 0, 0 # Reset n_clicks for download buttons @app.callback( Output("download-docx-file", "data"), Input("download-docx", "n_clicks"), prevent_initial_call=True, ) def download_docx(n_clicks): if n_clicks is None: raise PreventUpdate return dcc.send_file(docx_path, filename="generated_guide.docx") @app.callback( Output("download-md-file", "data"), Input("download-md", "n_clicks"), prevent_initial_call=True, ) def download_md(n_clicks): if n_clicks is None: raise PreventUpdate return dcc.send_file(md_path, filename="generated_guide.md") if __name__ == '__main__': print("Starting the Dash application...") app.run(debug=True, host='0.0.0.0', port=7860) print("Dash application has finished running.")