DeL-TaiseiOzaki's picture
Update app.py
5bdd26d verified
raw
history blame
4.36 kB
# app.py
import streamlit as st
from pathlib import Path
from core.file_scanner import FileScanner, FileInfo
# セッション状態を初期化
if 'scanned_files' not in st.session_state:
st.session_state.scanned_files = [] # List[FileInfo]
if 'selected_files' not in st.session_state:
st.session_state.selected_files = set() # {Path} 相対パス or 絶対パス
st.title("指定拡張子のみディレクトリスキャン & 選択ダウンロード")
# --- 1) ユーザー入力: スキャンしたいローカルディレクトリパス ---
dir_path_str = st.text_input("ローカルディレクトリパス", value=".")
# --- 2) ユーザー入力: スキャン対象拡張子選択 ---
st.subheader("スキャン対象拡張子")
available_exts = [".py", ".js", ".ts", ".md", ".txt", ".java", ".cpp"]
chosen_exts = []
for ext in available_exts:
if st.checkbox(ext, key=f"ext_{ext}", value=(ext in [".py", ".md"])):
chosen_exts.append(ext)
# --- 3) 「スキャン実行」ボタン ---
if st.button("スキャン開始"):
base_path = Path(dir_path_str).resolve()
if not base_path.is_dir():
st.error("有効なディレクトリを指定してください")
else:
scanner = FileScanner(base_path, set(chosen_exts))
found_files = scanner.scan_files()
st.session_state.scanned_files = found_files
st.session_state.selected_files = set() # スキャン毎に選択リセット
st.success(f"スキャン完了: {len(found_files)}個のファイル")
# --- 4) ファイルを表示するUI(ディレクトリ構造 or リスト) + 全選択 / 全解除 ---
if st.session_state.scanned_files:
# 全選択 / 全解除ボタン
col1, col2 = st.columns(2)
with col1:
if st.button("すべて選択"):
# すべてのファイルを選択
base_path = Path(dir_path_str).resolve()
# relative_to で相対パスを使うか、絶対パスを使うかは好みでOK
st.session_state.selected_files = {
f.path.relative_to(base_path) for f in st.session_state.scanned_files
}
with col2:
if st.button("すべて解除"):
st.session_state.selected_files = set()
st.write("### ファイル一覧 (指定拡張子のみ)")
base_path = Path(dir_path_str).resolve()
for file_info in st.session_state.scanned_files:
# 相対パスで扱う例
rel_path = file_info.path.relative_to(base_path)
checked = (rel_path in st.session_state.selected_files)
# チェックボックス + ファイル名表示
new_checked = st.checkbox(
f"{rel_path} ({file_info.formatted_size})",
value=checked,
key=str(rel_path) # keyは重複しないように文字列にしておく
)
# 選択状態を更新
if new_checked:
st.session_state.selected_files.add(rel_path)
else:
st.session_state.selected_files.discard(rel_path)
# --- 5) 選択ファイルをまとめてMarkdown化 & ダウンロード ---
def create_markdown_for_selected(files, selected_paths, base_dir: Path) -> str:
"""
選択されたファイルだけをMarkdownテキストとして返す
"""
output = []
for f in files:
rel_path = f.path.relative_to(base_dir)
if rel_path in selected_paths:
output.append(f"## {rel_path}")
output.append("------------")
if f.content is not None:
output.append(f.content)
else:
output.append("# Failed to read content")
output.append("") # 空行
return "\n".join(output)
if st.session_state.scanned_files:
st.write("### 選択ファイルをMarkdownダウンロード")
if st.button("選択ファイルをまとめてダウンロード"):
base_path = Path(dir_path_str).resolve()
markdown_text = create_markdown_for_selected(
st.session_state.scanned_files,
st.session_state.selected_files,
base_path
)
st.download_button(
label="ダウンロード",
data=markdown_text,
file_name="selected_files.md",
mime="text/markdown"
)