99 lines
3 KiB
Python
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))
|