"""Data classes for ITU document generation.""" class ValueAndLink: """A value (document number, question name, etc.) with an optional hyperlink.""" def __init__(self, value=None, link=None): if value is None: self.value = "" self.name = "" else: # Clean whitespace: collapse multiple spaces, strip brackets name = "" last_char = 0 for ch in value: if ch == ' ': if last_char != ' ': name += ch last_char = ch elif ch not in ('[]'): name += ch last_char = ch self.name = name idx = name.find('-') self.value = name[:idx] if idx > 0 else name self.link = link if link else "" class TableRow: """A row from the ITU meeting documents table.""" def __init__(self, number=None, rev="", title=None, source=None, questions=None): self.number = number if rev is None: self.rev = "" self.lastRev = "" else: self.rev = rev idx = rev.find("-") if idx > 0: self.lastRev = "R" + rev[idx + 1:-1] else: idx = rev.find(".") if idx > 0: self.lastRev = "R" + rev[idx + 1:-1] else: self.lastRev = "" self.title = title self.documentType, self.recommendation, self.acronym, self.textTitle = split_title(self.title) self.source = source self.questions = questions if questions else [] class Role: """A person's role in an ITU study group (rapporteur, chair, etc.).""" def __init__(self, roleName=None, firstName=None, lastName=None, company=None, address=None, email=None, tel=None): self.roleName = roleName or '' self.firstName = firstName or '' self.lastName = lastName or '' self.company = company or '' self.address = address or '' self.email = email or '' self.tel = tel or '' class Question: """An ITU-T Question with its leadership roles.""" def __init__(self, group=None, workingParty=None, question=None, title=None): self.group = group self.workingParty = workingParty self.question = question self.title = title self.roles = [] def addRole(self, role): self.roles.append(role) class WorkingParty: """An ITU-T Working Party with leadership and questions.""" def __init__(self, group=None, workingParty=None, title=None, questions=None): self.group = group self.workingParty = workingParty self.title = title self.questions = questions if questions else [] self.roles = [] self.sg_roles = [] def addRole(self, role): self.roles.append(role) class QuestionStructure: """Question number and title within the SG hierarchy.""" def __init__(self, number, title=None): self.number = number self.title = title class WorkingPartyStructure: """WP number, title, and contained questions within the SG hierarchy.""" def __init__(self, number, title=None): self.number = number self.title = title self.questions = [] class StudyGroupStructure: """Full SG hierarchy: study group -> working parties -> questions.""" def __init__(self, group, title=None): self.group = group self.title = title self.workingParties = [] class WorkItem: """A work item from the ITU work programme.""" def __init__(self, workItem=None, question=None, title=None, timing=None, group=None, period=None, version=None, status=None, approvalProcess=None, equivNum=None, detailLink=None): self.workItem = workItem self.question = question self.title = title self.timing = timing self.group = group self.period = period self.version = version self.status = status self.approvalProcess = approvalProcess self.equivNum = equivNum self.detailLink = detailLink or '' # --- Internal HTML parsing classes (used by itu_api) --- class AElement: """An element parsed from HTML.""" def __init__(self, href=None, strongElements=None, contents=None, text=None): self.href = href self.strongElements = strongElements or [] self.contents = contents or [] self.text = text or "" def get_text(self): """Get full text content (handles hyphenated names like 'Co-Rapporteur').""" return self.text class Column: """A