import random from datetime import datetime MONTH_CODES = "ABCDEFGHIJKL" SAFE_CHARS = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789" # No 0, O, 1, I — avoids label confusion # Family segment (chars 3-6 of segment 1, after "BS") BOARD_FAMILY_CODES = { "vesper": "VSPR", "vesper_plus": "VSPR", "vesper_pro": "VSPR", "agnus": "AGNS", "agnus_mini": "AGNS", "chronos": "CRNS", "chronos_pro": "CRNS", } # Variant segment (first 3 chars of segment 3) BOARD_VARIANT_CODES = { "vesper": "STD", "vesper_plus": "PLS", "vesper_pro": "PRO", "agnus": "STD", "agnus_mini": "MIN", "chronos": "STD", "chronos_pro": "PRO", } def _version_suffix(board_version: str) -> str: """Convert version string to 3-char suffix. Rules: - Strip the dot: "2.3" → "23", "10.2" → "102" - If result is 2 digits, append "R": "23" → "23R" - If result is already 3 digits, use as-is: "102" → "102" """ digits = board_version.replace(".", "") if len(digits) >= 3: return digits[:3] return digits.ljust(2, "0") + "R" def generate_serial(board_type: str, board_version: str) -> str: """Generate a serial number in the format BSFFFF-YYMDDFX-VVVHHH-XXXXXX. Format: BSFFFF-YYMDDf-VVVvvv-XXXXXX BS = Bell Systems (static) FFFF = 4-char family code (VSPR, AGNS, CRNS) YY = 2-digit year M = month code A-L DD = 2-digit day f = random filler char VVV = 3-char variant (STD, PLS, PRO, MIN) vvv = 3-char version suffix (e.g. 23R, 102) XXXXXX = 6-char random suffix board_type: enum value e.g. 'vesper', 'vesper_plus', 'vesper_pro' board_version: version string e.g. '2.3', '10.2' """ key = board_type.lower() family = BOARD_FAMILY_CODES.get(key, "UNKN") variant = BOARD_VARIANT_CODES.get(key, "UNK") ver = _version_suffix(board_version) now = datetime.utcnow() year = now.strftime("%y") month = MONTH_CODES[now.month - 1] day = now.strftime("%d") filler = random.choice(SAFE_CHARS) suffix = "".join(random.choices(SAFE_CHARS, k=6)) seg1 = f"BS{family}" # e.g. BSVSPR seg2 = f"{year}{month}{day}{filler}" # e.g. 26C13X seg3 = f"{variant}{ver}" # e.g. PRO23R seg4 = suffix # e.g. X9K4M2 return f"{seg1}-{seg2}-{seg3}-{seg4}"