-
Notifications
You must be signed in to change notification settings - Fork 0
/
file_utils.py
105 lines (88 loc) · 3.5 KB
/
file_utils.py
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
import logging
import pathlib
from datetime import datetime
from langchain_core.messages import AIMessage
logger = logging.getLogger(__name__)
def read_files_recursively(path: pathlib.Path) -> list[str]:
"""
Reads all Python files without migrations in the given path and returns their content as a list of strings
with a comment containing the file path.
:param path: Path to the directory containing Python files.
:return: List of strings, each string containing the content of a Python file with a comment
containing the file path.
"""
all_files_content = []
for filepath in path.rglob("*.py"):
if "migrations" in str(filepath):
continue
try:
with open(filepath, "r", encoding="utf-8") as file_content:
content = file_content.read()
file_info = f"# {filepath}\n{content}\n"
all_files_content.append(file_info)
except Exception as e:
logger.error(f"Couldn't read file {filepath}: {e}")
return all_files_content
def _extract_filepath(commented_filepath: str) -> str:
"""
Extracts the filepath from the commented file path.
:param commented_filepath: Commented file path.
:return: File path.
"""
return (
commented_filepath.replace("# ../", "")
.replace("# /", "")
.replace("# ", "")
.strip()
)
def create_files(ai_message: AIMessage, path: pathlib.Path) -> str:
"""
Creates files from the content of the AI message.
:param ai_message: Received AI message.
:param path: Path to the root directory where the files should be created.
:return: The content of the AI message.
"""
path.mkdir(mode=0o777, parents=True, exist_ok=True)
path_file = None
if not isinstance(ai_message.content, str):
raise ValueError(
f"AI message content should be a string but it is not: {ai_message.content}"
)
for line in ai_message.content.split("\n"):
if line == "```" or line == "```python":
continue
if line.startswith("# "):
path_file = path / _extract_filepath(line)
path_file.parent.mkdir(parents=True, exist_ok=True)
with path_file.open(mode="a") as file:
file.write(
f"# Generated by AI, date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n"
)
continue
if path_file is None:
continue
with path_file.open(mode="a") as file:
file.write(line + "\n")
return ai_message.content
def get_django_files_contents(paths: list[pathlib.Path]) -> list[str]:
"""
Reads all Python files without migrations in the given paths and returns their content as a list of strings.
:param paths: List of paths to the directories containing Python files.
:return: List of strings, each string containing the content of a Python file with a comment containing the file path.
"""
all_files = []
for path in paths:
all_files.extend(read_files_recursively(path))
return all_files
def read_file(task_file_path: str) -> str | None:
"""
Reads the content of the file. If the file is not found, logs an error and returns None.
:param task_file_path: Path to the file.
"""
try:
with open(task_file_path, mode="r") as file:
description = file.read()
return description
except FileNotFoundError:
logger.error(f"File not found: {task_file_path}")
return None