"""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))