FEAT: Implement deceased/givenaway enclosure visibility rules, preserve external clan name, and hide receiver fields for deceased gerbils
This commit is contained in:
@@ -35,19 +35,20 @@ DEATH = re.compile(r"\+\s?(\d{1,2}\.\d{1,2}\.(?:\d{4}|\d{2})|\d{4})")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- helpers ----
|
||||
def gen_of(colnum):
|
||||
def gen_of(colnum, offset=0):
|
||||
"""Map a column number to a generation band (0=proband ... 5=deepest)."""
|
||||
if colnum <= 6:
|
||||
return 0 # E band (proband / "Kids")
|
||||
if colnum <= 9:
|
||||
return 1 # H band (parents)
|
||||
if colnum <= 12:
|
||||
return 2 # K band (grandparents)
|
||||
if colnum <= 15:
|
||||
return 3 # N band (great-grandparents)
|
||||
if colnum <= 17:
|
||||
return 4 # Q band (gg-grandparents)
|
||||
return 5 # R/S band (name-pairs)
|
||||
effective_col = colnum - offset
|
||||
if effective_col <= 3:
|
||||
return 0 # Column B (2) -> proband
|
||||
if effective_col <= 6:
|
||||
return 1 # Column E (5) -> parents
|
||||
if effective_col <= 9:
|
||||
return 2 # Column H (8) -> grandparents
|
||||
if effective_col <= 12:
|
||||
return 3 # Column K (11) -> great-grandparents
|
||||
if effective_col <= 15:
|
||||
return 4 # Column N (14) -> gg-grandparents
|
||||
return 5 # Column Q (17) or deeper -> ggg-grandparents
|
||||
|
||||
|
||||
def norm_name(name):
|
||||
@@ -189,6 +190,9 @@ def extract_stammbaum(path):
|
||||
cells = xu.read_cells(z, sheets[0], ss)
|
||||
fillsex = xu.cell_fill_sex(z, sheets[0]) # box colour -> sex (blue=male, white=female)
|
||||
|
||||
has_col2 = any(c == 2 for (c, r) in cells)
|
||||
col_offset = 0 if has_col2 else 3
|
||||
|
||||
# group cells by column for block reconstruction
|
||||
by_col = {}
|
||||
for (c, r), t in cells.items():
|
||||
@@ -230,7 +234,7 @@ def extract_stammbaum(path):
|
||||
# WITH a Farbschlag cell; deep bands (gen >= 2, cols K/N/Q...) are 3-cell blocks
|
||||
# (Name/DOB/Genotype) with NO Farbschlag — colour is derived from the genotype. So in
|
||||
# deep bands we must NOT grab the next block's name or a stray health note as Farbschlag.
|
||||
deep_band = gen_of(c) >= 2
|
||||
deep_band = gen_of(c, col_offset) >= 2
|
||||
for rr in range(r + 1, r + 4):
|
||||
cell = cells.get((c, rr))
|
||||
if not cell:
|
||||
@@ -269,7 +273,7 @@ def extract_stammbaum(path):
|
||||
"parentRefs": [],
|
||||
"photos": [],
|
||||
"sourceFiles": [fname],
|
||||
"_gen": gen_of(c),
|
||||
"_gen": gen_of(c, col_offset),
|
||||
"_col": c,
|
||||
"_row": r,
|
||||
"_file": fname,
|
||||
@@ -280,7 +284,7 @@ def extract_stammbaum(path):
|
||||
for (c, r), t in cells.items():
|
||||
if (c, r) in used:
|
||||
continue
|
||||
if " & " in t and not DOB.search(t) and len(t) < 90 and gen_of(c) >= 4:
|
||||
if " & " in t and not DOB.search(t) and len(t) < 90 and gen_of(c, col_offset) >= 4:
|
||||
for part in t.split(" & "):
|
||||
part = clean_name(part)
|
||||
if part:
|
||||
@@ -291,7 +295,7 @@ def extract_stammbaum(path):
|
||||
"genotype": gt.parse(""), "deaf": None, "tags": [],
|
||||
"breeder": "", "zucht": zraw,
|
||||
"parentRefs": [], "photos": [], "sourceFiles": [fname],
|
||||
"_gen": gen_of(c), "_col": c, "_row": r, "_file": fname,
|
||||
"_gen": gen_of(c, col_offset), "_col": c, "_row": r, "_file": fname,
|
||||
"_zucht": norm_zucht(zraw),
|
||||
})
|
||||
|
||||
@@ -337,8 +341,9 @@ def _attach_photos(z, sheets, animals, fname):
|
||||
for a in animals:
|
||||
by_gen.setdefault(a["_gen"], []).append(a)
|
||||
media_dir = os.path.join(OUT, "photos")
|
||||
col_offset = 0 if any(a["_col"] == 2 for a in animals) else 3
|
||||
for i, (sp, col, row, media) in enumerate(anchors):
|
||||
g = gen_of(col)
|
||||
g = gen_of(col, col_offset)
|
||||
cands = by_gen.get(g, [])
|
||||
if not cands:
|
||||
# fall back to nearest animal by row across all gens
|
||||
@@ -1026,6 +1031,9 @@ def main():
|
||||
print(f" {len(got):4d} {os.path.basename(path)}")
|
||||
raw_animals.extend(got)
|
||||
|
||||
# Skip pseudo-animal records (like "DD-Tumor bei Geschwister") that are actually notes
|
||||
raw_animals = [a for a in raw_animals if "DD-Tumor" not in a["name"]]
|
||||
|
||||
litters = []
|
||||
if os.path.isfile(args.wurfchronik):
|
||||
litters = extract_wurfchronik(args.wurfchronik)
|
||||
|
||||
Reference in New Issue
Block a user