rehan953 commited on
Commit
6e70285
·
verified ·
1 Parent(s): 1d3dd4c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +40 -19
app.py CHANGED
@@ -1140,18 +1140,37 @@ def _patch_ocr_with_textlayer(page_md: str, pdf_path: str, page_num: int) -> str
1140
  ocr_freq[key] = ocr_freq.get(key, 0) + 1
1141
  ocr_rows_indexed.append((ri, key))
1142
 
1143
- # Guard: overlap required
 
 
 
 
 
 
1144
  overlap = set(ocr_freq.keys()) & set(tl_freq.keys())
1145
- if not overlap:
1146
- continue
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1147
 
1148
  # Determine missing rows.
1149
  # Case A: row exists in OCR but count is too low (duplicate dropped)
1150
- # Case B: row exists in text layer but is completely absent from OCR
1151
- # (entire section dropped by OCR model, e.g. Capital One purchases)
1152
- # For Case B we build the row content from the text layer directly.
1153
- to_inject = {} # key -> count of missing copies
1154
- to_inject_new = {} # key -> row content for brand-new rows
1155
 
1156
  for key in tl_freq:
1157
  ocr_count = ocr_freq.get(key, 0)
@@ -1159,18 +1178,20 @@ def _patch_ocr_with_textlayer(page_md: str, pdf_path: str, page_num: int) -> str
1159
  if tl_count > ocr_count:
1160
  missing = tl_count - ocr_count
1161
  if ocr_count > 0:
1162
- # Case A: restore missing duplicates (existing row template)
1163
- to_inject[key] = missing
 
1164
  else:
1165
- # Case B: completely new row — build from text layer data
1166
- # Find the original text-layer row for this key
1167
- tl_row_data = next(
1168
- (r for r in tl_rows
1169
- if (_norm(r["date"]), _norm(r["desc"]), _norm(r["amount"])) == key),
1170
- None
1171
- )
1172
- if tl_row_data:
1173
- to_inject_new[key] = (missing, tl_row_data)
 
1174
 
1175
  if not to_inject and not to_inject_new:
1176
  continue
 
1140
  ocr_freq[key] = ocr_freq.get(key, 0) + 1
1141
  ocr_rows_indexed.append((ri, key))
1142
 
1143
+ # Guard: overlap check for Case A (duplicate restore).
1144
+ # For Case A we require at least one row in both OCR and text layer
1145
+ # to confirm we are patching the right table.
1146
+ # For Case B (entirely missing rows) we use a lighter structural check:
1147
+ # if the OCR table has DATE+DESCRIPTION+AMOUNT columns (already verified)
1148
+ # and the text layer date format matches the OCR date format,
1149
+ # we can safely inject — even when zero rows overlap.
1150
  overlap = set(ocr_freq.keys()) & set(tl_freq.keys())
1151
+
1152
+ # Detect date format used in OCR table (MM/DD vs MM-DD vs Mon DD)
1153
+ _ocr_dates = [
1154
+ _norm(str(row[date_col] or ""))
1155
+ for row in grid[1:]
1156
+ if len(row) > date_col and str(row[date_col] or "").strip()
1157
+ ]
1158
+ _tl_dates = [_norm(r["date"]) for r in tl_rows]
1159
+ _slash_re = re.compile(r"^\d{1,2}/\d{2}")
1160
+ _hyphen_re = re.compile(r"^\d{1,2}-\d{2}")
1161
+ def _date_fmt(dates):
1162
+ if any(_slash_re.match(d) for d in dates): return "slash"
1163
+ if any(_hyphen_re.match(d) for d in dates): return "hyphen"
1164
+ return "other"
1165
+ ocr_fmt = _date_fmt(_ocr_dates)
1166
+ tl_fmt = _date_fmt(_tl_dates)
1167
+ date_fmt_match = (ocr_fmt == tl_fmt) or "other" in (ocr_fmt, tl_fmt)
1168
 
1169
  # Determine missing rows.
1170
  # Case A: row exists in OCR but count is too low (duplicate dropped)
1171
+ # Case B: row exists in text layer but completely absent from OCR
1172
+ to_inject = {}
1173
+ to_inject_new = {}
 
 
1174
 
1175
  for key in tl_freq:
1176
  ocr_count = ocr_freq.get(key, 0)
 
1178
  if tl_count > ocr_count:
1179
  missing = tl_count - ocr_count
1180
  if ocr_count > 0:
1181
+ # Case A: restore duplicates requires overlap confirmation
1182
+ if overlap:
1183
+ to_inject[key] = missing
1184
  else:
1185
+ # Case B: entirely new row — requires date format match
1186
+ # (lighter guard: no overlap needed, just structural match)
1187
+ if date_fmt_match:
1188
+ tl_row_data = next(
1189
+ (r for r in tl_rows
1190
+ if (_norm(r["date"]), _norm(r["desc"]), _norm(r["amount"])) == key),
1191
+ None
1192
+ )
1193
+ if tl_row_data:
1194
+ to_inject_new[key] = (missing, tl_row_data)
1195
 
1196
  if not to_inject and not to_inject_new:
1197
  continue