Browse Source

removed typehints due to py3.8 requirements

main
Holger Frey 2 months ago
parent
commit
e526a500fe
  1. 24
      superx_budget/__init__.py
  2. 14
      superx_budget/budget.py
  3. 21
      superx_budget/helpers.py

24
superx_budget/__init__.py

@ -10,7 +10,7 @@ import pathlib
import sys import sys
import warnings import warnings
from .budget import parse_budget_file # noqa: F401 from .budget import parse_budget_file
from .exceptions import BudgetParserError, SuperXParserError # noqa: F401 from .exceptions import BudgetParserError, SuperXParserError # noqa: F401
from .helpers import ( # noqa: F401 from .helpers import ( # noqa: F401
find_budget_file, find_budget_file,
@ -19,7 +19,7 @@ from .helpers import ( # noqa: F401
is_budget_file_name, is_budget_file_name,
list_budget_files, list_budget_files,
) )
from .overview import create_overview # noqa: F401 from .overview import create_overview
from .pyramid import main # noqa: F401 from .pyramid import main # noqa: F401
from .superx import parse_exported_file # noqa: F401 from .superx import parse_exported_file # noqa: F401
@ -31,17 +31,17 @@ def cli_parse_exported_file():
) )
parser.add_argument("filename") parser.add_argument("filename")
args = parser.parse_args() args = parser.parse_args()
with warnings.catch_warnings(action="ignore"): with warnings.catch_warnings(action="ignore"):
sys.stderr.write(f"trying to read '{args.filename}'\n") sys.stderr.write(f"trying to read '{args.filename}'\n")
exported = superx.parse_exported_file(pathlib.Path(args.filename)) exported = superx.parse_exported_file(pathlib.Path(args.filename))
sys.stderr.write("... OK\n") sys.stderr.write("... OK\n")
sys.stderr.write(f"searching budget file for year '{exported.account_year}'\n") sys.stderr.write(
budget_dir = pathlib.Path(__file__).parent.parent / "budgets" f"searching budget file for year '{exported.account_year}'\n"
budget_file = find_budget_file(
budget_dir, exported.account_year
) )
budget_dir = pathlib.Path(__file__).parent.parent / "budgets"
budget_file = find_budget_file(budget_dir, exported.account_year)
if not budget_file: if not budget_file:
sys.exit("... no budget file found") sys.exit("... no budget file found")
sys.stderr.write(f"... found '{budget_file}'\n") sys.stderr.write(f"... found '{budget_file}'\n")
@ -50,18 +50,18 @@ def cli_parse_exported_file():
budget_data = parse_budget_file(budget_file) budget_data = parse_budget_file(budget_file)
sys.stderr.write("... OK\n") sys.stderr.write("... OK\n")
sys.stderr.write(f"Creating overview\n") sys.stderr.write("Creating overview\n")
overview_map = create_overview(budget_data, exported) overview_map = create_overview(budget_data, exported)
sys.stderr.write("... OK\n") sys.stderr.write("... OK\n")
sys.stderr.write(f"Sorting overview\n") sys.stderr.write("Sorting overview\n")
overview = sorted(overview_map.values(), key=lambda i: i.row) overview = sorted(overview_map.values(), key=lambda i: i.row)
sys.stderr.write("... OK\n") sys.stderr.write("... OK\n")
sys.stderr.write(f"Geting recipients file\n") sys.stderr.write("Geting recipients file\n")
recipients = find_recipients(budget_dir) recipients = find_recipients(budget_dir)
sys.stderr.write("... OK\n") sys.stderr.write("... OK\n")
sys.stderr.write(f"Retrieving sheet for export\n") sys.stderr.write("Retrieving sheet for export\n")
sheet = get_sheet_of_file(budget_file) sheet = get_sheet_of_file(budget_file)
sys.stderr.write("... OK\n") sys.stderr.write("... OK\n")

14
superx_budget/budget.py

@ -1,14 +1,10 @@
"""Budget Parser""" """Budget Parser"""
import typing
from collections import namedtuple from collections import namedtuple
from .exceptions import BudgetParserError from .exceptions import BudgetParserError
from .helpers import get_sheet_of_file, is_empty_excel_value, strip_excel_value from .helpers import get_sheet_of_file, is_empty_excel_value, strip_excel_value
ExcelStuff = typing.Any
T = typing.TypeVar("T")
EXPECTED_TABLE_HEADERS = [ EXPECTED_TABLE_HEADERS = [
"Nr.", "Nr.",
"Projekt", "Projekt",
@ -40,7 +36,7 @@ BudgetData = namedtuple(
) )
def _check_table_header(xl_row: ExcelStuff) -> None: def _check_table_header(xl_row):
fields_ignore_none = ( fields_ignore_none = (
("" if c is None else c) for c in xl_row.data[:NUM_EXPECTED_HEADERS] ("" if c is None else c) for c in xl_row.data[:NUM_EXPECTED_HEADERS]
) )
@ -51,7 +47,7 @@ def _check_table_header(xl_row: ExcelStuff) -> None:
raise BudgetParserError(msg) raise BudgetParserError(msg)
def _skip_empty_lines(rows: ExcelStuff) -> typing.Iterable[T]: def _skip_empty_lines(rows):
for xl_row in rows: for xl_row in rows:
first_cell = xl_row.data[0] first_cell = xl_row.data[0]
if is_empty_excel_value(first_cell): if is_empty_excel_value(first_cell):
@ -59,7 +55,7 @@ def _skip_empty_lines(rows: ExcelStuff) -> typing.Iterable[T]:
yield xl_row yield xl_row
def _parse_data_table(rows: ExcelStuff) -> BudgetData: def _parse_data_table(rows):
for xl_row in _skip_empty_lines(rows): for xl_row in _skip_empty_lines(rows):
data = [ data = [
strip_excel_value(value) strip_excel_value(value)
@ -68,14 +64,14 @@ def _parse_data_table(rows: ExcelStuff) -> BudgetData:
yield BudgetData(xl_row.row, *data) yield BudgetData(xl_row.row, *data)
def parse_budget_data(xls_sheet: ExcelStuff) -> list[BudgetData]: def parse_budget_data(xls_sheet):
"""parses the budget data""" """parses the budget data"""
rows = (ExcelRow(i, v) for i, v in enumerate(xls_sheet.values, start=1)) rows = (ExcelRow(i, v) for i, v in enumerate(xls_sheet.values, start=1))
_check_table_header(next(rows)) _check_table_header(next(rows))
return list(_parse_data_table(rows)) return list(_parse_data_table(rows))
def parse_budget_file(file_path: str) -> list[BudgetData]: def parse_budget_file(file_path):
"""parses the budget file""" """parses the budget file"""
sheet = get_sheet_of_file(file_path, sheet=None) sheet = get_sheet_of_file(file_path, sheet=None)
return parse_budget_data(sheet) return parse_budget_data(sheet)

21
superx_budget/helpers.py

@ -1,16 +1,13 @@
"""some helper functions""" """some helper functions"""
from pathlib import Path from pathlib import Path
from typing import TypeVar
import openpyxl import openpyxl
ExcelItem = TypeVar("ExcelItem")
DEFAULT_RECIPIENTS = ["frey@imtek.de"] DEFAULT_RECIPIENTS = ["frey@imtek.de"]
def excel_value_as_number(value: ExcelItem) -> float | int: def excel_value_as_number(value):
if value is None: if value is None:
return 0 return 0
if isinstance(value, str): if isinstance(value, str):
@ -21,7 +18,7 @@ def excel_value_as_number(value: ExcelItem) -> float | int:
return value return value
def get_sheet_of_file(excel_file: str, sheet: str | None = None) -> ExcelItem: def get_sheet_of_file(excel_file, sheet=None):
"""returns a sheet from an excel FileCache """returns a sheet from an excel FileCache
if name is set to None, the function returns the first sheet if name is set to None, the function returns the first sheet
@ -33,21 +30,21 @@ def get_sheet_of_file(excel_file: str, sheet: str | None = None) -> ExcelItem:
return workbook[sheet] return workbook[sheet]
def is_empty_excel_value(value: ExcelItem) -> bool: def is_empty_excel_value(value):
"""is the cell value considered empty""" """is the cell value considered empty"""
if value is None: if value is None:
return True return True
return isinstance(value, str) and value.strip() == "" return isinstance(value, str) and value.strip() == ""
def strip_excel_value(value: ExcelItem) -> str | ExcelItem: def strip_excel_value(value):
"""remove whitespace from an excel value if it is a string""" """remove whitespace from an excel value if it is a string"""
if isinstance(value, str): if isinstance(value, str):
return value.strip() return value.strip()
return value return value
def is_budget_file_name(path_or_name: str | Path) -> bool: def is_budget_file_name(path_or_name):
"""checks if a filename has the format "budget[...]-<year>.xlsx""" """checks if a filename has the format "budget[...]-<year>.xlsx"""
path = Path(path_or_name) path = Path(path_or_name)
if path.suffix.lower() != ".xlsx": if path.suffix.lower() != ".xlsx":
@ -61,14 +58,14 @@ def is_budget_file_name(path_or_name: str | Path) -> bool:
return False return False
def list_budget_files(folder: str | Path) -> list[Path]: def list_budget_files(folder):
"""lists all files with the name "budget[...]-<year>.xlsx""" """lists all files with the name "budget[...]-<year>.xlsx"""
files = (i for i in Path(folder).iterdir() if i.is_file()) files = (i for i in Path(folder).iterdir() if i.is_file())
visible = (i for i in files if not i.name.startswith(".")) visible = (i for i in files if not i.name.startswith("."))
return [i for i in visible if is_budget_file_name(i)] return [i for i in visible if is_budget_file_name(i)]
def find_budget_file(folder: str | Path, year: str | int) -> Path | None: def find_budget_file(folder, year):
"""searches for a file with the name "budget[...]-<year>.xlsx""" """searches for a file with the name "budget[...]-<year>.xlsx"""
for path in list_budget_files(folder): for path in list_budget_files(folder):
if path.stem.endswith(f"-{year}"): if path.stem.endswith(f"-{year}"):
@ -76,9 +73,7 @@ def find_budget_file(folder: str | Path, year: str | int) -> Path | None:
return None return None
def find_recipients( def find_recipients(folder, filename="recipients.txt"):
folder: str | Path, filename: str = "recipients.txt"
) -> list[str]:
"""finds the recipients of the budget list""" """finds the recipients of the budget list"""
file_path = folder / filename file_path = folder / filename
if file_path.is_file(): if file_path.is_file():

Loading…
Cancel
Save