Upload files to "/"
This commit is contained in:
parent
f6f36e10b3
commit
c6e4c0126f
1 changed files with 46 additions and 16 deletions
|
@ -1,8 +1,13 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- 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
|
Dieses Script exportiert Geburtstage aus Apple Contacts und erstellt eine
|
||||||
Remind-Datei (geburtstage.rem) für Geburtstagserinnerungen.
|
Remind-Datei (geburtstage.rem) für Geburtstagserinnerungen.
|
||||||
|
|
||||||
|
Creation Date: 2025-04-18
|
||||||
|
Revision: 1.3
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
@ -12,11 +17,13 @@ import argparse
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
try:
|
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
|
from Contacts import CNContactStore, CNContactFetchRequest, CNContactBirthdayKey, CNContactGivenNameKey, CNContactFamilyNameKey
|
||||||
import objc
|
import objc
|
||||||
except ImportError:
|
except ImportError:
|
||||||
print("Die 'pyobjc-framework-Contacts' Bibliothek wird benötigt. Bitte installieren Sie sie mit:")
|
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")
|
print("uv pip install pyobjc-framework-Contacts")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
@ -29,6 +36,7 @@ def get_birthdays_from_contacts():
|
||||||
request = CNContactFetchRequest.alloc().initWithKeysToFetch_(keys_to_fetch)
|
request = CNContactFetchRequest.alloc().initWithKeysToFetch_(keys_to_fetch)
|
||||||
|
|
||||||
birthdays = []
|
birthdays = []
|
||||||
|
placeholder_contacts = [] # Kontakte mit dem Platzhalter-Jahr 1604
|
||||||
|
|
||||||
# Callback-Funktion für jeden gefundenen Kontakt
|
# Callback-Funktion für jeden gefundenen Kontakt
|
||||||
def handle_contact(contact, stop):
|
def handle_contact(contact, stop):
|
||||||
|
@ -48,6 +56,11 @@ def get_birthdays_from_contacts():
|
||||||
year = birthday.year()
|
year = birthday.year()
|
||||||
# In Apple Contacts ist 1604 oft ein Platzhalter für "kein Jahr"
|
# In Apple Contacts ist 1604 oft ein Platzhalter für "kein Jahr"
|
||||||
if year == 1604:
|
if year == 1604:
|
||||||
|
placeholder_contacts.append({
|
||||||
|
'name': name,
|
||||||
|
'month': month,
|
||||||
|
'day': day
|
||||||
|
})
|
||||||
year = None
|
year = None
|
||||||
except:
|
except:
|
||||||
year = None
|
year = None
|
||||||
|
@ -68,7 +81,7 @@ def get_birthdays_from_contacts():
|
||||||
error = objc.nil
|
error = objc.nil
|
||||||
store.enumerateContactsWithFetchRequest_error_usingBlock_(request, error, handle_contact)
|
store.enumerateContactsWithFetchRequest_error_usingBlock_(request, error, handle_contact)
|
||||||
|
|
||||||
return birthdays
|
return birthdays, placeholder_contacts
|
||||||
|
|
||||||
def create_remind_file(birthdays, output_file='geburtstage.rem'):
|
def create_remind_file(birthdays, output_file='geburtstage.rem'):
|
||||||
"""Erstellt eine Remind-Datei mit den Geburtstagsinformationen."""
|
"""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:
|
with open(output_file, 'w', encoding='utf-8') as f:
|
||||||
f.write("# Geburtstage aus Apple Contacts\n")
|
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("# 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'])):
|
for person in sorted(birthdays, key=lambda x: (x['month'], x['day'])):
|
||||||
name = person['name']
|
name = person['name']
|
||||||
|
@ -85,19 +104,15 @@ def create_remind_file(birthdays, output_file='geburtstage.rem'):
|
||||||
day = person['day']
|
day = person['day']
|
||||||
birth_year = person['year']
|
birth_year = person['year']
|
||||||
|
|
||||||
# Alterstext erstellen, falls Geburtsjahr vorhanden und gültig
|
# Verwende since() Funktion, wenn Geburtsjahr verfügbar ist
|
||||||
age_text = ""
|
|
||||||
if birth_year and isinstance(birth_year, int) and birth_year > 1900 and birth_year < current_year:
|
if birth_year and isinstance(birth_year, int) and birth_year > 1900 and birth_year < current_year:
|
||||||
age = current_year - birth_year
|
# Erinnerung mit 7-Tage-Vorwarnung
|
||||||
age_text = f"({age} Jahre alt)"
|
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)
|
||||||
# Remind-Eintrag für den Geburtstag selbst
|
else:
|
||||||
remind_entry = f'REM {day} {month_to_abbr(month)} MSG {name}: Geburtstag {age_text} %b\n'
|
# 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)
|
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)
|
|
||||||
|
|
||||||
def month_to_abbr(month_num):
|
def month_to_abbr(month_num):
|
||||||
"""Konvertiert eine Monatsnummer (1-12) in die dreistellige Abkürzung für Remind."""
|
"""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"]
|
"JUL", "AUG", "SEP", "OCT", "NOV", "DEC"]
|
||||||
return months[month_num - 1]
|
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():
|
def main():
|
||||||
"""Hauptfunktion des Scripts."""
|
"""Hauptfunktion des Scripts."""
|
||||||
parser = argparse.ArgumentParser(description='Exportiert Geburtstage aus Apple Contacts in eine Remind-Datei.')
|
parser = argparse.ArgumentParser(description='Exportiert Geburtstage aus Apple Contacts in eine Remind-Datei.')
|
||||||
|
@ -119,7 +146,7 @@ def main():
|
||||||
if args.verbose:
|
if args.verbose:
|
||||||
print("Lese Kontakte aus Apple Contacts...")
|
print("Lese Kontakte aus Apple Contacts...")
|
||||||
|
|
||||||
birthdays = get_birthdays_from_contacts()
|
birthdays, placeholder_contacts = get_birthdays_from_contacts()
|
||||||
|
|
||||||
if args.verbose:
|
if args.verbose:
|
||||||
print(f"{len(birthdays)} Kontakte mit Geburtstagsinformationen gefunden.")
|
print(f"{len(birthdays)} Kontakte mit Geburtstagsinformationen gefunden.")
|
||||||
|
@ -129,6 +156,9 @@ def main():
|
||||||
print(f"Remind-Datei erfolgreich erstellt: {args.output}")
|
print(f"Remind-Datei erfolgreich erstellt: {args.output}")
|
||||||
print(f"Insgesamt {len(birthdays)} Geburtstage exportiert.")
|
print(f"Insgesamt {len(birthdays)} Geburtstage exportiert.")
|
||||||
|
|
||||||
|
# Bericht über Kontakte mit fehlendem Geburtsjahr ausgeben
|
||||||
|
print_placeholder_report(placeholder_contacts)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Fehler: {e}")
|
print(f"Fehler: {e}")
|
||||||
import traceback
|
import traceback
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue