From aef138533c9612ac436f36fefaec8cdc4632b24d Mon Sep 17 00:00:00 2001 From: Kyattsukuro Date: Mon, 16 Mar 2026 16:10:58 +0100 Subject: [PATCH] ringe should work now --- .vscode/launch.json | 12 ++- __init__.py | 70 ++++++++++--- __pycache__/logger.cpython-312.pyc | Bin 0 -> 352 bytes data/ringe_short.xlsx | Bin 0 -> 35063 bytes .../countings_formater.cpython-312.pyc | Bin 1210 -> 1210 bytes .../__pycache__/ring_formater.cpython-312.pyc | Bin 0 -> 1400 bytes instructions/ring_formater.py | 94 +++++++++--------- logger.py | 3 + .../__pycache__/serializer.cpython-312.pyc | Bin 9367 -> 10874 bytes .../find_and_replace.cpython-312.pyc | Bin 1121 -> 1451 bytes .../regex_edit_col.cpython-312.pyc | Bin 962 -> 1654 bytes .../regex_move_to_col.cpython-312.pyc | Bin 5030 -> 5071 bytes .../row_color_to_value.cpython-312.pyc | Bin 0 -> 3486 bytes table_handler/commands/find_and_replace.py | 13 ++- table_handler/commands/regex_edit_col.py | 25 ++++- table_handler/commands/regex_move_to_col.py | 2 +- table_handler/commands/row_color_to_value.py | 52 ++++++++++ table_handler/serializer.py | 49 +++++---- 18 files changed, 232 insertions(+), 88 deletions(-) create mode 100644 __pycache__/logger.cpython-312.pyc create mode 100644 data/ringe_short.xlsx create mode 100644 instructions/__pycache__/ring_formater.cpython-312.pyc create mode 100644 logger.py create mode 100644 table_handler/commands/__pycache__/row_color_to_value.cpython-312.pyc create mode 100644 table_handler/commands/row_color_to_value.py diff --git a/.vscode/launch.json b/.vscode/launch.json index 1f0c528..b0cc008 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,12 +4,20 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ - { - "name": "Python Debugger: Current File", + "name": "Rings", "type": "debugpy", "request": "launch", "program": "${workspaceFolder}/__init__.py", + "args": ["-i", "data/ringe_short.xlsx", "-o", "ringe_short_out.xlsx", "-t", "ring"], + "console": "integratedTerminal" + }, + { + "name": "Countings", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/__init__.py", + "args": ["-i", "data/zählungen_short.xlsx", "-o", "zählungen_short_out.xlsx", "-t", "counting"], "console": "integratedTerminal" } ] diff --git a/__init__.py b/__init__.py index 93a44a0..7e4a91a 100644 --- a/__init__.py +++ b/__init__.py @@ -1,17 +1,61 @@ +import argparse +from table_handler.serializer import TableSerializer +from logger import logger -from table_handler.serializer import TableSerializer -from pprint import pprint as print +import instructions.countings_formater as countings_formater +import instructions.ring_formater as ring_formater +def main(): + + parser = argparse.ArgumentParser(description="Serialize Excel tables.") + + parser.add_argument( + "-i", "--input", + required=True, + help="Input Excel file" + ) + + parser.add_argument( + "-o", "--output", + required=True, + help="Output Excel file" + ) + + parser.add_argument( + "-t", "--type", + required=True, + choices=["ring", "counting"], + help="Type of table to process" + ) + + args = parser.parse_args() + + # Select formatter based on type + if args.type == "ring": + formatter = ring_formater + row_instructions = ring_formater.ROW_INSTRUCTIONS + else: + formatter = countings_formater + row_instructions = countings_formater.ROW_INSTRUCTION + + logger.info("Reading file, building serializer...") + serializer = TableSerializer( + args.input, + formatter.EXPECTED_INPUT_TABLE_SCHEMA, + formatter.EXPECTED_OUTPUT_TABLE_SCHEMA + ) + + logger.info("Starting transformation") + serializer.run( + formatter.COL_INSTRUCTIONS, + row_instructions + ) + + logger.info("Writing transformations") + serializer.write_output(args.output) + + logger.info("Done") + if __name__ == "__main__": - # Example usage - import instructions.countings_formater as countings_formater - - file = "data/zählungen_short.xlsx" - serializer = TableSerializer(file, countings_formater.EXPECTED_INPUT_TABLE_SCHEMA, countings_formater.EXPECTED_OUTPUT_TABLE_SCHEMA) - serializer.run( - countings_formater.COL_INSTRUCTIONS, - countings_formater.ROW_INSTRUCTION - ) - print(serializer.serialized_output) - serializer.write_output("zählungen_test_out.xlsx") \ No newline at end of file + main() \ No newline at end of file diff --git a/__pycache__/logger.cpython-312.pyc b/__pycache__/logger.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7267dd081a600b7b03f794aa65fe6decb000ab67 GIT binary patch literal 352 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 KQJ&Za;sF4tt6x+A literal 0 HcmV?d00001 diff --git a/instructions/__pycache__/countings_formater.cpython-312.pyc b/instructions/__pycache__/countings_formater.cpython-312.pyc index b4edbc11930238bfb74dedb6b138c6a0723f7ae1..d053f798d42661ee24516103ebd8184a90bfca71 100644 GIT binary patch delta 19 ZcmdnRxr>wQG%qg~0}vQgY~wQG%qg~0}$90ZRFa(0st_$1f2i? diff --git a/instructions/__pycache__/ring_formater.cpython-312.pyc b/instructions/__pycache__/ring_formater.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c4d3d57bd092b9602f0dfe4e42bd380fbf67923 GIT binary patch literal 1400 zcma)5OK;mo5GF;6vSeG56FF2) zYcBqa-k4yRKYZig1$MCBz5($KgBZm2nV&-}qcJG-9ou0s+X*2KbBI6kB_GIeh{0jZ zeKmca{f>BfuD@i*3KCERO&sxPoWuXmoai_Q#ZVMY9&uV2O`&NNM+uY!EDlG;Jn#hI z&jhilBfb+wS5O+wY9WZtpe(wIt{n*)+ld{{iMdmsk;qcED8^~5p_`iN8U`kmD-(yt z*0J5~^>Mf7&~Ul$!2Xp69uNz;2aax;w(Y2nYrAm(X`A3yiP8V{2UEi|vW}nXL0%O? z49dxX7kQ|fn(8a<9vNcYp~5DyzQiV-e5_-H$-ZkMOrvWUC>*$^Mw1U~8&#zYUqjlg zmn)JOqLHp;7^;aVXQ%@@(~#DsE#;B?xumpYr6Sjdg}tQ*_qO-)yT$ynSX_GcY%za3 zzxe#Q_`w5kE%Vz;zVeufwm7h7Hx}_GrklNCcvW*Dv83 zOX?*+kqfX$20}^JM~#oEN!41*=hYe(_qO-cm0@|Mvx9bvOWR|8wTZ3avgq9n=i({dC*`!>UEOvHNMqoOQJAtWOQFsx>nyJ zHl0)lFezW_Ko+hPs9?Ki^$`^um1r0S>WSKS@rF1_C*U3jP>xM=($=O_X-QS3wz1i6 zDXsEaT~eBr&!k6XI)CAm+pYh2r(i%DauiFmg5AdN)BhAfPr6x6L ztWs_PUR7E9f+nGAIH?I01Zhp0^n3B{&QHu+D3bZ>(^AheaLI-o7w^1UymPX6_ay(3H*?pE z-#CkgAv(^agMj9bTi Geschlecht a | Alter a - "name": "REGEX_MOVE_TO_COL", - "command": { - "match": r"^(?:[^ ]* +)*m(a),?(?: .*+)*$", - "to": "Alter" - } + "command": "REGEX_MOVE_TO_COL", + "match": r"^(?:[^ ]* +)*m(a),?(?: .*+)*$", + "to": "Alter" + }], + ("Ringnummer",): { + "command": "REGEX_EDIT_COL", + "matching_group_rearange": True, + "match": r"^[^a-zA-Z\d]*([a-zA-Z]*)[^a-zA-Z\d]*(\d+)$", + "replace_with": r"{{% 0 %}}{{% 1 %}}" }, - ["Ringnummer"]: { - "name": "REGEX_EDIT_COL", - "command": { - "match": r"^[^a-zA-Z\d]*([a-zA-Z]*)[^a-zA-Z\d]*(\d+)$", - "to": "{{% 1 %}}{{% 2 %}}" - } + ("Art",): { + "command": "FIND_AND_REPLACE", + "map": SPICIES }, - ["Art"]: { - "name": "FIND_AND_REPLACE", - "command": { - "map": SPICIES - } - }, - ["Ort"]: { - "name": "REGEX_MOVE_TO_COL", - "command": { - "with_input_iteration": flatten_dict(CATCHED_BY), # Moves matching group {{% 1 %}} to "to" - "match": r"^(?:[^ ]* +)*({{% 1 %}}),?(?: .*+)*$", - "to": "Fangart" - } + ("Ort",): { + "command": "REGEX_MOVE_TO_COL", + "with_input_iteration": CATCHED_BY, # Moves matching group {{% 1 %}} to "to" + "match": r"^(?:[^ ]* +)*({{% 0 %}}),?(?: .*+)*$", + "to": "Fangart" } } @@ -72,12 +71,13 @@ COL_INSTRUCTIONS = { ROW_INSTRUCTIONS = [ { "command": "ROW_COLOR_TO_BOOL", # Match when found as text color in any col of the row - "color": ["#ff0000", "#0000ff"], + "fg_colors": [(255,0,0), (0,0,255)], "approximate": True, - "column": "Wiederfunde", - "value": "TRUE" - }, - { - "command": "ROW_COPY_REMAINING" + "threshold": "ALL", # ALL, ANY, MAJORITY of row must be collored + "target": "Wiederfunde", + "value": "TRUE", } + #{ + # "command": "ROW_COPY_REMAINING" + #} ] \ No newline at end of file diff --git a/logger.py b/logger.py new file mode 100644 index 0000000..7350b87 --- /dev/null +++ b/logger.py @@ -0,0 +1,3 @@ +import logging +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) \ No newline at end of file diff --git a/table_handler/__pycache__/serializer.cpython-312.pyc b/table_handler/__pycache__/serializer.cpython-312.pyc index c693891db92020578aa450501c33393f9d28435b..2008f80d3f13b4d5da78abf3848ade2e07972884 100644 GIT binary patch delta 3893 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 PX8(po#rP8ll`Q)gz$!&Q delta 683 zcmY*XKWGzS6o22p%b%Jy*Vo2vsS$3#43Z`7SAhT(Luk z3{?y_L?^Ex*wR54admKW(k|i9!O=yc5u}^%yEy2B_xpbD-Fv_HKE68|`x@6jq*6&h zd%XIl_KI}%v$@L{^}qs)I8Y~LLV&^wSacUGc0^SzK$*6g9+;ZOjEJ{(8rfk!;Jk8ETu zI3y*LNDV`ihTOHCY81Gt&A&++1&+i`AnZWjnCS3F@gW8fYSL~r<%9obDVb>2d+<+4 zr7#b$ibC6Ln|pj2?oJ~Yp76-}zZ)t!v@LMS-nd8C6aFP;_yN@mGaUAE96Wj(WE@LO zA(eb6w$_}c9W5G)TEnipVNBYa&RWGbHJR{Vuzbo@%S=Tklm2(Ma4v=k_YT4ieAXwP zG<)rC`&gguu)bg9nS3^wc{#g3`^lK^XR^;1pDhOM*DJ@FVt46>fT_6wgDckuaX4*s zlJXR)l+2j_mggSIF%0A+!XZQ-r1}x0ddmpZ#_m;wT^LXzCZ8?`MqnM}_iI7+7%Q6n?w2Ydf*i1gD8<6p*2H%_>q1NK^rlM5PcUKshu~52k3f@lG6D>)kNB zE_J$=a>&6*m8efng;2wZR=FTfJ@y!hOG1FSOAiRRa3aM>NSt^x{z((%N&Eh0-+MFf zdo$k;4D+?da` zU2TpT1+`vB(Etir$%L$IMofv4Wf`-mS;Zt&MP1oYvLRCydI1yhZ|5R0(2?u3AQp>Yo+76{cd0rUZ&htz{NLgY|L7-7c@5MEdW;%!*T@85fyj z)65meq?uJ#xRF`5s7YDLD7zWYShA?TV%VldStjR{N~pRS#?Pr!JgA;?tjX0%5YhF5 zji$af@@x|(yKY|9J%?-^nj>R1<#vB_{FR#WW8_>jJyTPDid<;nA_VFU!z$BU@0jQd z;U`-38!8R(dJQQ)`xmZp^5Imk)J4B4n@}ab%;r4a4MDzK40rV-nTPF8rLKGzKG6WK zW7VosRei!_pV(2X$UA(3iqR7eG)>7@zQk$#iuh`8Kjij=0_|K22>$|TWPVM#bt{!z zQ8XR!%X_1jAIuCrQV>Nd-a$&QKj1BPJg&6h9%sw^|962!&-=V@UO%dfus>;5+ zjvsdQ)R|z6bJVid#*f{;6RU9ybw5Cc zmvCsL5v@mSYBM@in{Ez2U;F6S=-@##{X;a}98NT*>(g5!`@`woSo)8_vtLv`uWX*Z zH+FYyYw;j;X)kr@p}Idfvm2QaAkAyioEG74fNhkht_S_PUUJMbJ{@`x)AdiwhSgb7 zmK?`oyg_(WkF`%ej^+apsl-S!{#ppe59?k;wgFFNqRu{AYypbH{;-|Z4z&HfF@M9lxG CWMh{A literal 962 zcmZuvziSjx5T3U`&Q0z@5@H~c5SC!!HrXPD#YrFuVj)~%u(=42&AxZu9s47`-92;R ziWFBQAjDMHSXdg;Xd(U)HW3lSYG-8^a)MyxyxY5Y9vRqgXTEteJNwQ1I59B}Xy%jm zwN(P}Lk0uW`cBtGrvnTa@t_O}JOHM&fvKlTcA`w0#L|AspyXy$hW$Kr7cuSthcaPM zRv2kRS!D{>DhgBET3K&umYxL%v+Z$ObpqybVY{L4qZ`>mPE9$EP2JF2-f5-=rL_P?YmsUP4t-O8wVe8%2=gGA*V@(vWwq)hxz5>VRl&0g9`XNhj z%``1g`Ydt0EFMxM*tU?|} s1*QfyVorK;l1u{QUN*q0m`6@t>*yxJg-Qtd24lZ9gRGNFkl3sG3jkEgVE_OC diff --git a/table_handler/commands/__pycache__/regex_move_to_col.cpython-312.pyc b/table_handler/commands/__pycache__/regex_move_to_col.cpython-312.pyc index 3d73fd1ac03b2b1c39ae599b98951cf37ce3a0c3..cea26d4286cab037fad15fff57c564f24d95f665 100644 GIT binary patch delta 119 zcmZ3ceqNpTG%qg~0}!3)c?AJ*ig=TqZi6Fg&4rQN(vLH;V%Dt delta 86 zcmX@FzD%9>G%qg~0}x!u-Ame3`_)QSHMjZJO+wDBevbW!jhZ)0`1$T|e#IXTN8l zS*7h-@7#0GJ@?#u&OPUM{fFx6Dg^Bx%y#sF4WYl$fzkLfv)2sF8e-8UB%);`GWXfi z%mi9s{ao14r+syKu=jId){ulI7!ggdlV}pwiEM-yIf)Z__$(4HStKj{MYv<2O+V54 zT&Yd6iFS#LxJ1XYWx_62Jy**KR$Y=UVil{G`3Z;U7HdHd_KUE(?K+sRNr9Jeih8h9 zwNT?fLTcYp<^~j5!Q;w6P)W zqp_d{D%up5)G0+4!?1_hIN<2F_a`80NMnqdGlPJyTV~b%oZPCY8b8HpaSqAUl**qoeYz14U zZwtuJkETwVf$=KXYlg-fORAbTBzYk|vr$pf{2avf%{MVU3bDWS+8b}bb9ww~%4Y`6 zTmf3Ayl@57o}uTr6Hb=mr0NR2jX{hROzg(a#BOYhsUw(rhaHsA-1gfDuS#;HB-RzE z3)p@@OQkYzseSc!&y*6AdQ>1vTkW9#({f3y0}752%|mengDt12|Mu1*5uEO>l(`ZN5l zz4?i=A=~;=&iRsVW-#v_%DRRM$2v3ok8Ac|J476i*RmAWqH*HXQ(Q>M!LUTESkjU> z9yXH+l%4SD$^1T~;|+9!yT z{w_p+ky&K-!3~pUQ((f_afO>{LFi}98Uyia;n4#6H8;m>GNXQmaKVu3=Ls8lkuX8R zgorf;7#WSLw5FkSmN0dOIQl20xHO-@=TjHHmhIswDLf-YBeY2Lq*LMopeKm28t9jm za8Opy2TTj?U{LJ_^5x&rmrE$?3+0A`pYl7*&Y64a#+i-xHqZScwRPpe$v%+(TR+H; z+B%p6@u2xi54Pt6a+{^GSYe-+tt$+DCT1b7xD}X9hSseZ4MW`mdNK3338dH!M5Q*p zOJ#@c{cqh;C_(^Otwmp&y4CnmAnC1d@Q9|QA{spZh zzq15%G(^M-uaOiN;htofaH(j5@N!hu2p0<`bSQ+G_yVznm1JDQG@<=A-5uNryzU*b z!4n1-lAv1f+L3CorOZiU3DmHDKw65|z1QK!FO+WlxbRKanmYYIMTOph`b!{REun(D zA!92zYacp2pF2H;qfMEiN5?u>Ero9X$Jg#&+v?lxes%S&LW5^*^w#LT-n=jLNA9!1 z?AZ0);UEn1U7-gJ;inw(U0{H=bUm}9CeKH`yY0hy&*gmM8<|T_YTQ4Guf+dS-}tzx z<<84LO=s)69_=3#>fME=wzb7ui|gb0rWbxSw$*h1-R+LeALN?)vUPp>t&9>5D|5uD zDoGrc^wd6pnlxZKYCZ<$hNXmA zq=(kauoIZu3@yX|UWDZm#3w-4&k`oAXQxVSlwk&+1U~iR;nb4mrEpS{1b`K|l6{C$ zt}u9FkV;dZR#@

CNeF&*yhHFS{V>42l)OL*#Z~0E#)^_YVI|~iXYa_Qt)*C)mf!jnS>ohAc z&3B#9r%e3~kY!Y~qF4F~-~LYFgul??d+Kbkblp*l2)aU3OOb>AiKl(tvL4>(-Qw0` zIq%t==UmYOa#-2w{o0I;&e%~~XVF2qD%9G(M~xN(b(a1uZF_L1Ye)TTVCQtM|GT-D zzgI*c&R!3f`YCyjj-UGM7Wevzb#-H4eg1Bsh+w#_?wtMY{4>gyJfhCPi&=7N5C#=T giM_uRx$~I5&$_p@z!W)#VgAMTGVXsOAo_y;0P^rd&j0`b literal 0 HcmV?d00001 diff --git a/table_handler/commands/find_and_replace.py b/table_handler/commands/find_and_replace.py index 9289aca..93eab31 100644 --- a/table_handler/commands/find_and_replace.py +++ b/table_handler/commands/find_and_replace.py @@ -1,13 +1,20 @@ +import re from copy import deepcopy class FindAndReplace: - def __init__(self, map: dict[str, dict[str]]): + def __init__(self, map: dict[str, list[str]], case_sensitive: bool = False): self.map = map + self.case_sensitive = case_sensitive def execute_on_cell(self, entry) -> str: res = deepcopy(entry.value) + for species, alternatives in self.map.items(): for old_version in alternatives: - if old_version in entry.value: - res = res.replace(old_version, species) + if self.case_sensitive: + res = res.replace(old_version, species) + else: + pattern = re.compile(re.escape(old_version), re.IGNORECASE) + res = pattern.sub(species, res) + return res \ No newline at end of file diff --git a/table_handler/commands/regex_edit_col.py b/table_handler/commands/regex_edit_col.py index c2f1976..249b75c 100644 --- a/table_handler/commands/regex_edit_col.py +++ b/table_handler/commands/regex_edit_col.py @@ -1,11 +1,26 @@ -import re +import regex class RegexEditCol: - def __init__(self, match, replace_with): + def __init__(self, match, replace_with, matching_group_rearange: bool = False): self.match = match self.replace_with = replace_with + self.matching_group_rearange = matching_group_rearange + def _reorder(self, value: str): + matches = regex.match(self.match, value) + res = None + if matches: + for i, match in enumerate(matches.groups([])): + res = (res if res else self.replace_with).replace(f"{{{{% {i} %}}}}", match) + + return res if res else value + def execute_on_cell(self, entry) -> str: - if entry.value is None: - return entry.value - return re.sub(self.match, self.replace_with, entry.value) \ No newline at end of file + value = entry.value + if value is None: + return value + + if self.matching_group_rearange: + return self._reorder(value) + + return regex.sub(self.match, self.replace_with, value) \ No newline at end of file diff --git a/table_handler/commands/regex_move_to_col.py b/table_handler/commands/regex_move_to_col.py index 290297b..f47d7b2 100644 --- a/table_handler/commands/regex_move_to_col.py +++ b/table_handler/commands/regex_move_to_col.py @@ -11,7 +11,7 @@ class RegexMoveToCol: [[with_input_iteration]] if isinstance(with_input_iteration, str) else [ - x if isinstance(x, list) else [x] + x if isinstance(x, list) or isinstance(x, tuple) else [x] for x in (with_input_iteration if isinstance(with_input_iteration, (list, tuple)) else [with_input_iteration]) ] ) diff --git a/table_handler/commands/row_color_to_value.py b/table_handler/commands/row_color_to_value.py new file mode 100644 index 0000000..3ba3c1a --- /dev/null +++ b/table_handler/commands/row_color_to_value.py @@ -0,0 +1,52 @@ +class RowColorToCalue: + def __init__(self, target: str, + value: str, + fg_colors: dict[tuple[int, int, int]] = [], + bg_colors: dict[tuple[int, int, int]] = [], + approximate: bool = False, + threshold: str = "ANY", + ): + + if not len(fg_colors) and not len(bg_colors): + raise ValueError("fg_colors or bg_colors must be providet") + + self.fg_color = fg_colors if fg_colors else [] + self.bg_color = bg_colors if bg_colors else [] + + self.value = value, + self.target = target, + self.approximate = approximate, + + if threshold not in ("ALL", "ANY", "MAJORITY"): + raise ValueError("threshold must be ALL, ANY or MAJORITY") + self.threshold = threshold + + + def _check_if_collection_matchers(self, collectin: dict[tuple[int, int, int]], color_place: str) -> bool: + res_map = [] + if self.approximate: + margin = 10 + for color in collectin: + for allowed_color in self.__dict__[color_place]: + res_map.append(all(abs(a - b) <= margin for a, b in zip(color, allowed_color))) + else: + res_map = list(map(lambda x: x in self.__dict__[color_place])) + + match self.threshold: + case "ALL": + return all(res_map) + case "ANY": + return any(res_map) + case _: + return res_map.count(True) > len(res_map)/2 + + + def execute_on_row(self, row: dict[str, str], source_coll: str|None = None): + color_pace_results = [] + for color_place in ["fg_color", "bg_color"]: + color_collection = (map(lambda c: c.__dict__[color_place], row.values())) + color_pace_results.append(self._check_if_collection_matchers(color_collection, color_place)) + + if all(color_pace_results): + return {self.target: self.value} + return {} \ No newline at end of file diff --git a/table_handler/serializer.py b/table_handler/serializer.py index 0a3bf55..7eff1f7 100644 --- a/table_handler/serializer.py +++ b/table_handler/serializer.py @@ -10,9 +10,17 @@ from .commands.regex_edit_col import RegexEditCol from .commands.regex_move_to_col import RegexMoveToCol from .commands.copy import Copy from .commands.regex_group_valuebased_choose import RegexGroupValuebasedChoose +from .commands.row_color_to_value import RowColorToCalue +from logger import logger from .conditions.regex_cell import RegexCellCondition +def hex_to_rgb(hex): + if type(hex) != str and str("Values must be of type "): + # chatch wierd openxl things + hex = "#0" + hex= "{:06}".format(str(hex).lstrip("#")) + return tuple(int(hex[i:i+2],16) for i in (0, 2, 4)) @dataclass class Entry: @@ -48,15 +56,15 @@ class TableSerializer: print(f"Skipping unexpected Col {cell_value}") if set(map_expected_with_ws.keys()) != set(expected_cols): - raise ValueError("Missing Col in input") + raise ValueError("Missing Col in input, check your table header") for rid, row in enumerate(self.ws.iter_rows(min_row=2, values_only=False), start=2): for expected_col, ws_idx in map_expected_with_ws.items(): cell = row[ws_idx] data[expected_col][rid] = Entry( - value=str(cell.value) if not cell.value is None else None, - bg_color=cell.fill.start_color.rgb if cell.fill and cell.fill.start_color else (0,0,0), - fg_color=cell.font.color.rgb if cell.font and cell.font.color else (0,0,0) + value=str(cell.value) if not cell.value is None else "", + bg_color=hex_to_rgb(cell.fill.start_color.rgb if cell.fill and cell.fill.start_color else "#0"), + fg_color=hex_to_rgb(cell.font.color.rgb if cell.font and cell.font.color else "#0") ) return data @@ -87,10 +95,11 @@ class TableSerializer: return True def _merge_change_to_cel(self, value, changes): - if not value and changes: - value = changes - elif changes: - value = f"{value}{self.seperator}{changes}" + #if not value and changes: + # value = changes + #elif changes: + # value = f"{value}{self.seperator}{changes}" + value = changes return value def _extecute_instruct(self, source_cell: str, instruct: dict, row: dict[str, any], working_row: dict[str, any]): @@ -104,7 +113,7 @@ class TableSerializer: res_row = RegexMoveToCol(instruct["match"], instruct["to"], instruct.get("with_input_iteration")) \ .execute_on_row(row, source_cell) case "REGEX_EDIT_COL": - res = RegexEditCol(instruct["match"], instruct["replace_with"])\ + res = RegexEditCol(instruct["match"], instruct["replace_with"], instruct.get("matching_group_rearange"))\ .execute_on_cell(row[source_cell]) case "REGEX_GROUP_VALUEBASED_CHOOS": res = RegexGroupValuebasedChoose(instruct["match"], instruct["highest"])\ @@ -112,7 +121,10 @@ class TableSerializer: case "CONDITIONAL_COPY": res_row = Copy(instruct["source"], instruct["target"], replace=instruct.get("replace"))\ .execute_on_row(row) - + case "ROW_COLOR_TO_BOOL": + res_row = RowColorToCalue(instruct["target"], instruct["value"], instruct.get("fg_colors"), instruct.get("bg_colors"), instruct.get("approximate"), instruct.get("threshold"))\ + .execute_on_row(row) + # Merge row_changes to working_row for target_cel, change in res_row.items(): working_row[target_cel] = self._merge_change_to_cel(working_row.get(target_cel), change) @@ -132,19 +144,22 @@ class TableSerializer: def run(self, col_instructions: dict[tuple[str], dict], row_instructions: dict[tuple[str], dict]): self.serialized_output = {} - for rid in range(2, self.vertical_len + 2): + amount_working_rows = self.vertical_len +2 + for rid in range(2, amount_working_rows): + logger.info(f"Working on row {rid}/{amount_working_rows} ") working_row = {} source_row = self.get_row_as_dict(rid) - for source_cols, instruct in list(col_instructions.items()) + [ + for source_cols, instructions in list(col_instructions.items()) + [ ((None,), instr) for instr in row_instructions ]: - for col in source_cols: - if not self._check_conditions(instruct, source_row): - continue - working_row = self._extecute_instruct(col, instruct, source_row, working_row) + for instruct in instructions if type(instructions) == list else [instructions]: + for col in source_cols: + if not self._check_conditions(instruct, source_row): + continue + working_row = self._extecute_instruct(col, instruct, source_row, working_row) if not self.implicit_copy: continue - for col in self.expected_output_schema: + for col in self. expected_output_schema: if col in working_row: continue working_row[col] = source_row.get(col).value