2023-03-23 10:12:57 +00:00
|
|
|
"""
|
|
|
|
read protocol:
|
|
|
|
|
|
|
|
<filepath>|<start line>-<end line>
|
|
|
|
"""
|
2023-04-03 12:40:58 +00:00
|
|
|
from pathlib import Path
|
2023-04-03 07:43:34 +00:00
|
|
|
from typing import List, Optional, Tuple
|
2023-03-26 06:27:51 +00:00
|
|
|
|
2023-04-03 12:40:58 +00:00
|
|
|
from env import settings
|
|
|
|
|
2023-04-07 02:11:24 +00:00
|
|
|
from .verify import verify
|
|
|
|
|
2023-03-26 06:27:51 +00:00
|
|
|
|
|
|
|
class Line:
|
|
|
|
def __init__(self, content: str, line_number: int, depth: int):
|
|
|
|
self.__content: str = content
|
|
|
|
self.__line_number: int = line_number
|
|
|
|
self.__depth: int = depth
|
|
|
|
self.__children: List[Line] = []
|
|
|
|
|
|
|
|
def get_content(self) -> str:
|
|
|
|
return self.__content
|
|
|
|
|
|
|
|
def get_depth(self) -> int:
|
|
|
|
return self.__depth
|
|
|
|
|
|
|
|
def append_child(self, child: "Line") -> None:
|
|
|
|
self.__children.append(child)
|
|
|
|
|
|
|
|
def find_by_lte_depth(self, depth: int) -> List["Line"]:
|
|
|
|
if self.__depth > depth:
|
|
|
|
return []
|
|
|
|
|
|
|
|
lines: List[Line] = [self]
|
|
|
|
for child in self.__children:
|
|
|
|
lines += child.find_by_lte_depth(depth)
|
|
|
|
return lines
|
|
|
|
|
|
|
|
def find_by_content(self, content: str) -> List["Line"]:
|
|
|
|
if content in self.__content:
|
|
|
|
return [self]
|
|
|
|
|
|
|
|
lines: List[Line] = []
|
|
|
|
for child in self.__children:
|
|
|
|
lines += child.find_by_content(content)
|
|
|
|
return lines
|
|
|
|
|
|
|
|
def find_last_lines(self) -> List["Line"]:
|
|
|
|
if len(self.__children) == 0:
|
|
|
|
return [self]
|
|
|
|
else:
|
|
|
|
return [self, *self.__children[-1].find_last_lines()]
|
|
|
|
|
|
|
|
def print(self, depth: int = 0) -> None:
|
|
|
|
print(f"{' ' * depth}{self}", end="")
|
|
|
|
for child in self.__children:
|
|
|
|
child.print(depth + 1)
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
return f"{self.__line_number}: {self.__content}"
|
|
|
|
|
|
|
|
|
|
|
|
class CodeTree:
|
|
|
|
def __init__(self):
|
|
|
|
self.root: Line = Line("\n", -1, -1)
|
|
|
|
|
|
|
|
def append(self, content: str, line_number: int) -> None:
|
|
|
|
last_lines: List[Line] = self.root.find_last_lines()
|
|
|
|
new_leading_spaces: int = self.__get_leading_spaces(content)
|
|
|
|
|
|
|
|
previous_line: Line = self.root
|
|
|
|
previous_leading_spaces: int = -1
|
|
|
|
for line in last_lines:
|
|
|
|
leading_spaces = self.__get_leading_spaces(line.get_content())
|
|
|
|
if (
|
|
|
|
previous_leading_spaces < new_leading_spaces
|
|
|
|
and new_leading_spaces <= leading_spaces
|
|
|
|
):
|
|
|
|
break
|
|
|
|
previous_line, previous_leading_spaces = line, leading_spaces
|
|
|
|
|
|
|
|
new_line_depth: int = previous_line.get_depth() + 1
|
|
|
|
previous_line.append_child(Line(content, line_number, new_line_depth))
|
|
|
|
|
|
|
|
def find_from_root(self, depth: int) -> List[Line]:
|
|
|
|
return self.root.find_by_lte_depth(depth)
|
|
|
|
|
|
|
|
def find_from_parent(self, depth: int, parent_content: str) -> List[Line]:
|
|
|
|
lines: List[Line] = self.root.find_by_content(parent_content)
|
|
|
|
if len(lines) == 0:
|
|
|
|
return []
|
|
|
|
parent = lines[0]
|
|
|
|
return parent.find_by_lte_depth(depth + parent.get_depth())
|
|
|
|
|
|
|
|
def print(self):
|
|
|
|
print("Code Tree:")
|
|
|
|
print("=================================")
|
|
|
|
self.root.print()
|
|
|
|
print("=================================")
|
|
|
|
|
|
|
|
def __get_leading_spaces(self, content: str) -> int:
|
|
|
|
return len(content) - len(content.lstrip())
|
2023-03-23 10:12:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
class ReadCommand:
|
|
|
|
separator = "|"
|
|
|
|
|
|
|
|
def __init__(self, filepath: str, start: int, end: int):
|
2023-04-07 02:11:24 +00:00
|
|
|
self.filepath: str = filepath
|
2023-03-23 10:12:57 +00:00
|
|
|
self.start: int = start
|
|
|
|
self.end: int = end
|
|
|
|
|
2023-04-07 02:11:24 +00:00
|
|
|
@verify
|
2023-03-26 06:27:51 +00:00
|
|
|
def execute(self) -> str:
|
2023-03-23 10:12:57 +00:00
|
|
|
with open(self.filepath, "r") as f:
|
|
|
|
code = f.readlines()
|
2023-03-26 06:27:51 +00:00
|
|
|
|
2023-03-23 10:12:57 +00:00
|
|
|
if self.start == self.end:
|
|
|
|
code = code[self.start - 1]
|
|
|
|
else:
|
|
|
|
code = "".join(code[self.start - 1 : self.end])
|
|
|
|
return code
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def from_str(command: str) -> "ReadCommand":
|
|
|
|
filepath, line = command.split(ReadCommand.separator)
|
|
|
|
start, end = line.split("-")
|
|
|
|
return ReadCommand(filepath, int(start), int(end))
|
|
|
|
|
|
|
|
|
2023-03-26 06:27:51 +00:00
|
|
|
class SummaryCommand:
|
|
|
|
separator = "|"
|
|
|
|
|
|
|
|
def __init__(self, filepath: str, depth: int, parent_content: Optional[str] = None):
|
2023-04-07 02:11:24 +00:00
|
|
|
self.filepath: str = filepath
|
2023-03-26 06:27:51 +00:00
|
|
|
self.depth: int = depth
|
|
|
|
self.parent_content: Optional[str] = parent_content
|
|
|
|
|
2023-04-07 02:11:24 +00:00
|
|
|
@verify
|
2023-03-26 06:27:51 +00:00
|
|
|
def execute(self) -> str:
|
|
|
|
with open(self.filepath, "r") as f:
|
|
|
|
code = f.readlines()
|
|
|
|
|
|
|
|
code_tree = CodeTree()
|
|
|
|
for i, line in enumerate(code):
|
|
|
|
if line.strip() != "":
|
|
|
|
code_tree.append(line, i + 1)
|
|
|
|
|
|
|
|
if self.parent_content is None:
|
|
|
|
lines = code_tree.find_from_root(self.depth)
|
|
|
|
else:
|
|
|
|
lines = code_tree.find_from_parent(self.depth, self.parent_content)
|
|
|
|
return "".join([str(line) for line in lines])
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def from_str(command: str) -> "SummaryCommand":
|
|
|
|
command_list: List[str] = command.split(SummaryCommand.separator)
|
|
|
|
filepath: str = command_list[0]
|
|
|
|
depth: int = int(command_list[1])
|
|
|
|
parent_content: str | None = command_list[2] if len(command_list) == 3 else None
|
|
|
|
return SummaryCommand(
|
|
|
|
filepath=filepath, depth=depth, parent_content=parent_content
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2023-03-23 10:12:57 +00:00
|
|
|
class CodeReader:
|
|
|
|
@staticmethod
|
|
|
|
def read(command: str) -> str:
|
|
|
|
return ReadCommand.from_str(command).execute()
|
2023-03-26 06:27:51 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def summary(command: str) -> str:
|
|
|
|
return SummaryCommand.from_str(command).execute()
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
summary = CodeReader.summary("read.py|1|class ReadCommand:")
|
|
|
|
print(summary)
|