refactor: big, more patterns\n\nBREAKING CHANGES

This commit is contained in:
2026-03-16 20:53:42 +03:00
parent 2105e9bc36
commit 7e0e4a0b71
5 changed files with 416 additions and 244 deletions

View File

@@ -1,6 +1,7 @@
# --- Абстрактный базовый класс (Контракт) ---
from abc import ABC, abstractmethod
from datetime import datetime, time
import openpyxl
import xlrd
@@ -10,9 +11,18 @@ from coord import Coord, Merged
EMPTY_CTYPES = [xlrd.XL_CELL_EMPTY, xlrd.XL_CELL_BLANK]
class TranschendentnostCell:
def __init__(self, value, is_empty):
def __init__(self, value, is_empty, is_time=False):
self.value = value
self.is_time = isinstance(value, time) or is_time
self._is_empty = is_empty
def is_nospace_nocase_same(self, query):
try:
if self.value.lower().replace(" ", "").strip() == query.lower().replace(" ", "").strip():
return True
except: pass
return False
def is_empty(self):
return self._is_empty
@@ -28,6 +38,10 @@ class ExcelSheetReader(ABC):
@abstractmethod
def get_sheet_index(self):
pass
@abstractmethod
def get_sheet_name(self):
pass
@abstractmethod
def has_next_sheet(self):
@@ -71,16 +85,28 @@ class ExcelSheetReader(ABC):
return "TODO: info"
@abstractmethod
def cell(self, row, col):
def cell(self, row, col) -> TranschendentnostCell:
"""Возвращает абстрактную клетку"""
pass
def find(self, query = None):
def find(self, query = None, startswith=False, nospace=False):
return self.find_any([query], startswith=startswith, nospace=nospace)
def find_any(self, query = None, startswith=False, nospace=False):
for rx in range(self.get_row_count()):
i = 0
for x in self.get_row_values(rx):
if x == query:
return Coord(rx, i)
if nospace:
x = str(x).replace(" ", "").strip()
for query_selected in query:
if x == query_selected:
return Coord(rx, i)
elif startswith:
try:
if str(x).lower().startswith(query_selected.lower()):
return Coord(rx, i)
except: pass
i += 1
return None
@@ -117,6 +143,9 @@ class XlrdSheetReader(ExcelSheetReader):
def init_sheet(self):
self.sheet = self.book.sheet_by_index(self.sheet_index)
def get_sheet_name(self):
return self.sheet.name
def has_next_sheet(self):
return self.sheet_index < len(self.book.sheet_names())-1
@@ -140,7 +169,24 @@ class XlrdSheetReader(ExcelSheetReader):
def cell(self, row, col):
"""Возвращает абстрактную клетку"""
c = self.sheet.cell(row, col)
return TranschendentnostCell(c.value, c.ctype in EMPTY_CTYPES)
is_empty = c.ctype in EMPTY_CTYPES
is_time = c.ctype == xlrd.XL_CELL_DATE
value = c.value
if is_empty:
value = ""
elif is_time:
if isinstance(value, float):
if value <= 1:
seconds = round(value * 86400)
minutes, seconds = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)
value = time(hour=hours, second=seconds, minute=minutes)
else:
print(f"TODO: value is {value} its unix? not 0.xxxxxxxx")
else:
is_time = False
print("IsTime but not float!")
return TranschendentnostCell(value, is_empty, is_time=is_time)
def get_border_style(self, coord: Coord, side):
row = coord.row
@@ -192,6 +238,9 @@ class OpenpyxlSheetReader(ExcelSheetReader):
def get_sheet_index(self):
return self.sheet_index
def get_sheet_name(self):
return self.workbook.sheetnames[self.sheet_index]
def has_next_sheet(self):
return self.sheet_index < len(self.workbook.sheetnames)-1
@@ -221,7 +270,7 @@ class OpenpyxlSheetReader(ExcelSheetReader):
c = self._get_cell(row, col)
is_empty = (c.value is None)
return TranschendentnostCell("" if is_empty else c.value, is_empty)
return TranschendentnostCell("" if is_empty else c.value, is_empty, is_time=isinstance(c.value, time))
def get_cell_value(self, row, col):
cell = self._get_cell(row, col)