def _generate_rsvp(status, account, event): # It seems that Google Calendar requires us to copy a number of fields # in the RVSP reply. I suppose it's for reconciling the reply with the # invite. - karim cal = iCalendar() cal.add('PRODID', '-//Nylas sync engine//nylas.com//') cal.add('METHOD', 'REPLY') cal.add('VERSION', '2.0') cal.add('CALSCALE', 'GREGORIAN') icalevent = icalendar.Event() icalevent['uid'] = event.uid # For ahem, 'historic reasons', we're saving the owner field # as "Organizer <*****@*****.**>". organizer_name, organizer_email = event.owner.split('<') organizer_email = organizer_email[:-1] icalevent['sequence'] = event.sequence_number icalevent['X-MICROSOFT-CDO-APPT-SEQUENCE'] = icalevent['sequence'] if event.status == 'confirmed': icalevent['status'] = 'CONFIRMED' icalevent['dtstamp'] = serialize_datetime(datetime.utcnow()) if event.start is not None: icalevent['dtstart'] = serialize_datetime(event.start) if event.end is not None: icalevent['dtend'] = serialize_datetime(event.end) if event.description is not None: icalevent['description'] = event.description if event.location is not None: icalevent['location'] = event.location if event.title is not None: icalevent['summary'] = event.title attendee = icalendar.vCalAddress(u'MAILTO:{}'.format( account.email_address)) attendee.params['cn'] = account.name attendee.params['partstat'] = status icalevent.add('attendee', attendee, encode=0) cal.add_component(icalevent) ret = {} ret["cal"] = cal ret["organizer_email"] = organizer_email return ret
def _generate_rsvp(status, account, event): # It seems that Google Calendar requires us to copy a number of fields # in the RVSP reply. I suppose it's for reconciling the reply with the # invite. - karim cal = iCalendar() cal.add("PRODID", "-//Nylas sync engine//nylas.com//") cal.add("METHOD", "REPLY") cal.add("VERSION", "2.0") cal.add("CALSCALE", "GREGORIAN") icalevent = icalendar.Event() icalevent["uid"] = event.uid if event.organizer_email is not None: icalevent["organizer"] = event.organizer_email icalevent["sequence"] = event.sequence_number icalevent["X-MICROSOFT-CDO-APPT-SEQUENCE"] = icalevent["sequence"] if event.status == "confirmed": icalevent["status"] = "CONFIRMED" icalevent["dtstamp"] = serialize_datetime(datetime.utcnow()) if event.start is not None: icalevent["dtstart"] = serialize_datetime(event.start) if event.end is not None: icalevent["dtend"] = serialize_datetime(event.end) if event.description is not None: icalevent["description"] = event.description if event.location is not None: icalevent["location"] = event.location if event.title is not None: icalevent["summary"] = event.title attendee = icalendar.vCalAddress(u"MAILTO:{}".format( account.email_address)) attendee.params["cn"] = account.name attendee.params["partstat"] = status icalevent.add("attendee", attendee, encode=0) cal.add_component(icalevent) ret = {} ret["cal"] = cal return ret
def main(): test_data = [['20200920', '20200920000000000000'], ['2020-09-20', '20200920000000000000'], ['2020/09/20', '20200920000000000000'], ['20200920 1234', '20200920123400000000'], ['2020-09-20 12:34', '20200920123400000000'], ['2020/09/20 12:34', '20200920123400000000'], ['20200920T1234', '20200920123400000000'], ['20200920T123456.789', '20200920123456789000'], ['20200920T123456.789123', '20200920123456789123'], ['2020-09-20 12:34:56.789', '20200920123456789000'], ['2020-09-20 12:34:56.789123', '20200920123456789123'], ['2020/09/03 12:34:56.789', '20200903123456789000'], ['2020/09/03 12:34:56.789123', '20200903123456789123'], ['2020/9/3 12:34:56.789', '20200903123456789000'], ['2020/9/3 12:34:56.789123', '20200903123456789123'], ['20200903123456789123', '20200903123456789123'], ['20200903123456789123+0900', '20200903123456789123+0900'], ['20200920T123456.789123+0900', '20200920123456789123+0900'], ['20200920 1234 +0900', '20200920123400000000+0900'], ['2020-09-20 12:34 +0900', '20200920123400000000+0900'], ['2020/09/20 12:34 +0900', '20200920123400000000+0900']] for i in range(len(test_data)): data = test_data[i] data_in = data[0] data_expected = data[1] out = util.serialize_datetime(data_in) if out == data_expected: ret = 'OK' else: ret = 'NG' print('[' + ret + '] IN=' + data_in + ' ' + 'EXP=' + data_expected + ' OUT=' + out)
def generate_icalendar_invite(event, invite_type='request'): # Generates an iCalendar invite from an event. assert invite_type in ['request', 'cancel'] cal = iCalendar() cal.add('PRODID', '-//Nylas sync engine//nylas.com//') if invite_type in ['request', 'update']: cal.add('METHOD', 'REQUEST') elif invite_type == 'cancel': cal.add('METHOD', 'CANCEL') cal.add('VERSION', '2.0') cal.add('CALSCALE', 'GREGORIAN') icalendar_event = icalendar.Event() account = event.namespace.account organizer = icalendar.vCalAddress("MAILTO:{}".format( account.email_address)) if account.name is not None: organizer.params['CN'] = account.name icalendar_event['organizer'] = organizer icalendar_event['sequence'] = str(event.sequence_number) icalendar_event['X-MICROSOFT-CDO-APPT-SEQUENCE'] = icalendar_event[ 'sequence'] if invite_type == 'cancel': icalendar_event['status'] = 'CANCELLED' else: icalendar_event['status'] = 'CONFIRMED' icalendar_event['uid'] = "{}@nylas.com".format(event.public_id) icalendar_event['description'] = event.description or '' icalendar_event['summary'] = event.title or '' icalendar_event['last-modified'] = serialize_datetime(event.updated_at) icalendar_event['dtstamp'] = icalendar_event['last-modified'] icalendar_event['created'] = serialize_datetime(event.created_at) icalendar_event['dtstart'] = serialize_datetime(event.start) icalendar_event['dtend'] = serialize_datetime(event.end) icalendar_event['transp'] = 'OPAQUE' if event.busy else 'TRANSPARENT' icalendar_event['location'] = event.location or '' attendees = [] for participant in event.participants: email = participant.get('email', None) # FIXME @karim: handle the case where a participant has no address. # We may have to patch the iCalendar module for this. assert email is not None and email != "" attendee = icalendar.vCalAddress("MAILTO:{}".format(email)) name = participant.get('name', None) if name is not None: attendee.params['CN'] = name attendee.params['RSVP'] = 'TRUE' attendee.params['ROLE'] = 'REQ-PARTICIPANT' attendee.params['CUTYPE'] = 'INDIVIDUAL' status = participant.get('status', 'noreply') attendee.params['PARTSTAT'] = INVERTED_STATUS_MAP.get(status) attendees.append(attendee) if attendees != []: icalendar_event.add('ATTENDEE', attendees) cal.add_component(icalendar_event) return cal
def generate_icalendar_invite(event, invite_type='request'): # Generates an iCalendar invite from an event. assert invite_type in ['request', 'cancel'] cal = iCalendar() cal.add('PRODID', '-//Nylas sync engine//nylas.com//') if invite_type in ['request', 'update']: cal.add('METHOD', 'REQUEST') elif invite_type == 'cancel': cal.add('METHOD', 'CANCEL') cal.add('VERSION', '2.0') cal.add('CALSCALE', 'GREGORIAN') icalendar_event = icalendar.Event() account = event.namespace.account organizer = icalendar.vCalAddress(u"MAILTO:{}".format( account.email_address)) if account.name is not None: organizer.params['CN'] = account.name icalendar_event['organizer'] = organizer icalendar_event['sequence'] = str(event.sequence_number) icalendar_event['X-MICROSOFT-CDO-APPT-SEQUENCE'] = \ icalendar_event['sequence'] if invite_type == 'cancel': icalendar_event['status'] = 'CANCELLED' else: icalendar_event['status'] = 'CONFIRMED' icalendar_event['uid'] = u"{}@nylas.com".format(event.public_id) icalendar_event['description'] = event.description or '' icalendar_event['summary'] = event.title or '' icalendar_event['last-modified'] = serialize_datetime(event.updated_at) icalendar_event['dtstamp'] = icalendar_event['last-modified'] icalendar_event['created'] = serialize_datetime(event.created_at) icalendar_event['dtstart'] = serialize_datetime(event.start) icalendar_event['dtend'] = serialize_datetime(event.end) icalendar_event['transp'] = 'OPAQUE' if event.busy else 'TRANSPARENT' icalendar_event['location'] = event.location or '' attendees = [] for participant in event.participants: email = participant.get('email', None) # FIXME @karim: handle the case where a participant has no address. # We may have to patch the iCalendar module for this. assert email is not None and email != "" attendee = icalendar.vCalAddress(u"MAILTO:{}".format(email)) name = participant.get('name', None) if name is not None: attendee.params['CN'] = name attendee.params['RSVP'] = 'TRUE' attendee.params['ROLE'] = 'REQ-PARTICIPANT' attendee.params['CUTYPE'] = 'INDIVIDUAL' status = participant.get('status', 'noreply') attendee.params['PARTSTAT'] = INVERTED_STATUS_MAP.get(status) attendees.append(attendee) if attendees != []: icalendar_event.add('ATTENDEE', attendees) cal.add_component(icalendar_event) return cal
def generate_icalendar_invite(event, invite_type="request"): # Generates an iCalendar invite from an event. assert invite_type in ["request", "cancel"] cal = iCalendar() cal.add("PRODID", "-//Nylas sync engine//nylas.com//") if invite_type in ["request", "update"]: cal.add("METHOD", "REQUEST") elif invite_type == "cancel": cal.add("METHOD", "CANCEL") cal.add("VERSION", "2.0") cal.add("CALSCALE", "GREGORIAN") icalendar_event = icalendar.Event() account = event.namespace.account organizer = icalendar.vCalAddress(u"MAILTO:{}".format( account.email_address)) if account.name is not None and account.name != "": organizer.params["CN"] = account.name icalendar_event["organizer"] = organizer icalendar_event["sequence"] = str(event.sequence_number) icalendar_event["X-MICROSOFT-CDO-APPT-SEQUENCE"] = icalendar_event[ "sequence"] if invite_type == "cancel": icalendar_event["status"] = "CANCELLED" else: icalendar_event["status"] = "CONFIRMED" icalendar_event["uid"] = u"{}@nylas.com".format(event.public_id) icalendar_event["description"] = event.description or "" icalendar_event["summary"] = event.title or "" icalendar_event["last-modified"] = serialize_datetime(event.updated_at) icalendar_event["dtstamp"] = icalendar_event["last-modified"] icalendar_event["created"] = serialize_datetime(event.created_at) icalendar_event["dtstart"] = serialize_datetime(event.start) icalendar_event["dtend"] = serialize_datetime(event.end) icalendar_event["transp"] = "OPAQUE" if event.busy else "TRANSPARENT" icalendar_event["location"] = event.location or "" attendees = [] for participant in event.participants: email = participant.get("email", None) # FIXME @karim: handle the case where a participant has no address. # We may have to patch the iCalendar module for this. assert email is not None and email != "" attendee = icalendar.vCalAddress(u"MAILTO:{}".format(email)) name = participant.get("name", None) if name is not None: attendee.params["CN"] = name attendee.params["RSVP"] = "TRUE" attendee.params["ROLE"] = "REQ-PARTICIPANT" attendee.params["CUTYPE"] = "INDIVIDUAL" status = participant.get("status", "noreply") attendee.params["PARTSTAT"] = INVERTED_STATUS_MAP.get(status) attendees.append(attendee) if attendees != []: icalendar_event.add("ATTENDEE", attendees) cal.add_component(icalendar_event) return cal