diff --git a/contacts_to_remind.py b/contacts_to_remind.py index 9290968..df33d9f 100644 --- a/contacts_to_remind.py +++ b/contacts_to_remind.py @@ -1,8 +1,13 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ +contacts_to_remind.py - Exportiert Geburtstage aus Apple Contacts in eine Remind-Datei + Dieses Script exportiert Geburtstage aus Apple Contacts und erstellt eine Remind-Datei (geburtstage.rem) für Geburtstagserinnerungen. + +Creation Date: 2025-04-18 +Revision: 1.3 """ import os @@ -12,11 +17,13 @@ import argparse from pathlib import Path try: - # Statt 'contacts' verwenden wir pyobjc-framework-Contacts + # Verwenden von pyobjc-framework-Contacts für den Zugriff auf Apple Contacts from Contacts import CNContactStore, CNContactFetchRequest, CNContactBirthdayKey, CNContactGivenNameKey, CNContactFamilyNameKey import objc except ImportError: print("Die 'pyobjc-framework-Contacts' Bibliothek wird benötigt. Bitte installieren Sie sie mit:") + print("pip install pyobjc-framework-Contacts") + print("oder") print("uv pip install pyobjc-framework-Contacts") sys.exit(1) @@ -29,6 +36,7 @@ def get_birthdays_from_contacts(): request = CNContactFetchRequest.alloc().initWithKeysToFetch_(keys_to_fetch) birthdays = [] + placeholder_contacts = [] # Kontakte mit dem Platzhalter-Jahr 1604 # Callback-Funktion für jeden gefundenen Kontakt def handle_contact(contact, stop): @@ -48,6 +56,11 @@ def get_birthdays_from_contacts(): year = birthday.year() # In Apple Contacts ist 1604 oft ein Platzhalter für "kein Jahr" if year == 1604: + placeholder_contacts.append({ + 'name': name, + 'month': month, + 'day': day + }) year = None except: year = None @@ -68,7 +81,7 @@ def get_birthdays_from_contacts(): error = objc.nil store.enumerateContactsWithFetchRequest_error_usingBlock_(request, error, handle_contact) - return birthdays + return birthdays, placeholder_contacts def create_remind_file(birthdays, output_file='geburtstage.rem'): """Erstellt eine Remind-Datei mit den Geburtstagsinformationen.""" @@ -77,7 +90,13 @@ def create_remind_file(birthdays, output_file='geburtstage.rem'): with open(output_file, 'w', encoding='utf-8') as f: f.write("# Geburtstage aus Apple Contacts\n") f.write("# Erstellt am: {}\n".format(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))) - f.write("# Enthält Erinnerungen am Geburtstag und 7 Tage vorher\n\n") + f.write("# Enthält Erinnerungen am Geburtstag mit 7-Tage-Vorwarnung\n\n") + + # Add the since() function definition + f.write("if !defined(\"init\")\n") + f.write(" set init 1\n") + f.write(" fset since(x) ord(year(trigdate())-x)\n") + f.write("endif\n\n") for person in sorted(birthdays, key=lambda x: (x['month'], x['day'])): name = person['name'] @@ -85,19 +104,15 @@ def create_remind_file(birthdays, output_file='geburtstage.rem'): day = person['day'] birth_year = person['year'] - # Alterstext erstellen, falls Geburtsjahr vorhanden und gültig - age_text = "" + # Verwende since() Funktion, wenn Geburtsjahr verfügbar ist if birth_year and isinstance(birth_year, int) and birth_year > 1900 and birth_year < current_year: - age = current_year - birth_year - age_text = f"({age} Jahre alt)" - - # Remind-Eintrag für den Geburtstag selbst - remind_entry = f'REM {day} {month_to_abbr(month)} MSG {name}: Geburtstag {age_text} %b\n' - f.write(remind_entry) - - # Remind-Eintrag für die Vorwarnung 7 Tage vorher - remind_entry_advance = f'REM {day} {month_to_abbr(month)} +7 MSG Vorwarnung: {name} hat %b Geburstag {age_text}\n' - f.write(remind_entry_advance) + # Erinnerung mit 7-Tage-Vorwarnung + remind_entry = f'REM {day} {month_to_abbr(month)} +7 MSG {name}s [since({birth_year})] Geburtstag ist am {day}. {month_to_abbr(month)} %b\n' + f.write(remind_entry) + else: + # Kontakte ohne Geburtsjahr, Erinnerung mit 7-Tage-Vorwarnung + remind_entry = f'REM {day} {month_to_abbr(month)} +7 MSG {name}s Geburtstag ist am {day}. {month_to_abbr(month)} %b\n' + f.write(remind_entry) def month_to_abbr(month_num): """Konvertiert eine Monatsnummer (1-12) in die dreistellige Abkürzung für Remind.""" @@ -105,6 +120,18 @@ def month_to_abbr(month_num): "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"] return months[month_num - 1] +def print_placeholder_report(placeholder_contacts): + """Gibt einen Bericht über Kontakte mit dem Platzhalter-Jahr 1604 aus.""" + if not placeholder_contacts: + print("\nKeine Kontakte mit fehlendem Geburtsjahr gefunden.") + return + + print("\nKontakte mit fehlendem Geburtsjahr (1604):") + print("-----------------------------------------") + for person in sorted(placeholder_contacts, key=lambda x: x['name']): + print(f"• {person['name']} ({person['day']}.{person['month']}.)") + print("\nHinweis: Bei diesen Kontakten wird kein Alter berechnet.") + def main(): """Hauptfunktion des Scripts.""" parser = argparse.ArgumentParser(description='Exportiert Geburtstage aus Apple Contacts in eine Remind-Datei.') @@ -119,7 +146,7 @@ def main(): if args.verbose: print("Lese Kontakte aus Apple Contacts...") - birthdays = get_birthdays_from_contacts() + birthdays, placeholder_contacts = get_birthdays_from_contacts() if args.verbose: print(f"{len(birthdays)} Kontakte mit Geburtstagsinformationen gefunden.") @@ -129,6 +156,9 @@ def main(): print(f"Remind-Datei erfolgreich erstellt: {args.output}") print(f"Insgesamt {len(birthdays)} Geburtstage exportiert.") + # Bericht über Kontakte mit fehlendem Geburtsjahr ausgeben + print_placeholder_report(placeholder_contacts) + except Exception as e: print(f"Fehler: {e}") import traceback