def test_update_participant_status2(db, config): """Test the basic logic of the merge() function.""" base = _default_event(db) base.participants = [Participant(email_address="*****@*****.**", status="no")] dest = _default_event(db) dest.participants = [Participant(email_address="*****@*****.**", status="no")] participant1 = Participant(email_address="*****@*****.**", status="yes") remote = Event(account_id=ACCOUNT_ID, calendar=_default_calendar(db), subject='new subject', body='new body', location='new location', busy=True, read_only=True, reminders='', recurrence='', start=2, end=3, all_day=False, source='remote', participants=[participant1]) dest.merge_from(base, remote) assert len(dest.participants) == 1 assert dest.participants[0].status == 'yes'
def test_update_participant_status(db, config): """Test the basic logic of the merge() function.""" base = default_event(db) base.participants = [Participant(email_address="*****@*****.**")] dest = default_event(db) dest.participants = [Participant(email_address="*****@*****.**")] participant1 = Participant(email_address="*****@*****.**", status="yes") remote = default_event(db) remote.participants = [participant1] dest.merge_from(base, remote) assert len(dest.participants) == 1 assert dest.participants[0].status == 'yes'
def test_add_participant(db, config): """Test the basic logic of the merge() function.""" base = default_event(db) participant = Participant(email_address="*****@*****.**") remote = default_event(db) remote.participants = [participant] dest = default_event(db) dest.merge_from(base, remote) assert len(dest.participants) == 1
def test_multi_update(db, config): """Test the basic logic of the merge() function.""" base = default_event(db) base.participants = [ Participant(email_address="*****@*****.**", status="no") ] dest = default_event(db) dest.participants = [ Participant(email_address="*****@*****.**", status="no"), Participant(email_address="*****@*****.**", status="no") ] participant1 = Participant(email_address="*****@*****.**", status="yes") remote = default_event(db) remote.participants = [participant1] dest.merge_from(base, remote) assert len(dest.participants) == 2 for p in dest.participants: if p.email_address == "*****@*****.**": assert p.status == "yes" if p.email_address == "*****@*****.**": assert p.status == "no"
def parse_event(self, event, cal_info): """Constructs an Event object from a Google calendar entry. Parameters ---------- event: gdata.calendar.entry.CalendarEntry The Google calendar entry to parse. Returns ------- ..models.tables.base.Event A corresponding Inbox Event instance. Raises ------ MalformedEventError If the calendar data could not be parsed correctly. """ try: uid = str(event['id']) # The entirety of the raw event data in json representation. raw_data = str(event) # 'cancelled' events signify those instances within a series # that have been cancelled (for that given series). As such, # since full support for dealing with single instances within # a reocurring event series is not added, right now we just # treat this event as 'malformed'. -cg3 # TODO: Add support for reocurring events (see ways to handle # this generically across providers) if 'status' in event and event['status'] == 'cancelled': raise MalformedEventError() subject = event.get('summary', '')[:SUBJECT_MAX_LEN] body = event.get('description', None) location = event.get('location', None) if location: location = location[:LOCATION_MAX_LEN] all_day = False read_only = True is_owner = False start = event['start'] end = event['end'] g_reccur = event.get('recurrence', None) recurrence = str(g_reccur) if g_reccur else None busy = event.get('transparency', True) if busy == 'transparent': busy = False reminders = [] if 'dateTime' in start: if event['reminders']['useDefault']: reminder_source = cal_info['defaultReminders'] elif 'overrides' in event['reminders']: reminder_source = event['reminders']['overrides'] else: reminder_source = None if reminder_source: for reminder in reminder_source: reminders.append(reminder['minutes']) start = parse_datetime(start['dateTime']) end = parse_datetime(end['dateTime']) else: start = date_parser.parse(start['date']) end = date_parser.parse(end['date']) all_day = True reminders = str(reminders) # Convert google's notion of status into our own participants = [] status_map = {'accepted': 'yes', 'needsAction': 'noreply', 'declined': 'no', 'tentative': 'maybe'} for attendee in event.get('attendees', []): g_status = attendee.get('responseStatus') if g_status not in status_map: raise MalformedEventError() status = status_map[g_status] email = attendee.get('email') if not email: raise MalformedEventError() name = attendee.get('displayName') notes = None if 'additionalGuests' in attendee: notes = "Guests: {}".format(attendee['additionalGuests']) if 'comment' in attendee: notes += " Notes: {}".format(attendee['comment']) elif 'comment' in attendee: notes = "Notes: {}".format(attendee['comment']) participants.append(Participant(email_address=email, name=name, status=status, notes=notes)) if 'self' in event['creator']: is_owner = True read_only = False elif 'guestsCanModify' in event: read_only = False owner = "{} <{}>".format(event['creator']['displayName'], event['creator']['email']) except (KeyError, AttributeError): raise MalformedEventError() return Event(account_id=self.account_id, uid=uid, provider_name=self.PROVIDER_NAME, raw_data=raw_data, subject=subject, body=body, location=location, reminders=reminders, recurrence=recurrence, start=start, end=end, owner=owner, is_owner=is_owner, busy=busy, all_day=all_day, read_only=read_only, source='remote', participants=participants)
def events_from_ics(namespace, calendar, ics_str): try: cal = Calendar.from_ical(ics_str) except ValueError: raise MalformedEventError() events = [] for component in cal.walk(): if component.name == "VEVENT": start = component.get('dtstart').dt end = component.get('dtend').dt title = component.get('summary') description = str(component.get('description')) if isinstance(start, datetime): all_day = False else: all_day = True start = datetime.combine(start, datetime.min.time()) end = datetime.combine(end, datetime.min.time()) reccur = component.get('rrule') if reccur: reccur = reccur.to_ical() else: reccur = '' participants = [] for attendee in component.get('attendee'): email = str(attendee) # strip mailto: if it exists if email.startswith('mailto:'): email = email[7:] try: name = attendee.params['CN'] except KeyError: name = None status_map = { 'NEEDS-ACTION': 'noreply', 'ACCEPTED': 'yes', 'DECLINED': 'no', 'TENTATIVE': 'maybe' } status = 'noreply' try: a_status = attendee.params['PARTSTAT'] status = status_map[a_status] except KeyError: pass notes = None try: guests = attendee.params['X-NUM-GUESTS'] notes = "Guests: {}".format(guests) except KeyError: pass participant = Participant(email_address=email, status=status, name=name, notes=notes) participants.append(participant) location = component.get('location') organizer = component.get('organizer') if (organizer): organizer = str(organizer) if organizer.startswith('mailto:'): organizer = organizer[7:] uid = str(component.get('uid')) event = Event(namespace=namespace, calendar=calendar, uid=uid, provider_name='ics', raw_data=component.to_ical(), title=title, description=description, location=location, reminders=str([]), recurrence=reccur, start=start, end=end, busy=True, all_day=all_day, read_only=True, source='local') event.participants = participants events.append(event) return events