import os import unicodedata def _slug(s: str) -> str: if not s: return '' s = unicodedata.normalize('NFKD', s) s = ''.join(c for c in s if not unicodedata.combining(c)) s = ''.join(c for c in s if c.isalnum() or c in (' ', '_', '-')) return s.replace(' ', '_') def generate_vcard(adresse, base_dir: str): """Generate a vCard 4.0 file for the given adresse object. adresse: object with attributes vorname, nachname, strasse, hausnummer, plz, ort, land, email, telefon_vorwahl, telefon_nummer, id base_dir: directory where 'vcards/' will be created Returns the path to the written vcard file. """ vcards_dir = os.path.join(base_dir, 'vcards') os.makedirs(vcards_dir, exist_ok=True) filename = f"{_slug(adresse.nachname)}_{_slug(adresse.vorname)}_{adresse.id}.vcf" filepath = os.path.join(vcards_dir, filename) # build vCard 4.0 content lines = [ 'BEGIN:VCARD', 'VERSION:4.0', f'N:{adresse.nachname};{adresse.vorname};;;', f'FN:{adresse.vorname} {adresse.nachname}', ] street = getattr(adresse, 'strasse', '') or '' hausnummer = getattr(adresse, 'hausnummer', '') or '' if hausnummer: street = f"{street} {hausnummer}".strip() adr = f'ADR:;;{street};{getattr(adresse, "ort", "")};;{getattr(adresse, "plz", "")};{getattr(adresse, "land", "")}' lines.append(adr) if getattr(adresse, 'email', None): lines.append(f'EMAIL;TYPE=internet:{adresse.email}') if getattr(adresse, 'telefon_vorwahl', None) or getattr(adresse, 'telefon_nummer', None): tel = f"+{getattr(adresse, 'telefon_vorwahl', '')}{getattr(adresse, 'telefon_nummer', '')}".replace('++', '+') lines.append(f'TEL;TYPE=voice:{tel}') lines.append('END:VCARD') with open(filepath, 'w', encoding='utf-8') as f: f.write('\n'.join(lines)) return filepath