from datetime import datetime from typing import Tuple def get_time_or_now(time): return time if time is not None else datetime.now() def parse_optional_time(time): return None if time is None else datetime.fromisoformat(time) class RegistrationCode: def __init__(self, code: str, creation_time: datetime = None, expiration_time: datetime = None, usages: int = 0, max_usages: int = 1): self.code = code self.creation_time = get_time_or_now(creation_time) self.expiration_time = expiration_time self.usages = usages self.max_usages = max_usages @staticmethod def from_db(db_registration_code: Tuple) -> 'RegistrationCode': return RegistrationCode( db_registration_code[0], datetime.fromisoformat(db_registration_code[1]), parse_optional_time(db_registration_code[2]), db_registration_code[3], db_registration_code[4] ) def is_expired(self): return self.expiration_time is not None and self.expiration_time < datetime.now() def has_available_uses(self): return self.usages < self.max_usages class RegisteredUser: def __init__(self, registration_code: str, username: str, registered_user_id: str, registered_time: datetime = None): self.registration_code = registration_code self.username = username self.registered_user_id = registered_user_id self.registered_time = get_time_or_now(registered_time) @staticmethod def from_db(db_registered_user: Tuple) -> 'RegisteredUser': return RegisteredUser( db_registered_user[0], db_registered_user[1], db_registered_user[3], datetime.fromisoformat(db_registered_user[2]) )