Spaces:
Running
Running
File size: 3,755 Bytes
227e75d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
import streamlit as st
import tempfile
import git
from pathlib import Path
from datetime import datetime
import time
from core.file_scanner import FileScanner
from services.llm_service import LLMService
# ページ設定
st.set_page_config(
page_title="Repository Code Analysis",
page_icon="🔍",
layout="wide"
)
# カスタムCSS
st.markdown("""
<style>
.stAlert {
padding: 1rem;
margin: 1rem 0;
}
.css-1v0mbdj.ebxwdo61 {
width: 100%;
max-width: 800px;
}
</style>
""", unsafe_allow_html=True)
def clone_repository(repo_url: str) -> Path:
"""リポジトリをクローンして一時ディレクトリに保存"""
temp_dir = Path(tempfile.mkdtemp())
git.Repo.clone_from(repo_url, temp_dir)
return temp_dir
# セッション状態の初期化
if 'repo_content' not in st.session_state:
st.session_state.repo_content = None
if 'temp_dir' not in st.session_state:
st.session_state.temp_dir = None
if 'llm_service' not in st.session_state:
st.session_state.llm_service = None
# メインのUIレイアウト
st.title("🔍 リポジトリ解析・質問システム")
# OpenAI APIキーの設定
api_key = st.sidebar.text_input("OpenAI APIキー", type="password", key="api_key")
if api_key:
st.session_state.llm_service = LLMService(api_key)
# URLの入力
repo_url = st.text_input(
"GitHubリポジトリのURLを入力",
placeholder="https://github.com/username/repository.git"
)
# スキャン実行ボタン
if st.button("スキャン開始", disabled=not repo_url):
try:
with st.spinner('リポジトリをクローン中...'):
temp_dir = clone_repository(repo_url)
st.session_state.temp_dir = temp_dir
with st.spinner('ファイルをスキャン中...'):
scanner = FileScanner(temp_dir)
files_content = scanner.scan_files()
if st.session_state.llm_service:
st.session_state.repo_content = LLMService.format_code_content(files_content)
st.success(f"スキャン完了: {len(files_content)}個のファイルを検出")
except Exception as e:
st.error(f"エラーが発生しました: {str(e)}")
# スキャン完了後の質問セクション
if st.session_state.repo_content and st.session_state.llm_service:
st.divider()
st.subheader("💭 コードについて質問する")
query = st.text_area(
"質問を入力してください",
placeholder="例: このコードの主な機能は何ですか?"
)
if st.button("質問する", disabled=not query):
with st.spinner('回答を生成中...'):
response, error = st.session_state.llm_service.get_response(
st.session_state.repo_content,
query
)
if error:
st.error(error)
else:
st.markdown("### 回答:")
st.markdown(response)
# セッション終了時のクリーンアップ
if st.session_state.temp_dir and Path(st.session_state.temp_dir).exists():
try:
import shutil
shutil.rmtree(st.session_state.temp_dir)
except:
pass
# サイドバー情報
with st.sidebar:
st.subheader("📌 使い方")
st.markdown("""
1. OpenAI APIキーを入力
2. GitHubリポジトリのURLを入力
3. スキャンを実行
4. コードについて質問
""")
st.subheader("🔍 スキャン対象")
st.markdown("""
- Python (.py)
- JavaScript (.js)
- Java (.java)
- C/C++ (.c, .h, .cpp, .hpp)
- その他の主要なプログラミング言語
""") |