Coverage for hledger_lots/options.py: 26%
80 statements
« prev ^ index » next coverage.py v7.2.3, created at 2023-05-05 10:12 -0300
« prev ^ index » next coverage.py v7.2.3, created at 2023-05-05 10:12 -0300
1from dataclasses import dataclass
2from typing import Dict, Optional, Tuple
4NAMESPACE = "hledger-lots"
5KEYS = {"avg_cost", "check", "no_desc"}
8@dataclass
9class Options:
10 avg_cost: bool
11 check: bool
12 no_desc: str
15class OptionError(BaseException):
16 TEMPLATE = """Copy/Paste the text below to the journal, changing values according to the need
18#+hledger-lots avg_cost:false, check:true
19#+hledger-lots no_desc:
20 """
22 def __init__(self, message: str) -> None:
23 self.message = f"\n\n{message}\n\n{self.TEMPLATE}"
24 super().__init__(self.message)
27class HledgerVars:
28 NAMESPACE_START = "#+"
30 def __init__(self, files: Tuple[str, ...]):
31 self.files = files
32 self.vars: Dict[str, str] = {}
34 def get_var_tuple(self, var_str: str):
35 var_key_value = var_str.split(":", 1)
36 if len(var_key_value) == 0:
37 return None
39 key = var_key_value[0].strip(" \n")
40 value = var_key_value[1].strip()
41 result = (key, value)
42 return result
44 def get_row_vars(self, row: str, namespace: str):
45 start = self.NAMESPACE_START + namespace
46 if not row.startswith(start):
47 return
49 vars_str = row[len(start) :]
50 if len(vars_str) == 0:
51 return
53 vars_list = vars_str.split(",")
54 vars_tuple = (self.get_var_tuple(var) for var in vars_list)
55 vars_dict = {var[0]: var[1] for var in vars_tuple if var}
56 return vars_dict
58 def get_file_vars(self, file: str, namespace: str):
59 result: Dict[str, str] = {}
60 with open(file, "r") as f:
61 for row in f:
62 row_vars = self.get_row_vars(row, namespace)
63 if row_vars:
64 result = {**result, **row_vars}
66 return result
68 def get_namespace_vars(self, namespace: str):
69 result: Dict[str, str] = {}
70 for file in self.files:
71 file_vars = self.get_file_vars(file, namespace)
72 if file_vars:
73 result = {**result, **file_vars}
75 self.var = result
76 return result
78 def get(self, key: str, default: Optional[str] = None):
79 if not self.vars:
80 return default
82 try:
83 value = self.vars[key]
84 except KeyError:
85 value = default
87 return value
90def get_options(files: Tuple[str, ...]):
91 hledger_vars = HledgerVars(files)
92 vars = hledger_vars.get_namespace_vars(NAMESPACE)
93 existing_keys = set(vars.keys())
94 missing = KEYS.difference(existing_keys)
96 if len(missing) > 0:
97 raise OptionError(f"Missing keys {missing}")
99 errors = ""
100 if vars["avg_cost"] not in ["true", "false"]:
101 errors += 'avg_cost should be "true" or "false"\n'
103 if vars["check"] not in ["true", "false"]:
104 errors += 'check should be "true" or "false"\n'
106 if errors != "":
107 raise OptionError(errors)
109 avg_cost = True if vars["avg_cost"] == "true" else False
110 check = True if vars["check"] == "true" else False
111 no_desc = vars["no_desc"]
112 return Options(avg_cost, check, no_desc)