inwx_domains_owner: optionalen Zeitstempel im citeq-TXT auswerten
TXT-Werte koennen jetzt 'citeq:<ziffer>;<YYYYMMDD>;' lauten. get_group() liefert (ziffer, datum); die Domains werden je Gruppe (und im Block 'Ohne Zuordnung') nach Datum absteigend sortiert (juengste oben, undatierte ans Ende) und das Datum als eigene Spalte ausgegeben. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+46
-12
@@ -85,11 +85,15 @@ def load_owners():
|
||||
|
||||
|
||||
def get_group(domain):
|
||||
"""Ermittelt die Gruppen-Ziffer aus dem citeq:-TXT-Eintrag einer Domain.
|
||||
"""Ermittelt Gruppen-Ziffer und optionalen Zeitstempel aus dem citeq:-TXT.
|
||||
|
||||
Nutzt eine echte DNS-Abfrage (dig +short TXT) und funktioniert daher
|
||||
unabhängig davon, wo die DNS-Zone gehostet wird. Liefert die Ziffer als
|
||||
String oder None, wenn kein passender TXT-Eintrag gefunden wird.
|
||||
unabhängig davon, wo die DNS-Zone gehostet wird. Der TXT-Wert hat die Form
|
||||
'citeq:<ziffer>' oder – mit Zeitstempel – 'citeq:<ziffer>;<YYYYMMDD>;'
|
||||
(der abschließende Strichpunkt ist optional).
|
||||
|
||||
Liefert das Tupel (ziffer, datum), jeweils als String oder None, wenn kein
|
||||
passender TXT-Eintrag bzw. kein Datum gefunden wird.
|
||||
"""
|
||||
try:
|
||||
out = subprocess.run(
|
||||
@@ -98,20 +102,25 @@ def get_group(domain):
|
||||
)
|
||||
except FileNotFoundError:
|
||||
print("⚠️ 'dig' nicht gefunden – Gruppen können nicht ermittelt werden.")
|
||||
return None
|
||||
return None, None
|
||||
except subprocess.TimeoutExpired:
|
||||
return None
|
||||
return None, None
|
||||
|
||||
if out.returncode != 0:
|
||||
return None
|
||||
return None, None
|
||||
|
||||
for line in out.stdout.splitlines():
|
||||
# dig liefert TXT-Werte in Anführungszeichen, lange Werte ggf. in
|
||||
# mehreren Teilen ("teil1" "teil2") -> zusammenfügen und entkleiden.
|
||||
content = line.replace('" "', '').strip().strip('"')
|
||||
if content.startswith(TXT_PREFIX):
|
||||
return content[len(TXT_PREFIX):].strip()
|
||||
return None
|
||||
rest = content[len(TXT_PREFIX):].strip()
|
||||
# Ziffer und optionalen Zeitstempel am Semikolon trennen.
|
||||
parts = [p.strip() for p in rest.split(";")]
|
||||
ziffer = parts[0] if parts and parts[0] else None
|
||||
datum = parts[1] if len(parts) > 1 and parts[1] else None
|
||||
return ziffer, datum
|
||||
return None, None
|
||||
|
||||
|
||||
def tld_of(domain):
|
||||
@@ -153,6 +162,18 @@ def fmt_price(value):
|
||||
return f"{value:.2f}".replace(".", ",") + " €"
|
||||
|
||||
|
||||
def fmt_date(datum):
|
||||
"""Formatiert einen Zeitstempel 'YYYYMMDD' als 'DD.MM.YYYY'.
|
||||
|
||||
Liefert '-' bei fehlendem und den Rohwert bei unerwartetem Format.
|
||||
"""
|
||||
if not datum:
|
||||
return "-"
|
||||
if len(datum) == 8 and datum.isdigit():
|
||||
return f"{datum[6:8]}.{datum[4:6]}.{datum[0:4]}"
|
||||
return datum
|
||||
|
||||
|
||||
def print_group_sums(recs, ziffer, prices):
|
||||
"""Gibt für eine Gruppe die Anzahl Domains pro Top-Level-Domain aus.
|
||||
|
||||
@@ -177,7 +198,18 @@ def format_domain_line(rec):
|
||||
ns = "(keine NS-Einträge gefunden)"
|
||||
else:
|
||||
ns = ", ".join(rec['ns'])
|
||||
return f" {rec['name']:<35} {rec['status']:<8} {ns}"
|
||||
return f" {rec['name']:<35} {rec['status']:<8} {fmt_date(rec['datum']):<12} {ns}"
|
||||
|
||||
|
||||
def sort_by_date_desc(recs):
|
||||
"""Sortiert Domains nach Zeitstempel absteigend (jüngste zuerst).
|
||||
|
||||
Domains ohne Zeitstempel wandern ans Ende. Bei gleichem Datum bleibt die
|
||||
vorherige (alphabetische) Reihenfolge erhalten – sorted() ist stabil, auch
|
||||
mit reverse=True.
|
||||
"""
|
||||
recs.sort(key=lambda r: (r['datum'] is not None, r['datum'] or ""), reverse=True)
|
||||
return recs
|
||||
|
||||
|
||||
def main():
|
||||
@@ -198,10 +230,12 @@ def main():
|
||||
records = []
|
||||
for d in domains:
|
||||
name = d.get('domain', '')
|
||||
ziffer, datum = get_group(name)
|
||||
records.append({
|
||||
'name': name,
|
||||
'status': d.get('status', ''),
|
||||
'ziffer': get_group(name),
|
||||
'ziffer': ziffer,
|
||||
'datum': datum,
|
||||
'ns': get_nameservers(api, name),
|
||||
})
|
||||
|
||||
@@ -212,7 +246,7 @@ def main():
|
||||
print()
|
||||
for ziffer, klarname in owners.items():
|
||||
print(f"{ziffer} ({klarname})")
|
||||
matching = [r for r in records if r['ziffer'] == ziffer]
|
||||
matching = sort_by_date_desc([r for r in records if r['ziffer'] == ziffer])
|
||||
if matching:
|
||||
for rec in matching:
|
||||
print(format_domain_line(rec))
|
||||
@@ -222,7 +256,7 @@ def main():
|
||||
print() # Leerzeile zwischen den Gruppen
|
||||
|
||||
# Domains, die keiner Ziffer aus domain_owner zugeordnet sind
|
||||
rest = [r for r in records if r['ziffer'] not in owners]
|
||||
rest = sort_by_date_desc([r for r in records if r['ziffer'] not in owners])
|
||||
if rest:
|
||||
print("Ohne Zuordnung")
|
||||
for rec in rest:
|
||||
|
||||
Reference in New Issue
Block a user