HALU-HAL commited on
Commit
097e928
·
1 Parent(s): 8a0f16c

[refactor] アプリケーションのリファクタリング

Browse files

## 変更内容

- `app.py`をリファクタリングし、以下のモジュールに分割しました:
- `modules/git_operations.py`: Gitリポジトリのクローン操作を行う関数を定義
- `modules/file_operations.py`: ファイルツリーの取得とファイルの処理を行う関数を定義
- `modules/markdown_operations.py`: マークダウンコンテンツの作成とファイルの保存を行う関数を定義

- `app.py`から分割したモジュールをインポートするように変更しました。

- `app.py`内の関数呼び出しを適切なモジュールの関数に置き換えました。

## 理由

- コードの可読性と保守性を向上させるため、機能ごとにモジュールに分割しました。

- 分割されたモジュールにより、各機能の責務が明確になり、将来の変更や拡張が容易になります。

- モジュール化により、コードの重複を減らし、再利用性を高めることができます。

## 影響範囲

- `app.py`の構造が変更されましたが、アプリケーションの動作には影響ありません。

- 新しいモジュールが追加されましたが、既存の機能は維持されています。

## テスト

- アプリケーションを実行し、リポジトリのクローン、ファイルツリーの表示、マークダウンコンテンツの生成が正常に動作することを確認します。

- さまざまなリポジトリとIgnoreパターンでアプリケーションをテストし、期待される結果が得られることを確認します。

README.md CHANGED
@@ -4,7 +4,7 @@ emoji: 📚
4
  colorFrom: purple
5
  colorTo: blue
6
  sdk: docker
7
- sdk_version: 1.33.0
8
  app_file: app.py
9
  pinned: false
10
  license: mit
 
4
  colorFrom: purple
5
  colorTo: blue
6
  sdk: docker
7
+ app_port: 8501
8
  app_file: app.py
9
  pinned: false
10
  license: mit
app.py CHANGED
@@ -1,10 +1,10 @@
 
1
  import os
2
  import streamlit as st
3
- import fnmatch
4
- import shutil
5
- import time
6
- import json
7
  import base64
 
 
 
8
 
9
  # .gitignoreのパターンを読み込む
10
  ignore_patterns = []
@@ -19,87 +19,26 @@ if os.path.exists(".CodeLumiaignore"):
19
  if os.path.exists("docs/page_front.md"):
20
  with open("docs/page_front.md", "r", encoding="utf-8") as f:
21
  page_front_content = f.read()
22
-
23
  st.markdown(page_front_content, unsafe_allow_html=True)
24
 
 
25
  # リポジトリのURLを入力するテキストボックス
26
  repo_url = st.text_input("リポジトリのURL:")
 
27
 
28
  # .gitignoreのパターンを編集するサイドバー
29
  st.sidebar.title(".gitignore Patterns")
30
  ignore_patterns = st.sidebar.text_area("Enter patterns (one per line):", value="\n".join(ignore_patterns), height=600).split("\n")
31
 
32
  if repo_url:
33
- # tmpフォルダを削除
34
- if os.path.exists("tmp"):
35
- shutil.rmtree("tmp")
36
-
37
- # tmpフォルダを作成
38
- os.makedirs("tmp")
39
-
40
- # リポジトリのクローン
41
  repo_name = repo_url.split("/")[-1].split(".")[0]
42
- repo_path = f"tmp/{repo_name}"
43
- if os.path.exists(repo_path):
44
- shutil.rmtree(repo_path)
45
- os.system(f"git clone {repo_url} {repo_path}")
46
-
47
- # 一時的な遅延を追加
48
- time.sleep(1)
49
-
50
- # リポジトリのファイルツリーを取得
51
- file_tree = ""
52
- for root, dirs, files in os.walk(repo_path):
53
- # .gitignoreに一致するディレクトリを無視
54
- dirs[:] = [d for d in dirs if not any(fnmatch.fnmatch(d, pattern) for pattern in ignore_patterns)]
55
-
56
- level = root.replace(repo_path, "").count(os.sep)
57
- indent = " " * 4 * (level)
58
- file_tree += f"{indent}{os.path.basename(root)}/\n"
59
- subindent = " " * 4 * (level + 1)
60
- for f in files:
61
- # .gitignoreに一致するファイルを無視
62
- if not any(fnmatch.fnmatch(f, pattern) for pattern in ignore_patterns):
63
- file_tree += f"{subindent}{f}\n"
64
-
65
- # マークダウンファイルを結合
66
- markdown_content = f"# << {repo_name}>> \n## {repo_name} File Tree\n\n```\n{file_tree}\n```\n\n"
67
-
68
- # 拡張子と言語のマッピングを読み込む
69
- with open("docs/language_map.json", "r") as f:
70
- language_map = json.load(f)
71
 
72
- for root, dirs, files in os.walk(repo_path):
73
- # .gitignoreに一致するディレクトリを無視
74
- dirs[:] = [d for d in dirs if not any(fnmatch.fnmatch(d, pattern) for pattern in ignore_patterns)]
75
- for file in files:
76
- # .gitignoreに一致するファイルを無視
77
- if not any(fnmatch.fnmatch(file, pattern) for pattern in ignore_patterns):
78
- file_path = os.path.join(root, file)
79
- _, file_extension = os.path.splitext(file)
80
- language = language_map.get(file_extension, "")
81
- with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
82
- content = f.read()
83
- # コードブロック内のコードブロックの範囲の全行の先頭に2つのスペースを入れる
84
- lines = content.split("\n")
85
- modified_lines = []
86
- inside_code_block = False
87
- for line in lines:
88
- if line.startswith("```"):
89
- inside_code_block = not inside_code_block
90
- modified_lines.append("\t" + line)
91
- else:
92
- if inside_code_block:
93
- modified_lines.append("\t" + line)
94
- else:
95
- modified_lines.append(line)
96
- content = "\n".join(modified_lines)
97
- # コードブロックの中のバッククォートをエスケープ
98
- markdown_content += f"## {file_path.replace(f'{repo_path}/', '')}\n\n```{language}\n{content}\n```\n\n"
99
 
100
  # マークダウンファイルを保存
101
- with open(f"{repo_name}.md", "w", encoding="utf-8") as f:
102
- f.write(markdown_content)
103
 
104
  # Streamlitアプリケーションの構築
105
  st.markdown(markdown_content, unsafe_allow_html=True)
 
1
+ # main.py
2
  import os
3
  import streamlit as st
 
 
 
 
4
  import base64
5
+ from modules.git_operations import clone_repository
6
+ from modules.file_operations import get_file_tree, process_files
7
+ from modules.markdown_operations import create_markdown_content, save_markdown_file
8
 
9
  # .gitignoreのパターンを読み込む
10
  ignore_patterns = []
 
19
  if os.path.exists("docs/page_front.md"):
20
  with open("docs/page_front.md", "r", encoding="utf-8") as f:
21
  page_front_content = f.read()
 
22
  st.markdown(page_front_content, unsafe_allow_html=True)
23
 
24
+ st.markdown("---")
25
  # リポジトリのURLを入力するテキストボックス
26
  repo_url = st.text_input("リポジトリのURL:")
27
+ st.markdown("---")
28
 
29
  # .gitignoreのパターンを編集するサイドバー
30
  st.sidebar.title(".gitignore Patterns")
31
  ignore_patterns = st.sidebar.text_area("Enter patterns (one per line):", value="\n".join(ignore_patterns), height=600).split("\n")
32
 
33
  if repo_url:
 
 
 
 
 
 
 
 
34
  repo_name = repo_url.split("/")[-1].split(".")[0]
35
+ repo_path = clone_repository(repo_url, repo_name)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
+ file_tree = get_file_tree(repo_path, ignore_patterns)
38
+ markdown_content = create_markdown_content(repo_name, file_tree, repo_path, ignore_patterns)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
  # マークダウンファイルを保存
41
+ save_markdown_file(repo_name, markdown_content)
 
42
 
43
  # Streamlitアプリケーションの構築
44
  st.markdown(markdown_content, unsafe_allow_html=True)
modules/file_operations.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import fnmatch
3
+
4
+ def get_file_tree(repo_path, ignore_patterns):
5
+ file_tree = ""
6
+ for root, dirs, files in os.walk(repo_path):
7
+ # .gitignoreに一致するディレクトリを無視
8
+ dirs[:] = [d for d in dirs if not any(fnmatch.fnmatch(d, pattern) for pattern in ignore_patterns)]
9
+
10
+ level = root.replace(repo_path, "").count(os.sep)
11
+ indent = " " * 4 * (level)
12
+ file_tree += f"{indent}{os.path.basename(root)}/\n"
13
+ subindent = " " * 4 * (level + 1)
14
+ for f in files:
15
+ # .gitignoreに一致するファイルを無視
16
+ if not any(fnmatch.fnmatch(f, pattern) for pattern in ignore_patterns):
17
+ file_tree += f"{subindent}{f}\n"
18
+ return file_tree
19
+
20
+ def process_files(repo_path, ignore_patterns):
21
+ file_contents = []
22
+ for root, dirs, files in os.walk(repo_path):
23
+ # .gitignoreに一致するディレクトリを無視
24
+ dirs[:] = [d for d in dirs if not any(fnmatch.fnmatch(d, pattern) for pattern in ignore_patterns)]
25
+ for file in files:
26
+ # .gitignoreに一致するファイルを無視
27
+ if not any(fnmatch.fnmatch(file, pattern) for pattern in ignore_patterns):
28
+ file_path = os.path.join(root, file)
29
+ with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
30
+ content = f.read()
31
+ file_contents.append((file_path.replace(f'{repo_path}/', ''), content))
32
+ return file_contents
modules/git_operations.py ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import shutil
3
+ import time
4
+
5
+ def clone_repository(repo_url, repo_name):
6
+ # tmpフォルダを削除
7
+ if os.path.exists("tmp"):
8
+ shutil.rmtree("tmp")
9
+
10
+ # tmpフォルダを作成
11
+ os.makedirs("tmp")
12
+
13
+ # リポジトリのクローン
14
+ repo_path = f"tmp/{repo_name}"
15
+ if os.path.exists(repo_path):
16
+ shutil.rmtree(repo_path)
17
+ os.system(f"git clone {repo_url} {repo_path}")
18
+
19
+ # 一時的な遅延を追加
20
+ time.sleep(1)
21
+
22
+ return repo_path
modules/markdown_operations.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ from modules.file_operations import get_file_tree, process_files
3
+ import os
4
+
5
+ def create_markdown_content(repo_name, file_tree, repo_path, ignore_patterns):
6
+ markdown_content = f"# << {repo_name}>> \n## {repo_name} File Tree\n\n```\n{file_tree}\n```\n\n"
7
+
8
+ # 拡張子と言語のマッピングを読み込む
9
+ with open("docs/language_map.json", "r") as f:
10
+ language_map = json.load(f)
11
+
12
+ file_contents = process_files(repo_path, ignore_patterns)
13
+ for file_path, content in file_contents:
14
+ _, file_extension = os.path.splitext(file_path)
15
+ language = language_map.get(file_extension, "")
16
+ # コードブロック内のコードブロックの範囲の全行の先頭に2つのスペースを入れる
17
+ lines = content.split("\n")
18
+ modified_lines = []
19
+ inside_code_block = False
20
+ for line in lines:
21
+ if line.startswith("```"):
22
+ inside_code_block = not inside_code_block
23
+ modified_lines.append("\t" + line)
24
+ else:
25
+ if inside_code_block:
26
+ modified_lines.append("\t" + line)
27
+ else:
28
+ modified_lines.append(line)
29
+ content = "\n".join(modified_lines)
30
+ # コードブロックの中のバッククォートをエスケープ
31
+ markdown_content += f"## {file_path}\n\n```{language}\n{content}\n```\n\n"
32
+
33
+ return markdown_content
34
+
35
+ def save_markdown_file(repo_name, markdown_content):
36
+ with open(f"{repo_name}.md", "w", encoding="utf-8") as f:
37
+ f.write(markdown_content)