rehan953 commited on
Commit
7ab2c22
·
verified ·
1 Parent(s): 1b1cb6a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +20 -11
app.py CHANGED
@@ -1102,10 +1102,16 @@ def _patch_ocr_with_textlayer(page_md: str, pdf_path: str, page_num: int) -> str
1102
  key = (_norm(r["date"]), _norm(r["desc"]), _norm(r["amount"]))
1103
  tl_freq[key] = tl_freq.get(key, 0) + 1
1104
 
1105
- # Share with _dedupe_duplicate_rows_in_da3_table so it can use
1106
- # the confirmed count as the cap (Fix-20 override).
 
 
1107
  global _tl_freq_context
1108
- _tl_freq_context = dict(tl_freq)
 
 
 
 
1109
 
1110
  table_pattern = re.compile(r"<table[^>]*>.*?</table>", re.DOTALL | re.IGNORECASE)
1111
  result = page_md
@@ -1280,10 +1286,8 @@ def _patch_ocr_with_textlayer(page_md: str, pdf_path: str, page_num: int) -> str
1280
 
1281
  except Exception as e:
1282
  log.warning("_patch_ocr_with_textlayer failed (page %d): %s", page_num, e)
1283
- return page_md
1284
- finally:
1285
- # Always clear so stale frequencies do not affect subsequent pages.
1286
  _tl_freq_context.clear()
 
1287
 
1288
  # --------------------------
1289
  # Fix 5: Mid-table separator row reconstruction
@@ -2731,11 +2735,10 @@ _DA3_MONEY_TOKEN = re.compile(
2731
  _MSFT_PIN_G_REF = re.compile(r"MICROSOFT#(G\d{6,16})", re.IGNORECASE)
2732
 
2733
  # Module-level text-layer frequency context (Fix-20 override).
2734
- # Set by _patch_ocr_with_textlayer before post-patch normalize passes;
2735
- # cleared in a finally clause so it never bleeds across pages.
2736
- # Keys are (date_norm, desc_norm, amount_norm) tuples matching tl_freq.
2737
- # When a key is present, _dedupe_duplicate_rows_in_da3_table uses its value
2738
- # as the cap instead of the default 2, preserving all text-layer-confirmed rows.
2739
  _tl_freq_context: dict = {}
2740
 
2741
  _DA3_LEADING_DATE = re.compile(r"^\d{1,2}/\d{1,2}(?:/\d{2,4})?$")
@@ -3714,6 +3717,10 @@ def stabilize_tables_and_text(page_md: str) -> str:
3714
  if not page_md:
3715
  return page_md
3716
 
 
 
 
 
3717
  page_md = normalize_money_glyphs(page_md)
3718
 
3719
  blocks = re.split(r"\n\s*\n", page_md.strip())
@@ -3829,6 +3836,8 @@ def run_ocr(uploaded_file):
3829
 
3830
  all_pages = []
3831
  for page_num, page_result in enumerate(results):
 
 
3832
  page_md, regions = get_page_md_and_regions(page_result)
3833
  img_h = page_heights[page_num] if page_num < len(page_heights) else 1000
3834
  header_end_frac, footer_start_frac = get_header_footer_zones(regions, img_h)
 
1102
  key = (_norm(r["date"]), _norm(r["desc"]), _norm(r["amount"]))
1103
  tl_freq[key] = tl_freq.get(key, 0) + 1
1104
 
1105
+ # Share with _dedupe_duplicate_rows_in_da3_table (Fix-20 override).
1106
+ # Keys MUST match _transaction_row_dedupe_key (date/desc/amount, no spaces in
1107
+ # date/desc; amount stripped of $/,/space). The injection map tl_freq uses
1108
+ # _norm() with spaces — different tuple shape — so we keep a parallel count.
1109
  global _tl_freq_context
1110
+ tl_dedupe = {}
1111
+ for r in tl_rows:
1112
+ dk = _transaction_row_dedupe_key([r["date"], r["desc"], r["amount"]])
1113
+ tl_dedupe[dk] = tl_dedupe.get(dk, 0) + 1
1114
+ _tl_freq_context = tl_dedupe
1115
 
1116
  table_pattern = re.compile(r"<table[^>]*>.*?</table>", re.DOTALL | re.IGNORECASE)
1117
  result = page_md
 
1286
 
1287
  except Exception as e:
1288
  log.warning("_patch_ocr_with_textlayer failed (page %d): %s", page_num, e)
 
 
 
1289
  _tl_freq_context.clear()
1290
+ return page_md
1291
 
1292
  # --------------------------
1293
  # Fix 5: Mid-table separator row reconstruction
 
2735
  _MSFT_PIN_G_REF = re.compile(r"MICROSOFT#(G\d{6,16})", re.IGNORECASE)
2736
 
2737
  # Module-level text-layer frequency context (Fix-20 override).
2738
+ # Set by _patch_ocr_with_textlayer; consumed by normalize_html_tables in run_ocr's
2739
+ # post-patch pass. Cleared at the start of stabilize_tables_and_text (new page)
2740
+ # and on patch failure so keys never bleed across pages.
2741
+ # Keys match _transaction_row_dedupe_key (not the _norm()-based tl_freq map).
 
2742
  _tl_freq_context: dict = {}
2743
 
2744
  _DA3_LEADING_DATE = re.compile(r"^\d{1,2}/\d{1,2}(?:/\d{2,4})?$")
 
3717
  if not page_md:
3718
  return page_md
3719
 
3720
+ # Fresh page: drop any text-layer dedupe caps so the first normalize pass
3721
+ # (before _patch_ocr_with_textlayer) does not see stale keys from a prior page.
3722
+ _tl_freq_context.clear()
3723
+
3724
  page_md = normalize_money_glyphs(page_md)
3725
 
3726
  blocks = re.split(r"\n\s*\n", page_md.strip())
 
3836
 
3837
  all_pages = []
3838
  for page_num, page_result in enumerate(results):
3839
+ # Header normalize runs before body patch; do not reuse prior page caps.
3840
+ _tl_freq_context.clear()
3841
  page_md, regions = get_page_md_and_regions(page_result)
3842
  img_h = page_heights[page_num] if page_num < len(page_heights) else 1000
3843
  header_end_frac, footer_start_frac = get_header_footer_zones(regions, img_h)