Cura/printer-linter/tidy/diagnostic.py
2022-11-19 20:31:47 +01:00

86 lines
3.1 KiB
Python

class Diagnostic:
def __init__(self, illness, msg, file, key=None, termination_seq=None):
self.illness = illness
self.key = key
self.msg = msg
self.file = file
self._lines = None
self._location = None
self._fix = None
self._content_block = None
self._termination_seq = termination_seq
@property
def location(self):
if self._location:
return self._location
if not self._lines:
with open(self.file, "r") as f:
if not self.is_text_file:
self._fix = ""
return self._fix
self._lines = f.readlines()
start_location = {"col": 1, "line": 1}
end_location = {"col": len(self._lines[-1]) + 1, "line": len(self._lines) + 1}
if self.key is not None:
for lino, line in enumerate(self._lines, 1):
if f'"{self.key}":' in line:
col = line.index(f'"{self.key}":') + 1
start_location = {"col": col, "line": lino}
if self._termination_seq is None:
end_location = {"col": len(line) + 1, "line": lino}
break
if f'"{self._termination_seq}":' in line:
col = line.index(f'"{self._termination_seq}":') + 1
end_location = {"col": col, "line": lino}
self._location = {"start": start_location, "end": end_location}
return self._location
@property
def is_text_file(self):
return self.file.name.split(".", maxsplit=1)[-1] in ("def.json", "inst.cfg")
@property
def content_block(self):
if self._content_block:
return self._content_block
if not self._lines:
if not self.is_text_file:
self._fix = ""
return self._fix
with open(self.file, "r") as f:
self._lines = f.readlines()
start_line = self.location["start"]["line"] - 1
end_line = self.location["end"]["line"] - 1
self._content_block = "\n".join(self._lines[start_line:end_line])
return self._content_block
@property
def fix(self):
if self._fix:
return self._fix
if not self._lines:
if not self.is_text_file:
self._fix = ""
return self._fix
with open(self.file, "r") as f:
self._lines = f.readlines()
start_line = self.location["start"]["line"] - 2
start_col = 0
end_line = self.location["end"]["line"] - 1
end_col = len(self._lines[start_line:end_line - 1]) + self.location["start"]["col"] - 4 # TODO: double check if 4 holds in all instances
self._fix = self.content_block[start_col:end_col]
return self._fix
def toDict(self):
diagnostic_dict = {"diagnostic": self.illness, "message": self.msg}
if self.is_text_file:
diagnostic_dict |= {"fix": self.fix, "lino": self.location, "content": self.content_block}
return diagnostic_dict