feat(import): neue Stammbäume (12 Charts) + litterChildren.add + EMF-Fotos überspringen
Die Züchterin hat 24 neue/aktualisierte Stammbaum-xlsx geliefert (Ordner
"neuestammbäume"); sie liegen jetzt im kanonischen Quellverzeichnis
Sttammbäume (12 neue Charts, 7 aktualisierte, 3 identisch, das inhaltsgleiche
"Picus Son (2)" ausgelassen). Prod ist per Upload-Ingest aktualisiert:
2372 -> 2451 Tiere, 916 -> 965 Würfe, 432 -> 507 Fotos, 2198 -> 2275 Tiere
mit Geburtsdatum. Overrides/verified-Zeilen, manuelle Tiere und Tickets
haben den Ingest unverändert überlebt.
Zwei Datenfehler, die die neuen Charts aufgedeckt haben — datengetrieben und
re-ingest-stabil gefixt statt an der globalen Heuristik zu drehen:
- litterChildren kennt jetzt `add` [Name | {name, dob}] als Gegenstück zu
`keep`: hängt ein Jungtier an DIESEN Wurf und entfernt den alten Wurf, wenn
er dadurch kinderlos UND virtuell ist. Nötig, weil "Pukas Kids" Akanes
Eltern komplett UNTER ihren Block setzt (N80 Roni = Vater, N81 Fumi =
Mutter) — _reconstruct_parents griff eine Zeile zu hoch, paarte Irish
Coffee (Bonapartes Mutter) mit Roni und riss Akane aus dem Z21-Wurf in
einen Phantom-Wurf, der in der Wurfchronik auftauchte (Ticket 88389f8e).
- Merle: durch das neue Geburtsdatum (18.06.2023) mergt der addAnimals-Stub
in den Chart-Datensatz und verliert dabei sein isResident -> expliziter
resolutions-Override (Ticket 36a3fcde/a8f11ac0, Züchterin: Zuchttier).
Außerdem: Excel legt neben Fotos teils EMF/WMF-Vektorvorschauen ab, die
Browser nicht darstellen können (kaputte Bildkachel in der Tier-Akte) ->
extract._attach_photos überspringt .emf/.wmf (5 Fotos betroffen).
Regressionstests für alle drei Punkte; alle Python-Suites grün.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
10
CLAUDE.md
10
CLAUDE.md
@@ -299,6 +299,16 @@ python test_extract.py test_extract_docx.py test_genotype.py test_merge_resol
|
||||
werden aus dem Wurf gelöst (`LitterId=None`, Tier bleibt erhalten), optional `renameTo` setzt
|
||||
den kanonischen Wurf-Namen. Use-Case: Wurfchronik-Abnehmer-Sammelseiten, die fälschlich in einen
|
||||
datierten Buchstaben-Wurf gemergt wurden (Tickets 4b9f49fb M-Wurf, 8d259edf Gale).
|
||||
**`add`** [Name | {name, dob}] ist das Gegenstück (seit 2026-08-18): hängt ein Jungtier an
|
||||
**diesen** Wurf, wenn die Chart-Positions-Heuristik es in einen falschen **virtuellen**
|
||||
Stammbaum-Wurf gezogen hat; wird der alte Wurf dadurch kinderlos UND virtuell, entfernt der
|
||||
Importer ihn (sonst bliebe ein Phantom-Wurf in der Wurfchronik stehen). Use-Case Akane
|
||||
(Ticket 88389f8e): die neuen Stammbäume führen die Eltern eine Zeile unter dem Kind-Block
|
||||
(Vater N80/Mutter N81) — `_reconstruct_parents` greift dann eine Zeile zu hoch und paart die
|
||||
Mutter des Nachbar-Blocks mit dem echten Vater.
|
||||
- **EMF/WMF sind keine Fotos**: Excel legt neben dem Foto teils ein Vektor-Metafile ab; Browser
|
||||
können es nicht darstellen (kaputte Bildkachel in der Akte) → `extract._attach_photos`
|
||||
überspringt `.emf`/`.wmf` (Regressionstest in `test_extract.py`).
|
||||
- **`renameTo` ist eltern-verknüpfungssicher**: umbenannte Tiere werden im Eltern-Namensindex
|
||||
zusätzlich unter ihrem **Quell-Namen** (`_pre_rename_name`) geführt, sonst verlieren Würfe, die
|
||||
den alten Namen referenzieren, ihren Eltern-Link (Ticket e0a0c304 Kruke→Kuke). `dateOfDeath`
|
||||
|
||||
@@ -1318,6 +1318,13 @@
|
||||
],
|
||||
"decision": "Leeres Mino-Stub (ohne DOB) in vollständigen Mino mergen; L6-/X6-Wurf (Mino×Misaki) hängen dadurch am vollständigen Mino.",
|
||||
"source": "Ticket 44a9b677"
|
||||
},
|
||||
{
|
||||
"name": "Merle",
|
||||
"dob": "18.06.2023",
|
||||
"isResident": true,
|
||||
"decision": "Merle (Tochter Akane × Bonaparte, bei Clan of Black Forest geboren) ist Zuchttier. Das Geburtsdatum 18.06.2023 kommt aus „Stammbaum von Pukas Kids“ — seit der addAnimals-Stub mit dem Chart-Datensatz verschmilzt, braucht die Residenz einen expliziten Override (der isResident-Sweep würde sie sonst auf false setzen).",
|
||||
"source": "Ticket 36a3fcde + Ticket a8f11ac0 (Züchterin: Merle = Zuchttier)"
|
||||
}
|
||||
],
|
||||
"addAnimals": [
|
||||
@@ -2208,7 +2215,19 @@
|
||||
"Kai-Uwe"
|
||||
],
|
||||
"note": "Ticket 8d259edf: Gales (früher Drake Jr) Wurf hatte 9 fälschlich zugeordnete unbenannte Jungtiere. Wurfchronik: 3 überlebt = Pünktchen, Quebec, Kai-Uwe (aus Abgabeverträgen/Stammbaum bestätigt)."
|
||||
},
|
||||
{
|
||||
"date": "21.01.2023",
|
||||
"matchChild": "Anakoni",
|
||||
"add": [
|
||||
{
|
||||
"name": "Akane von den Kleinen Chaoten",
|
||||
"dob": "21.01.2023"
|
||||
}
|
||||
],
|
||||
"_doc_litterChildren": "litterChildren: autoritative Kinder-Whitelist eines Wurfs (Match date+matchChild). Kinder außerhalb keep werden aus dem Wurf gelöst (LitterId=None); optional renameTo. Für Über-Merges von Abnehmer-Sammelseiten."
|
||||
"note": "Akane ist laut Wurfchronik ein Z21-Jungtier (Roni × Fumi). Die neuen Stammbäume (Pukas Kids / Sa Sp (YaraFire) & Sa Kids) führen Akanes Eltern in Spalte N direkt UNTER ihrem Block (N80 Roni = Vater, N81 Fumi = Mutter); die Positions-Heuristik griff eine Zeile zu hoch und paarte Irish Coffee (Bonapartes Mutter) mit Roni — dadurch entstand ein Phantom-Wurf vom 21.01.2023 in der Wurfchronik.",
|
||||
"source": "Züchterin 2026-06-22 — Ticket 88389f8e (Roni=Vater, Fumi=Mutter) + Chart „Stammbaum von Pukas Kids“"
|
||||
}
|
||||
],
|
||||
"_doc_litterChildren": "litterChildren: autoritative Kinder-Whitelist eines Wurfs (Match date+matchChild). Kinder außerhalb keep werden aus dem Wurf gelöst (LitterId=None); optional renameTo. Für Über-Merges von Abnehmer-Sammelseiten. Optional add [Name | {name, dob}]: hängt ein Jungtier an DIESEN Wurf (Gegenstück zu keep) — für Jungtiere, die die Chart-Positions-Heuristik in einen falschen virtuellen Stammbaum-Wurf gezogen hat; wird der alte Wurf dadurch kinderlos UND virtuell, entfernt der Importer ihn (kein Phantom-Wurf in der Wurfchronik)."
|
||||
}
|
||||
@@ -444,6 +444,11 @@ def _attach_photos(z, sheets, animals, fname):
|
||||
if not target:
|
||||
continue
|
||||
ext = os.path.splitext(media)[1] or ".img"
|
||||
# Excel legt neben dem echten Foto teils ein Vektor-Metafile (EMF/WMF) als
|
||||
# Vorschau ab. Browser können das NICHT darstellen → es landete als kaputte
|
||||
# Bildkachel in der Tier-Akte. Solche Anhänge sind keine Fotos → überspringen.
|
||||
if ext.lower() in (".emf", ".wmf"):
|
||||
continue
|
||||
sl = slug(target["name"], target["dob"])
|
||||
dest_dir = os.path.join(media_dir, sl)
|
||||
os.makedirs(dest_dir, exist_ok=True)
|
||||
|
||||
@@ -4166,17 +4166,45 @@ def main():
|
||||
# Würfe). Alle Kinder, deren Ruf-Name NICHT in `keep` steht, werden aus dem Wurf gelöst
|
||||
# (LitterId=None) — sie verschwinden aus dem Wurf, bleiben aber als Tier erhalten. Optional
|
||||
# `renameTo` setzt den kanonischen Wurf-Namen (z. B. 'Ungeklärt' -> 'M-Wurf').
|
||||
# Optional `add` [Name | {name, dob}] hängt ein Jungtier an DIESEN Wurf (Gegenstück zu `keep`):
|
||||
# nötig, wenn die Chart-Positions-Heuristik ein Jungtier in einen falschen (virtuellen)
|
||||
# Stammbaum-Wurf gezogen hat, obwohl die Wurfchronik es einem echten Wurf zuordnet
|
||||
# (Ticket 36a3fcde/88389f8e: Akane gehört in den Z21-Wurf Roni × Fumi). Der vorherige Wurf
|
||||
# wird entfernt, wenn er dadurch ein kinderloser VIRTUELLER Wurf wird — sonst blieben
|
||||
# Phantom-Würfe in der Wurfchronik stehen.
|
||||
try:
|
||||
with open(CONFLICT_DECISIONS_PATH, encoding="utf-8") as _lcfh:
|
||||
_litter_children = (json.load(_lcfh).get("litterChildren") or [])
|
||||
except Exception:
|
||||
_litter_children = []
|
||||
|
||||
def _drop_if_empty_virtual(litter_id):
|
||||
"""Entfernt einen VIRTUELLEN Wurf, der kein Jungtier mehr hat (Phantom-Wurf aus der
|
||||
Chart-Positions-Heuristik). Echte Wurfchronik-Würfe bleiben immer erhalten — die haben
|
||||
legitim keine namentlich erfassten Jungtiere."""
|
||||
if not litter_id:
|
||||
return 0
|
||||
if any(g.get("LitterId") == litter_id for g in resolved_gerbils):
|
||||
return 0
|
||||
for i, cand in enumerate(resolved_litters):
|
||||
if cand["Id"] != litter_id:
|
||||
continue
|
||||
ext = cand.get("ExternalRef") or ""
|
||||
if cand.get("_virtual") or "-virtual-" in ext or ext.startswith("override-virtual-litter"):
|
||||
del resolved_litters[i]
|
||||
return 1
|
||||
return 0
|
||||
return 0
|
||||
|
||||
_lc_removed = 0
|
||||
_lc_added = 0
|
||||
_lc_dropped = 0
|
||||
for lc in _litter_children:
|
||||
lc_date = parse_date(lc["date"]) if lc.get("date") else None
|
||||
match_child = normalize_name(get_call_name(lc.get("matchChild") or ""))
|
||||
keep = {normalize_name(get_call_name(n)) for n in (lc.get("keep") or [])}
|
||||
if not keep:
|
||||
add = lc.get("add") or []
|
||||
if not keep and not add:
|
||||
continue
|
||||
for l in resolved_litters:
|
||||
if lc_date and l.get("Date") != lc_date:
|
||||
@@ -4185,15 +4213,29 @@ def main():
|
||||
names = {normalize_name(get_call_name(g.get("Name") or "")) for g in kids}
|
||||
if match_child and match_child not in names:
|
||||
continue # falscher, nur zufällig gleich-datierter Wurf
|
||||
if keep:
|
||||
for g in kids:
|
||||
if normalize_name(get_call_name(g.get("Name") or "")) not in keep:
|
||||
g["LitterId"] = None
|
||||
_lc_removed += 1
|
||||
for entry in add:
|
||||
a_name = entry.get("name") if isinstance(entry, dict) else entry
|
||||
a_dob = entry.get("dob") if isinstance(entry, dict) else None
|
||||
child = _find_final_gerbil(a_name, a_dob)
|
||||
if not child or child.get("LitterId") == l["Id"]:
|
||||
continue
|
||||
prev_litter_id = child.get("LitterId")
|
||||
child["LitterId"] = l["Id"]
|
||||
_lc_added += 1
|
||||
_lc_dropped += _drop_if_empty_virtual(prev_litter_id)
|
||||
if lc.get("renameTo"):
|
||||
l["Name"] = lc["renameTo"]
|
||||
break
|
||||
if _lc_removed:
|
||||
print(f"litterChildren: {_lc_removed} fälschlich zugeordnete Jungtiere aus Würfen gelöst")
|
||||
if _lc_added:
|
||||
print(f"litterChildren: {_lc_added} Jungtier(e) dem korrekten Wurf zugeordnet "
|
||||
f"({_lc_dropped} leerer Phantom-Wurf/Würfe entfernt)")
|
||||
|
||||
# ── isResident-Sweep (Ticket 381f7e51, freigegeben) ───────────────────────
|
||||
# Entscheidung der Züchterin: „Nimm wirklich ALLE Tiere aus dem Bestand heraus,
|
||||
|
||||
@@ -4,15 +4,15 @@ _Automatisch erzeugt von `tools/import/extract.py` — **noch nichts in die Date
|
||||
|
||||
## Überblick
|
||||
|
||||
- Rohe Tier-Einträge aus den Stammbäumen: **2548**
|
||||
- Nach Zusammenführung (eindeutige Tiere): **1042**
|
||||
- davon mit Geburtsdatum: 684
|
||||
- in mehreren Dateien gefunden (Dubletten zusammengeführt): 477
|
||||
- Konflikte zur Klärung: **8**
|
||||
- Mehrdeutige / unvollständige Einträge (ohne Name+Datum): **379**
|
||||
- Fotos zugeordnet: **435**
|
||||
- Rohe Tier-Einträge aus den Stammbäumen: **3600**
|
||||
- Nach Zusammenführung (eindeutige Tiere): **1487**
|
||||
- davon mit Geburtsdatum: 771
|
||||
- in mehreren Dateien gefunden (Dubletten zusammengeführt): 545
|
||||
- Konflikte zur Klärung: **20**
|
||||
- Mehrdeutige / unvollständige Einträge (ohne Name+Datum): **757**
|
||||
- Fotos zugeordnet: **510**
|
||||
- Würfe aus der Wurfchronik: **752**
|
||||
- Tiere mit Wurf verknüpft: **271** (davon über Geburtsdatum **und** Eltern: 174, nur über Geburtsdatum: 97; mehrdeutig: 16)
|
||||
- Tiere mit Wurf verknüpft: **292** (davon über Geburtsdatum **und** Eltern: 188, nur über Geburtsdatum: 104; mehrdeutig: 18)
|
||||
- Würfe mit Datenqualitäts-Hinweisen: 113 (+ 138 Zeilen mit abweichendem Spaltenschema)
|
||||
|
||||
## Zusammenführungs-Schlüssel
|
||||
@@ -24,6 +24,7 @@ Tiere wurden zusammengeführt über **normalisierter Rufname + Geburtsdatum**, m
|
||||
| Tier | Geburtsdatum | Zuchten | Dateien |
|
||||
|---|---|---|---|
|
||||
| Blacky | 23.07.2009 | PZ Seligenstadt // Privatzucht Seligenstadt | Stammbaum von Danako, Stammbaum von Hana, Stammbaum von Jin, Stammbaum von Unit, Stammbaum von Uriana, Stammbaum von Wildfire und Vestras Kids |
|
||||
| Dark Henry | 10.07.2022 | Kleinen Chaoten (extern) // Zucht der Kleinen Chaoten (extern SC) | Stammbaum von Fire Kids, Stammbaum von Kids von dd Algierfuchs & Sa, Stammbaum von Sa Sp (YaraFire) & Sa Kids, Stammbaum von Valentino Firehearts Kids |
|
||||
| Danny | 09.10.2009 | Maintaler PZ // PZ Maintal | Stammbaum von Hana, Stammbaum von Vance |
|
||||
| Lola | 10.02.2014 | Chalfont Stud, Freddy Braun // Lennylengo | Stammbaum von Jeremy, Stammbaum von Jiminy of Black Forest, Stammbaum von Marlin of Black Forest, Stammbaum von Zac (Vance.Dorie), Stammbaum von Zenon von Elea |
|
||||
| Debby gen. Eva | 08.08.2012 | KK Chaos // KK Chaos of KK Chaos | Stammbaum von Kalea, Stammbaum von Unit, Stammbaum von Uriana |
|
||||
@@ -34,18 +35,30 @@ Gleiches Tier (Name+Datum), aber widersprüchliche Angaben in verschiedenen Date
|
||||
|
||||
| Tier | Geburtsdatum | abweichende Genotypen | abweichende Farbschläge | Sterbedaten | Dateien |
|
||||
|---|---|---|---|---|---|
|
||||
| Ella | 10.06.2019 | Aa C D- ee[f] GG P- spsp // Aa Cc[chm] D- ee[f] GG P- spsp // Aa Cc[chm] D- ee[f] UwUw P- spsp | Algierfuchsschimmel, hell | 03.02.2023 // 31.01.2023 | Stammbaum von Akio Kids, Stammbaum von CP-Fuchs, CP-Sa Sp von Unity, Stammbaum von Ella, Stammbaum von Picus Son, Stammbaum von Valentino Firehearts Kids |
|
||||
| Lui von den Kleinen Chaoten | 16.04.2021 | Aa Cc[chm] DD ee[f] Gg PP Spsp // Aa c[chm]c[chm] D- Ee[f] Gg PP spsp | — | 15.12.2020 | Stammbaum von Alberto Kids, Stammbaum von Picus Son |
|
||||
| Osamu | 10.12.2015 | AA CC DD ee gg P- spsp // AA CC DD ee gg PP spsp // AA CC DD ee uw[d]uw[d] PP spsp | — | 01.10.2020 // 18.12.2020 | Stammbaum von Danako, Stammbaum von Ella, Stammbaum von Jin, Stammbaum von Kazuya, Stammbaum von Kentucky, Stammbaum von Martin, Stammbaum von Picus Son, Stammbaum von Rainny, Stammbaum von Ren, Stammbaum von South Dakota, Stammbaum von Stella Kids, Stammbaum von Tennessee, Stammbaum von Zenon von Elea |
|
||||
| Ella | 10.06.2019 | Aa C D- ee[f] GG P- spsp // Aa C D- ee[f] GG PP spsp // Aa Cc[chm] D- ee[f] GG P- spsp // Aa Cc[chm] D- ee[f] UwUw P- spsp | Algierfuchsschimmel, hell | 03.02.2023 // 31.01.2023 | Stammbaum von Akio Kids, Stammbaum von Blitzis Kids, Stammbaum von CP Mädels von Grisu, Stammbaum von CP-Fuchs, CP-Sa Sp von Unity, Stammbaum von CP-Polarfuchs von Grisu, Stammbaum von Ella, Stammbaum von Picus Son, Stammbaum von Sa von Johnny Kids, Stammbaum von Valentino Firehearts Kids |
|
||||
| Fatou gen. Sam von den Kleinen Chaoten | 03.02.2020 | aa Cc[chm] DD Ee gg Pp spsp // aa c[chm]c[h] D- Ee GG P- Spsp | — | 19.03.2022 | Stammbaum von Akio Kids, Stammbaum von CP-Fuchs, CP-Sa Sp von Unity, Stammbaum von Kid von Cassy & Blaster, Stammbaum von Pukas Kids, Stammbaum von Sa Sp (YaraFire) & Sa Kids |
|
||||
| Charly of Golden Lights | 05.04.2016 | aa c[chm]c[chm] D- Ee Gg P- Spsp // aa c[chm]c[chm] DD Ee GG P- Spsp | — | — | Stammbaum von Akio Kids, Stammbaum von Kid von Cassy & Blaster |
|
||||
| Xtra Bounty von den Schlossmäusen | 20.03.2014 | aa c[h]c[h] DD Ee Gg PP spsp // aa c[h]c[h] DD Ee gg PP spsp | — | 01.05.2018 | Stammbaum von Akio Kids, Stammbaum von Kid von Cassy & Blaster |
|
||||
| Jay | 24.10.2021 | aa c[chm]c[hm] Dd Ee gg P- spsp | Zobel | 10.01.2024 // 10.01.2025 | Stammbaum von Alberto Kids, Stammbaum von Pukas Kids |
|
||||
| Inochi gen. Picu von den Kleinen Chaoten | 11.07.2020 | Aa CC dd Ee GG Pp spsp // Aa CC dd Ee Gg Pp spsp | Dilute Agouti | 11.03.2025 // 12.03.2025 | Stammbaum von Alberto Kids, Stammbaum von Kids von dd Algierfuchs & Sa, Stammbaum von Picus Son, Stammbaum von Rj |
|
||||
| Snickers of Black Forest | 21.09.2018 | Aa Cc[chm] dd Ee Gg P- spsp // Aa Cc[chm] dd Ee gg Pp Spsp | — | 04.04.2023 // 04.11.2022 | Stammbaum von Alberto Kids, Stammbaum von CP Mädels von Grisu, Stammbaum von CP-Polarfuchs von Grisu, Stammbaum von Jiminy of Black Forest, Stammbaum von Kid von Cassy & Blaster, Stammbaum von Kids von dd Algierfuchs & Sa, Stammbaum von Picus Son, Stammbaum von Pukas Kids, Stammbaum von Rj, Stammbaum von Sa Sp (YaraFire) & Sa Kids, Stammbaum von Stella Kids |
|
||||
| Lui von den Kleinen Chaoten | 16.04.2021 | Aa Cc[chm] DD ee[f] Gg PP Spsp // Aa c[chm]c[chm] D- Ee[f] Gg PP spsp | — | 15.12.2020 | Stammbaum von Alberto Kids, Stammbaum von Blitzis Kids, Stammbaum von Kids von dd Algierfuchs & Sa, Stammbaum von Picus Son, Stammbaum von Rj |
|
||||
| Odette von den Kleinen Chaoten | 22.02.2021 | 2, AA c[chm]c[chm] DD Ee Gg PP Spsp // AA c[chm]c[chm] DD Ee Gg Pp Spsp DP | — | 30.02.2020 // 30.12.2024 | Stammbaum von Blitzis Kids |
|
||||
| Marlin of Black Forest | 28.05.2019 | Aa C- DD Ee Gg Pp spsp // Aa Cc[chm] DD Ee Gg Pp Spsp // Aa Cc[chm] DD Ee Gg Pp spsp | Agouti | 18.11.2023 | Stammbaum von Blitzis Kids, Stammbaum von Fire Kids, Stammbaum von Kids von dd Algierfuchs & Sa, Stammbaum von Marlin of Black Forest, Stammbaum von Sa Sp (YaraFire) & Sa Kids, Stammbaum von Valentino Firehearts Kids |
|
||||
| Louis of Black Forest | 22.08.2019 | Aa CC dd EE Gg P- spsp | — | 09.04.2024 // 10.04.2024 | Stammbaum von CP Mädels von Grisu, Stammbaum von CP-Polarfuchs von Grisu, Stammbaum von Kid von Cassy & Blaster, Stammbaum von Kids von dd Algierfuchs & Sa, Stammbaum von Rj, Stammbaum von Sa Sp (YaraFire) & Sa Kids |
|
||||
| Osamu | 10.12.2015 | AA CC DD ee gg P- spsp // AA CC DD ee gg PP spsp // AA CC DD ee uw[d]uw[d] PP spsp | — | 01.10.2020 // 18.12.2020 | Stammbaum von Danako, Stammbaum von Ella, Stammbaum von Jin, Stammbaum von Kazuya, Stammbaum von Kentucky, Stammbaum von Kid von Cassy & Blaster, Stammbaum von Martin, Stammbaum von Picus Son, Stammbaum von Rainny, Stammbaum von Ren, Stammbaum von Rj, Stammbaum von South Dakota, Stammbaum von Stella Kids, Stammbaum von Tennessee, Stammbaum von Zenon von Elea |
|
||||
| Taro von den kleinen Chaoten | 01.09.2012 | Aa Cc[chm] D- Ee Gg Pp spsp // aa Cc[chm] DD EE GG PP spsp | — | 01.10.2015 // 21.09.2012 | Stammbaum von Danako, Stammbaum von Kalea |
|
||||
| Quebec v.d. Kleinen Chaoten | 21.06.2014 | aa Cc[chm] dd Ee Gg Pp spsp // aa Cc[chm] dd Ee Uwuw[d] Pp spsp // aa Cc[chm] dd Ee gg Pp spsp | — | 21.10.2016 | Stammbaum von Ella, Stammbaum von Jin, Stammbaum von Kazuya, Stammbaum von Martin, Stammbaum von Picus Son, Stammbaum von Rainny, Stammbaum von Ren, Stammbaum von South Dakota, Stammbaum von Tennessee, Stammbaum von Zenon von Elea |
|
||||
| | 20.04.2024 | Aa C- dd Ee Gg P- Spsp | Dilute Agouti Kragenschecke // Dilute Kohlfuchs Kragenschecke DP | — | Stammbaum von Fire Kids, Stammbaum von Stella Kids |
|
||||
| Hanami | 10.09.2015 | aa Cc[chm] D- Ee gg P- spsp // aa Cc[chm] D- Ee uw[d]uw[d] P- spsp | — | 02.01.2020 // 12.12.2019 // 14.01.2020 | Stammbaum von Hana, Stammbaum von Kentucky, Stammbaum von Rainny, Stammbaum von Ren, Stammbaum von Stella Kids, Stammbaum von Vance, Stammbaum von Zac (Vance.Dorie) |
|
||||
| | 13.08.2025 | Aa C- D- ee[f] G(G) pp Spsp // aa Cc[chm] D- ee[f] Gg Pp Spsp | Goldfuchsschimmel Kragenschecke // Kohlfuchsschimmel, hell | — | Stammbaum von Kohlief, Goldfuchsef Sp von Chrissi, Stammbaum von Watarus Kids |
|
||||
| Little Runner's Destiny | 02.03.2019 | aa Cc[chm] DD ee Gg PP Spsp // aa Cc[chm] DD ee Gg Pp Spsp | — | — | Stammbaum von Goldfuchs Sp DP, Stammbaum von Kohlief, Goldfuchsef Sp von Chrissi, Stammbaum von Sa von Johnny Kids |
|
||||
| | 01.08.2025 | AA CC DD EE gg PP spsp // Aa Cc[chm] D- Ee gg P- Spsp | Silberagouti // Silberagouti Punktschecke | — | Stammbaum von Kids von dd Algierfuchs & Sa, Stammbaum von Sa Sp (YaraFire) & Sa Kids |
|
||||
| | 26.02.2026 | Aa C-D- Ee[-] Gg pp spsp // Aa C-D- Ee[-] gg P- spsp // Aa C-D- ee[-] Gg P- spsp | Algierfuchs // Gold // Silberagouti | — | Stammbaum von Kohlief und Johnny Jumper Kids, Stammbaum von Sa von Johnny Kids |
|
||||
| | 13.08.2025 | Aa C- D- ee[f] G(G) pp Spsp // aa Cc[chm] D- ee[f] Gg Pp Spsp | Goldfuchsschimmel Kragenschecke // Kohlfuchsschimmel, hell | — | Stammbaum von Kohlief und Johnny Jumper Kids, Stammbaum von Kohlief, Goldfuchsef Sp von Chrissi, Stammbaum von Watarus Kids |
|
||||
| Gold Sp (RV) | 16.01.2023 | Aa CC D- Ee Gg pp Spsp [DP] // aa c[chm]c[chm] D- EE GG P- Spsp | — | — | Stammbaum von Kohlief und Johnny Jumper Kids, Stammbaum von Sa von Johnny Kids |
|
||||
|
||||
## Mehrdeutige / unvollständige Einträge
|
||||
|
||||
379 Einträge ohne sichere Name+Datum-Kombination (z. B. `Name1 & Name2`-Paarzellen der tiefsten Generation, oder Zellen ohne Datum). Diese werden NICHT automatisch zusammengeführt.
|
||||
757 Einträge ohne sichere Name+Datum-Kombination (z. B. `Name1 & Name2`-Paarzellen der tiefsten Generation, oder Zellen ohne Datum). Diese werden NICHT automatisch zusammengeführt.
|
||||
|
||||
- Oskar v.d. bunten Fellnase · Stammbaum von Akio Kids.xlsx
|
||||
- Raya v.d. bunten Fellnasen · Stammbaum von Akio Kids.xlsx
|
||||
@@ -69,14 +82,6 @@ Gleiches Tier (Name+Datum), aber widersprüchliche Angaben in verschiedenen Date
|
||||
- Katara · Stammbaum von Akio Kids.xlsx
|
||||
- Jack Jr. · Stammbaum von Akio Kids.xlsx
|
||||
- Nala · Stammbaum von Akio Kids.xlsx
|
||||
- Brandon Stark · Stammbaum von Akio Kids.xlsx
|
||||
- Enya · Stammbaum von Akio Kids.xlsx
|
||||
- Oscar of Black Forest · Stammbaum von Akio Kids.xlsx
|
||||
- Naho · Stammbaum von Akio Kids.xlsx
|
||||
- Hagrid Rubeus of Black Forest · Stammbaum von Akio Kids.xlsx
|
||||
- Lilo of LennyLengo · Stammbaum von Akio Kids.xlsx
|
||||
- Kazuya · Stammbaum von Akio Kids.xlsx
|
||||
- Rainny · Stammbaum von Akio Kids.xlsx
|
||||
- Eddward · Stammbaum von Akio Kids.xlsx
|
||||
- Harumi · Stammbaum von Akio Kids.xlsx
|
||||
- Marc Sloan · Stammbaum von Akio Kids.xlsx
|
||||
@@ -87,10 +92,18 @@ Gleiches Tier (Name+Datum), aber widersprüchliche Angaben in verschiedenen Date
|
||||
- Isa of Golden Lights · Stammbaum von Akio Kids.xlsx
|
||||
- Mystique of Black Forest · Stammbaum von Alberto Kids.xlsx
|
||||
- Verpaarung von Fleur · Stammbaum von Alberto Kids.xlsx
|
||||
- Pinto (RV) · Stammbaum von Alberto Kids.xlsx
|
||||
- Verpaarung von Hanami · Stammbaum von Alberto Kids.xlsx
|
||||
- Robb Stark · Stammbaum von Alberto Kids.xlsx
|
||||
- Verpaarung von Isabel · Stammbaum von Alberto Kids.xlsx
|
||||
- Tyrion Lannister · Stammbaum von Alberto Kids.xlsx
|
||||
- Verpaarung von Fleur · Stammbaum von Alberto Kids.xlsx
|
||||
- Pinto (RV) · Stammbaum von Alberto Kids.xlsx
|
||||
- Verpaarung von Nala (Exidra) · Stammbaum von Alberto Kids.xlsx
|
||||
|
||||
## Wahrscheinliche Zuordnungen unvollständiger Einträge
|
||||
|
||||
98 namenlose/datenlose Einträge tragen denselben Namen wie ein vollständiges Tier — vermutlich dasselbe Tier (zur Bestätigung):
|
||||
245 namenlose/datenlose Einträge tragen denselben Namen wie ein vollständiges Tier — vermutlich dasselbe Tier (zur Bestätigung):
|
||||
|
||||
- „Tai of Lennylengo“ → Tai of Lennylengo (*01.10.2011)
|
||||
- „Arrow PZ Niederlande“ → Arrow PZ Niederlande (*20.05.2014)
|
||||
@@ -98,9 +111,6 @@ Gleiches Tier (Name+Datum), aber widersprüchliche Angaben in verschiedenen Date
|
||||
- „Leila v. Jessica Walldorf“ → Leila v. Jessica Walldorf (*08.04.2014)
|
||||
- „Osamu“ → Osamu (*10.12.2015)
|
||||
- „Nala“ → Nala (*06.03.2015)
|
||||
- „Oscar of Black Forest“ → Oscar of Black Forest (*12.06.2019)
|
||||
- „Hagrid Rubeus of Black Forest“ → Hagrid Rubeus of Black Forest (*18.07.2019)
|
||||
- „Lilo of LennyLengo“ → Lilo of LennyLengo (*04.11.2018)
|
||||
- „Harumi“ → Harumi (*21.02.2015)
|
||||
- „Pan“ → Pan (*09.12.2014)
|
||||
- „Gin“ → Gin (*05.02.2015)
|
||||
@@ -109,6 +119,41 @@ Gleiches Tier (Name+Datum), aber widersprüchliche Angaben in verschiedenen Date
|
||||
- „Elay“ → Elay (*16.03.2016)
|
||||
- „Osamu“ → Osamu (*10.12.2015)
|
||||
- „Baiko“ → Baiko (*02.06.2019)
|
||||
- „Raya von den bunten Fellnasen“ → Raya von den bunten Fellnasen (*02.02.2013)
|
||||
- „Raya von den bunten Fellnasen“ → Raya von den bunten Fellnasen (*02.02.2013)
|
||||
- „Hanse Renner's Poseidon“ → Hanse Renner's Poseidon (*14.08.2014)
|
||||
- „Yuki“ → Yuki (*02.07.2023); Yuki (*02.09.2019); Yuki (*10.07.2022)
|
||||
- „Hagrid Rubeus of Black Forest“ → Hagrid Rubeus of Black Forest (*18.07.2019)
|
||||
- „Osamu“ → Osamu (*10.12.2015)
|
||||
- „Umi“ → Umi (*13.08.2016)
|
||||
- „Chevrolet Camaro of Topolino“ → Chevrolet Camaro of Topolino (*10.04.2018)
|
||||
- „Stich von Privatzucht Gießen“ → Stich von Privatzucht Gießen (*01.09.2018)
|
||||
- „Lilo of LennyLengo“ → Lilo of LennyLengo (*04.11.2018)
|
||||
- „Baiko“ → Baiko (*02.06.2019)
|
||||
- „Blue Wave of Fiomi“ → Blue Wave of Fiomi (*22.09.2018)
|
||||
- „Giulietta gen. Gulie of Black Forest“ → Giulietta gen. Gulie of Black Forest (*30.01.2020)
|
||||
- „Pinto of Fiomi“ → Pinto of Fiomi (*28.08.2016)
|
||||
- „Yurika“ → Yurika (*27.11.2017)
|
||||
- „Hagrid Rubeus of Black Forest“ → Hagrid Rubeus of Black Forest (*18.07.2019)
|
||||
- „Lilo of LennyLengo“ → Lilo of LennyLengo (*04.11.2018)
|
||||
- „Nala“ → Nala (*06.03.2015)
|
||||
- „Osamu“ → Osamu (*10.12.2015)
|
||||
- „Umi“ → Umi (*13.08.2016)
|
||||
- „Pauline von den Schlossmäusen“ → Pauline von den Schlossmäusen (*31.07.2018)
|
||||
- „Pinto of Fiomi“ → Pinto of Fiomi (*28.08.2016)
|
||||
- „Osamu“ → Osamu (*10.12.2015)
|
||||
- „Umi“ → Umi (*13.08.2016)
|
||||
- „Stich von Privatzucht Gießen“ → Stich von Privatzucht Gießen (*01.09.2018)
|
||||
- „Lilo of LennyLengo“ → Lilo of LennyLengo (*04.11.2018)
|
||||
- „Osamu“ → Osamu (*10.12.2015)
|
||||
- „Umi“ → Umi (*13.08.2016)
|
||||
- „Dorie of Black Forest“ → Dorie of Black Forest (*28.05.2019)
|
||||
- „Zadar from Zeko i ptica, Croatia“ → Zadar from Zeko i ptica, Croatia (*12.04.2019)
|
||||
- „Hana“ → Hana (*14.10.2018)
|
||||
- „Living Force's Idefix“ → Living Force's Idefix (*05.04.2016)
|
||||
- „Rosie of LennyLengo“ → Rosie of LennyLengo (*15.03.2016)
|
||||
- „Living Force's Idefix“ → Living Force's Idefix (*05.04.2016)
|
||||
- „Rosie of LennyLengo“ → Rosie of LennyLengo (*15.03.2016)
|
||||
- „Hagrid Rubeus of Black Forest“ → Hagrid Rubeus of Black Forest (*18.07.2019)
|
||||
- „Osamu“ → Osamu (*10.12.2015)
|
||||
- „Umi“ → Umi (*13.08.2016)
|
||||
@@ -119,39 +164,7 @@ Gleiches Tier (Name+Datum), aber widersprüchliche Angaben in verschiedenen Date
|
||||
- „Gin“ → Gin (*05.02.2015)
|
||||
- „Isa of golden lights“ → Isa of Golden Lights (*24.12.2014)
|
||||
- „Porter“ → Porter (*23.05.2015)
|
||||
- „Chelsea von den Kleinen Chaoten“ → Chelsea von den Kleinen Chaoten (*02.04.2021)
|
||||
- „Pinto of Fiomi“ → Pinto of Fiomi (*28.08.2016)
|
||||
- „Nala“ → Nala (*06.03.2015)
|
||||
- „Hanami“ → Hanami (*10.09.2015)
|
||||
- „Living Force's Idefix“ → Living Force's Idefix (*05.04.2016)
|
||||
- „Osamu“ → Osamu (*10.12.2015)
|
||||
- „Baiko“ → Baiko (*02.06.2019)
|
||||
- „Olivia“ → Olivia (*23.07.2019)
|
||||
- „Baiko“ → Baiko (*02.06.2019)
|
||||
- „Olivia“ → Olivia (*23.07.2019)
|
||||
- „Living Force's Idefix“ → Living Force's Idefix (*05.04.2016)
|
||||
- „Rosie of LennyLengo“ → Rosie of LennyLengo (*15.03.2016)
|
||||
- „Pan“ → Pan (*09.12.2014)
|
||||
- „Gin“ → Gin (*05.02.2015)
|
||||
- „Chiako“ → Chiako (*15.11.2016)
|
||||
- „Stich von Privatzucht Gießen“ → Stich von Privatzucht Gießen (*01.09.2018)
|
||||
- „Lilo of LennyLengo“ → Lilo of LennyLengo (*04.11.2018)
|
||||
- „Ken'ichi“ → Ken'ichi (*01.03.2015)
|
||||
- „Rumi“ → Rumi (*24.02.2017)
|
||||
- „Living Force's Idefix“ → Living Force's Idefix (*05.04.2016)
|
||||
- „Rosie of LennyLengo“ → Rosie of LennyLengo (*15.03.2016)
|
||||
- „Living Force's Idefix“ → Living Force's Idefix (*05.04.2016)
|
||||
- „Rosie of LennyLengo“ → Rosie of LennyLengo (*15.03.2016)
|
||||
- „Inusch of Black Forest“ → Inusch of Black Forest (*25.10.2017)
|
||||
- „Little Hero of Black Forest“ → Little Hero of Black Forest (*22.02.2018)
|
||||
- „Little Runner's Destiny“ → Little Runner's Destiny (*02.03.2019)
|
||||
- „Chevrolet Camaro of Topolino“ → Chevrolet Camaro of Topolino (*10.04.2018)
|
||||
- „Danako“ → Danako (*22.08.2018)
|
||||
- „Marlin of Black Forest“ → Marlin of Black Forest (*28.05.2019)
|
||||
- „Zenon von Elea“ → Zenon von Elea (*06.10.2019)
|
||||
- „Nisha of Black Forest“ → Nisha of Black Forest (*28.03.2018)
|
||||
- „Zenon von Elea“ → Zenon von Elea (*06.10.2019)
|
||||
- „Nisha of Black Forest“ → Nisha of Black Forest (*28.03.2018)
|
||||
|
||||
## Nicht ins 8-Loci-Modell abgebildete Tokens (verbatim erhalten)
|
||||
|
||||
@@ -169,6 +182,8 @@ Diese Tokens stehen weiter in `rawGenotype`/`unmappedTokens` — Entscheidung (M
|
||||
| `!` | 2 | ? |
|
||||
| `C(C)` | 2 | Schreibweise (C trägt c) |
|
||||
| `/18.02.2020` | 2 | ? |
|
||||
| `chmchm` | 2 | Schreibweise (c[chm]c[chm]) |
|
||||
| `C-D-` | 2 | ? |
|
||||
| `(KW` | 2 | ? |
|
||||
| `[WFNZ-Maroon]` | 1 | ? |
|
||||
| `[meliert]-[DP]` | 1 | ? |
|
||||
@@ -180,10 +195,8 @@ Diese Tokens stehen weiter in `rawGenotype`/`unmappedTokens` — Entscheidung (M
|
||||
| `!Niereninsuffizienz!` | 1 | ? |
|
||||
| `7+09.07.2017` | 1 | ? |
|
||||
| `+2018` | 1 | ? |
|
||||
| `(F5-Wurf)` | 1 | ? |
|
||||
| `/05.06.2014` | 1 | ? |
|
||||
| `AAA` | 1 | ? |
|
||||
| `chmchm` | 1 | Schreibweise (c[chm]c[chm]) |
|
||||
| `c[chm]chm]` | 1 | ? |
|
||||
|
||||
## Wurfchronik — Datenqualitäts-Hinweise
|
||||
|
||||
|
||||
@@ -485,6 +485,19 @@ check("gender override: Mozart flipped male -> female", _g_merged[0]["gender"] =
|
||||
try: os.remove(_g_dec)
|
||||
except OSError: pass
|
||||
|
||||
# --- EMF/WMF-Vorschauen sind keine Fotos (neue Stammbäume 2026-08-18) ---
|
||||
# Excel legt neben dem echten Foto teils ein Vektor-Metafile ab; Browser können es nicht
|
||||
# darstellen → es landete als kaputte Bildkachel in der Tier-Akte.
|
||||
_emf_chart = os.path.join(r"C:\Users\gulum\dev\Sttammbäume",
|
||||
"Stammbaum von Kohlief und Johnny Jumper Kids.xlsx")
|
||||
if os.path.exists(_emf_chart):
|
||||
_emf_animals = e.extract_stammbaum(_emf_chart)
|
||||
_emf_photos = [ph for a in _emf_animals for ph in a["photos"]
|
||||
if ph.lower().endswith((".emf", ".wmf"))]
|
||||
check("EMF/WMF werden nicht als Foto angehängt", _emf_photos == [])
|
||||
else:
|
||||
print("\nWarning: EMF-Stammbaum nicht gefunden, EMF-Check übersprungen.")
|
||||
|
||||
if failed:
|
||||
print(f"\n{failed} test(s) FAILED")
|
||||
sys.exit(1)
|
||||
|
||||
@@ -616,9 +616,28 @@ if _os.path.exists(_resolved):
|
||||
# ── New ticket-triage fixes (non-genetics import cluster) ─────────────────
|
||||
# Akane: Roni is the FATHER (gender flipped male), mother = Fumi (stub).
|
||||
_check_parents("Akane (wrong-parents)", "Akane", "Roni", "Fumi")
|
||||
# Match on the call-name: since the new Stammbäume (2026-08-18) Roni carries the full
|
||||
# clan name „Roni von den Kleinen Chaoten“ — and a substring _find("Roni") would hit
|
||||
# „Vroni of little Jumpers“ first.
|
||||
_roni = next((g for g in _d["gerbils"]
|
||||
if g["Name"] == "Roni" and g.get("DateOfBirth") == "2022-01-27"), None)
|
||||
if g["Name"].startswith("Roni") and g.get("DateOfBirth") == "2022-01-27"), None)
|
||||
check("Roni: gender flipped to male", _roni is not None and _roni.get("Gender") == "male")
|
||||
# litterChildren.add (neue Stammbäume 2026-08-18): Akane bleibt im Z21-Wurf (Roni × Fumi);
|
||||
# der Phantom-Wurf „Irish Coffee × Roni“ aus der Chart-Positions-Heuristik ist entfernt.
|
||||
_akane = next((g for g in _d["gerbils"]
|
||||
if g["Name"].startswith("Akane") and g.get("DateOfBirth") == "2023-01-21"), None)
|
||||
_akane_litter = _L.get(_akane.get("LitterId")) if _akane else None
|
||||
check("Akane: im Z21-Wurf (nicht im Chart-Phantom-Wurf)",
|
||||
_akane_litter is not None and _akane_litter.get("Name") == "Z21-Wurf")
|
||||
check("kein Phantom-Wurf 'Irish Coffee × Roni' vom 21.01.2023",
|
||||
not any((l.get("Date") == "2023-01-21" and "Irish Coffee" in (l.get("Name") or ""))
|
||||
for l in _d["litters"]))
|
||||
# Merle (Ticket 36a3fcde/a8f11ac0): DOB aus „Stammbaum von Pukas Kids“, Zuchttier per Override.
|
||||
_merle = next((g for g in _d["gerbils"] if g["Name"] == "Merle"), None)
|
||||
check("Merle: DOB 18.06.2023 aus dem neuen Stammbaum",
|
||||
_merle is not None and _merle.get("DateOfBirth") == "2023-06-18")
|
||||
check("Merle: Zuchttier (isResident-Override)",
|
||||
_merle is not None and _merle.get("IsResident") is True)
|
||||
# Fumi: materialised stub that is the (Wurfchronik) MOTHER of T21/Z21/22 →
|
||||
# under the isResident-Sweep (Ticket 381f7e51) a parent of her OWN litters is
|
||||
# resident. (No isResident override in conflict-decisions, so the sweep decides.)
|
||||
|
||||
Reference in New Issue
Block a user