cteward-ng/cteward_ng/memberdata.py
2026-06-06 12:04:59 +02:00

99 lines
3 KiB
Python

"""Member data utility functions.
Replaces memberdata.js:
- realstatus: determine crew/passive/ex-crew/raumfahrer status
- datum: parse 'YYYYMMDD' strings to German date format (d.m.YYYY)
- datum_parsed: parse date strings via Python datetime
- patenarray: split comma-separated sponsor names
- cleanpaten: clean and rejoin sponsor names
"""
from datetime import datetime
def realstatus(member):
"""Determine the real membership status of *member*.
member: dict with keys Kennung3, Austritt, Kurzname
Returns one of: 'crew', 'raumfahrer', 'passiv', 'ex-crew', 'ex-raumfahrer'
"""
if member is None:
raise TypeError("Need a member record to work with")
status = member.get('Kennung3') or ''
# Normalize Kennung3 prefix
if not status or status.startswith('check'):
status = 'crew'
if status.startswith('crew'):
status = 'crew'
if status.startswith('raumfahrer'):
status = 'raumfahrer'
if status.startswith('passiv'):
status = 'passiv'
# Check for expiry date (Austritt in the past)
austritt = member.get('Austritt')
if austritt and austritt != '':
try:
austritt_dt = datetime.strptime(austritt, '%Y-%m-%dT%H:%M:%S.%fZ')
# Set to end of that day
austritt_dt = austritt_dt.replace(hour=23, minute=59, second=59, microsecond=999999)
if austritt_dt < datetime.utcnow():
if status == 'crew' or status == 'passiv':
status = 'ex-crew'
elif status == 'raumfahrer':
status = 'ex-raumfahrer'
except ValueError:
pass
# Disabled crewname prefix
kurzname = member.get('Kurzname') or ''
if kurzname.startswith('disabled-'):
status = 'ex-crew'
return status
def datum(isodate):
"""Parse 'YYYYMMDD' string to German date format 'd.m.YYYY'.
Returns '1.1.1970' on failure.
"""
if not isinstance(isodate, str) or len(isodate) != 8:
return '1.1.1970'
try:
dt = datetime.strptime(isodate, '%Y%m%d')
return f'{dt.day}.{dt.month}.{dt.year}'
except ValueError:
return '1.1.1970'
def datum_parsed(isodate):
"""Parse a date string via Python datetime, return German format.
Returns '1.1.1970' on failure.
"""
try:
dt = datetime.fromisoformat(isodate.replace('Z', '+00:00'))
return f'{dt.day}.{dt.month}.{dt.year}'
except (ValueError, AttributeError):
return '1.1.1970'
def patenarray(patenstr):
"""Split a comma-separated sponsor string into a clean list.
Handles leading/trailing whitespace and empty entries.
"""
if not patenstr:
return []
if ',' not in patenstr:
stripped = patenstr.strip()
return [stripped] if stripped else []
return [p.strip() for p in patenstr.split(',') if p.strip()]
def cleanpaten(patenstr):
"""Clean and rejoin sponsor names as a single comma-separated string."""
return ','.join(patenarray(patenstr))