Whitepaper
Docs
Sign In
Tool
Tool
v0.0.1
VCF & iCal
Tool ID
vobject
Creator
@ex0dus
Downloads
296+
VCard / iCalendar generation toolkit - Create importable contacts, calendar events, and todos
Get
README
No README available
Tool Code
Show
""" title: VCF & iCal author: ex0dus author_url: https://github.com/roryeckel version: 0.0.1 requirements: vobject, pytz """ import vobject from datetime import datetime from pytz import UTC from dateutil import parser from typing import Callable, Awaitable, Optional def validate_date(date_string: str) -> Optional[datetime]: """ Validate and parse a date string. :param date_string: The date string to validate. :return: Parsed UTC datetime object if valid, None otherwise. """ try: return parser.parse(date_string).astimezone(UTC) except ValueError: return None class Tools: def __init__(self): pass async def create_contact_vcard( self, __event_emitter__: Callable[[dict], Awaitable[None]], first_name: str, last_name: str = None, organization: str = None, email: str = None, phone: str = None, address: str = None, title: str = None, website: str = None, birthday: str = None, note: str = None, photo_url: str = None ) -> str: """ Create a new contact VCard based on the input parameters. Note: strictly adhere to JSON syntax. :param first_name: The first name of the contact. :param last_name: The last name of the contact. :param organization: The organization of the contact. :param email: The email of the contact. :param phone: The phone number of the contact. :param address: The address of the contact. :param title: The job title of the contact. :param website: The website of the contact. :param birthday: The birthday of the contact. :param note: Additional notes about the contact. :param photo_url: URL of the contact's photo. :return: The VCF formatted VCard contact file contents. """ vcard = vobject.vCard() vcard.add("n").value = vobject.vcard.Name(family=last_name, given=first_name) vcard.add("fn").value = f"{first_name} {last_name}" if organization: vcard.add("org") vcard.org.value = [organization] if email: vcard.add("email") vcard.email.value = email vcard.email.type_param = "INTERNET" if phone: vcard.add("tel") vcard.tel.value = phone vcard.tel.type_param = "CELL" if address: vcard.add("adr") vcard.adr.value = vobject.vcard.Address(street=address) vcard.adr.type_param = "HOME" if title: vcard.add("title") vcard.title.value = title if website: vcard.add("url") vcard.url.value = website if birthday: parsed_date = validate_date(birthday) if parsed_date: vcard.add("bday").value = parsed_date.isoformat() else: await __event_emitter__( { "data": { "description": f"Invalid date format for birthday: {birthday}. Expected format: YYYY-MM-DDTHH:MM:SS±HHMM.", "status": "complete", "done": True, }, "type": "status", }) if note: vcard.add("note") vcard.note.value = note if photo_url: vcard.add("photo") vcard.photo.value = photo_url vcard.photo.type_param = "URL" # for key, value in kwargs.items(): # vcard.add(key).value = value try: result = vcard.serialize() await __event_emitter__( { "type": "message", "data": {"content": f"```vcard\n{result}\n```\n"}, } ) return result except Exception as e: print(e) vcard.prettyPrint() await __event_emitter__( { "data": { "description": f"Error serializing VCard: {e}", "status": "complete", "done": True, }, "type": "status", } ) async def create_icalendar_todo( self, __event_emitter__: Callable[[dict], Awaitable[None]], summary: str, status: str = None, uid: str = None, dtstamp: str = None, sequence: str = None, created: str = None, last_modified: str = None, description: str = None, percent_complete: str = None ) -> str: """ Create a new iCalendar TODO item based on the input parameters. Note: strictly adhere to JSON syntax. :param summary: The required summary of the TODO item. :param status: The status of the TODO item. :param uid: The unique identifier for the TODO item. Should be left empty if new entry, otherwise provide the existing UID. :param dtstamp: The timestamp of the TODO item. :param sequence: The sequence number of the TODO item. :param created: The creation date of the TODO item. If empty, will be set to now. :param last_modified: The last modified date of the TODO item. :param description: The description of the TODO item. This description may also be formatted in Markdown, but be careful to escape any special characters. :param percent_complete: The percentage of completion of the TODO item. :return: The iCalendar ICS formatted TODO item. """ cal = vobject.iCalendar() todo = cal.add('vtodo') todo.add('dtstamp').value = validate_date(dtstamp) if dtstamp else datetime.now(UTC) if uid: todo.add('uid').value = uid todo.add('summary').value = summary todo.add('status').value = status or 'IN-PROCESS' if sequence: todo.add('sequence').value = sequence if created: parsed_created = validate_date(created) if parsed_created: todo.add('created').value = parsed_created if last_modified: parsed_last_modified = validate_date(last_modified) if parsed_last_modified: todo.add('last-modified').value = parsed_last_modified if description: todo.add('description').value = description if percent_complete: todo.add('percent-complete').value = percent_complete # for key, value in kwargs.items(): # todo.add(key).value = value try: result = cal.serialize() await __event_emitter__( { "type": "message", "data": {"content": f"```icalendar\n{result}\n```\n"}, } ) return result except Exception as e: print(e) cal.prettyPrint() await __event_emitter__( { "data": { "description": f"Error serializing iCalendar: {e}", "status": "complete", "done": True, }, "type": "status", } ) async def create_icalendar_event( self, __event_emitter__: Callable[[dict], Awaitable[None]], dtstart: str, dtstamp: str = None, dtend: str = None, location: str = None, summary: str = None, description: str = None ) -> str: """ Create a new iCalendar Event item based on the input parameters. :param dtstart: The start date-time of the Event. :param dtstamp: The timestamp of the Event. :param dtend: The end date-time of the Event. :param location: The location of the Event. :param summary: The required summary of the Event. :param description: The optional description of the Event. :return: The iCalendar ICS formatted Event item. """ if not summary: description = summary if not description: description = summary cal = vobject.iCalendar() event = cal.add('vevent') event.add('dtstamp').value = validate_date(dtstamp) if dtstamp else datetime.now(UTC) event.add('summary').value = summary parsed_dtstart = validate_date(dtstart) if parsed_dtstart: event.add('dtstart').value = parsed_dtstart if not dtend: dtend = dtstart parsed_dtend = validate_date(dtend) if parsed_dtend: event.add('dtend').value = parsed_dtend if location: event.add('location').value = location if description: event.add('description').value = description # for key, value in kwargs.items(): # event.add(key).value = value try: result = cal.serialize() await __event_emitter__( { "type": "message", "data": {"content": f"```icalendar\n{result}\n```\n"}, } ) return result except Exception as e: print(e) cal.prettyPrint() await __event_emitter__( { "data": { "description": f"Error serializing iCalendar: {e}", "status": "complete", "done": True, }, "type": "status", } )