def icalendar(self): cal = Calendar() cal.add('version', '2.0') cal.add('prodid', '-//Medical appointement//') cal.add('calscale', 'GREGORIAN') cal.add('method', 'PUBLISH') cal.add('x-wr-calname', '[Medagenda] appointment') cal.add('x-wr-timezone', self.refer_doctor.timezone) cal.add('x-wr-caldesc', '') event = Event() title = '[Medical appointment] %s' % str(self.refer_doctor.full_name()) event.add('dtstart', self.start_dt()) event.add('dtend', self.end_dt()) event.add('dtstamp', datetime.now(pytz.timezone(str(self.refer_doctor.timezone)))) event.add('created', datetime.now(pytz.timezone(str(self.refer_doctor.timezone)))) event['description'] = vText(_(u"Medical consultation with %s" % self.refer_doctor.full_name())) event.add('last-modified', datetime.now(pytz.timezone(str(self.refer_doctor.timezone)))) event['location'] = vText(self.refer_doctor.address.formatted) event.add('sequence', 0) event['status'] = vText('CONFIRMED') event.add('summary', title) event['transp'] = vText('OPAQUE') cal.add_component(event) f = open(self.path, 'wb') f.write(cal.to_ical()) f.close()
def __init__(self, text, name=None): self.ical = icalendar.Calendar.from_ical(text) self._name = name if not self._name: # Try to find the element's name for c in self.ical.walk(): if c.get('X-CAL9-NAME'): self._name = str(c.get('X-CAL9-NAME')) break elif c.get('TZID'): self._name = str(c.get('TZID')) break elif c.get('UID'): self._name = str(c.get('UID')) # Do not break, X-CAL9-NAME can still appear if not self._name: # The name is still not found, define one import uuid self._name = str(uuid.uuid4()) # Now redefine the X-CAL9-NAME property for c in self.ical.walk(): if c.get('X-CAL9-NAME'): c['X-CAL9-NAME'] = icalendar.vText(self._name) break else: self.ical['X-CAL9-NAME'] = icalendar.vText(self._name)
def build_calendar(issues, ics_path): cal = Calendar() for i in issues: event = Event() if "Full" in str(i.status): summary = "[COMPLET] " + i.subject else: summary = i.subject event.add('summary', summary) event.add('description', i.description) event['uid'] = i.id for c in i.custom_fields: if c.id == 20: # 20 is 'debut' start_time = str(c.value).replace(':', '')+"00" if c.id == 21: # 21 is 'fin' end_time = str(c.value).replace(':', '')+"00" event['dtstart'] = i.due_date.replace('/','')+"T"+start_time event['dtend'] = i.due_date.replace('/','')+"T"+end_time event['dtstamp'] = vDatetime(now).to_ical() organizer = vCalAddress('MAILTO:[email protected]') organizer.params['cn'] = vText('Les fruits défendus') event['organizer'] = organizer event['location'] = vText('Montréal, QC') cal.add_component(event) f = open(ics_path, 'wb') f.write(cal.to_ical()) f.close()
def recycle_data_to_ical(data): cal = icalendar.Calendar() cal.add('prodid', '-//Edinburgh Recycling//{}'.format(data['location'])) cal.add('version', '1.0') calendar_name = vText('Edinburgh Recycling - {}'.format(data['location'])) cal['X-WR-CALNAME'] = calendar_name cal['X-WR-CALDESC'] = calendar_name cal['X-WR-TIMEZONE'] = vText('Europe/London') location_ical = vText('{}, Edinburgh'.format(data['location'])) for date in data.get('blue_dates', []): event = icalendar.Event() event.add('Summary', 'Blue bin collection') event.add('dtstart', date) event['location'] = location_ical event['description'] = data['pdf_link'] cal.add_component(event) for date in data.get('red_dates', []): event = icalendar.Event() event.add('Summary', 'Red bin collection') event.add('dtstart', date) event['location'] = location_ical event['description'] = data['pdf_link'] cal.add_component(event) return cal
def create_calendar_with_metadata (): cal = icalendar.Calendar() cal['prodid'] = icalendar.vText(u'-//Techism//Techism//DE') cal['version'] = icalendar.vText(u'2.0') cal['x-wr-calname'] = icalendar.vText(u'Techism') cal['x-wr-caldesc'] = icalendar.vText(u'Techism - Events, Projekte, User Groups in München') return cal
def create_milestone(milestone, author, projectname): print("\tAdding Milestone ID {} with title: {}".format(milestone.id, milestone.title)) event = Event() # Parse due date dyear, dmonth, dday = milestone.due_date.split('-') event['uid'] = '{}/{}@{}'.format(milestone.created_at, author.username, CALENDAR_FQDN) event.add('summary', milestone.title) description = "{}\n\n---> {} <---\n".format(milestone.description, projectname) event.add('description', description) event.add('dtstart', date(int(dyear), int(dmonth), int(dday))) # event.add('dtend', datetime(2016,7,12,12,0,0,tzinfo=pytz.utc)) event.add('dtstamp', datetime.utcnow()) # event['location'] = vText('Koeln, Deutschland') event.add('categories', "Milestone") event.add('priority', 2) organizer = vCalAddress('{}@{}'.format(author.username, CALENDAR_FQDN)) organizer.params['cn'] = vText(author.name) organizer.params['role'] = vText('Author') event['organizer'] = organizer return event
def to_ical_event(ev): """ Convert Eventure Event to ical (CalDAV) string format Params: ev: core.models.event """ cal = Calendar() cal.add('prodid', '-//Eventure Interactive.//CalDAV Client//EN') cal.add('version', '2.0') event = iEvent() event.add('summary', ev.title) event.add('dtstart', ev.start) event.add('dtend', ev.end) event.add('dtstamp', ev.created) event.add('uid', 'EVENTURE-' + str(ev.id)) event['location'] = vText(ev.location) # Add Guests for guest in ev.guests.all(): attendee = vCalAddress('MAILTO:%s' % (guest.email)) attendee.params['cn'] = vText(guest.name) attendee.params['ROLE'] = vText('REQ-PARTICIPANT') event.add('attendee', attendee, encode=0) cal.add_component(event) return cal.to_ical()
def CreateReminder(cal, days, text, fromaddress): """Creates a calendar entry in days days with title text. Args: cal: A Calendar. days: How many days in the future to create the reminder. text: The calendar summary Returns: A calendar entry. """ event = Event() event.add('summary', text) eventdate = datetime.datetime.now() + datetime.timedelta(days=int(days)) event.add('dtstart',eventdate) event.add('dtend', eventdate) event.add('dtstamp', eventdate) event['uid'] = str(uuid.uuid1()) + '@kumari.net' event.add('priority', 5) organizer = vCalAddress('MAILTO:%s' % fromaddress) organizer.params['cn'] = vText('%s' % fromaddress) organizer.params['role'] = vText('CHAIR') event['organizer'] = organizer event['location'] = vText('Online') cal.add_component(event) return cal
def generate_ical(self): """Generate an ical file.""" cal = icalendar.Calendar() ical_file = open(self.rota_ical, 'w') counter = 1 if not ical_file: print("Error creating ical file.", file=sys.stderr) sys.exit(-1) for data in self.rota: name, talk_title, title_blog, rota_date = data rota_date = datetime.combine(rota_date, datetime.min.time()) rota_date = rota_date.replace(tzinfo=self.tz) session = icalendar.Event() session['uid'] = rota_date.isoformat() session['dtstart'] = icalendar.vDatetime(rota_date + self.the_time_start) session['dtend'] = icalendar.vDatetime(rota_date + self.the_time_end) session['location'] = icalendar.vText(self.rota_location) session['summary'] = icalendar.vText("{} - {}".format(name, talk_title)) cal.add_component(session) counter += 1 new_cal = cal.to_ical().decode('utf-8').replace('\r\n', '\n').strip() # print(new_cal) print(new_cal, file=ical_file) ical_file.close() print("[Output] ics file written: {}".format(self.rota_ical))
def createAttendee(address): """create a complete random attendee entry for a event for the address""" attendee = address.toVCalAdddress() attendee.params['CUTYPE'] = vText('INDIVIDUAL') attendee.params['PARTSTAT'] = vText(random.choice(PARTSTAT)) attendee.params['RSVP'] = vText(random.choice(RSVP)) attendee.params['ROLE'] = vText(random.choice(ROLE)) return attendee
def examples_for_term(course_year, term): examples = list(course_year.examples(term)) events = [] for example in examples: events.append(icalendar.Event( summary='P{0.paper_no}: {0.name} - Example paper {0.sheet_no}'.format(example), dtstart=icalendar.vDatetime(timezone.localize(example.class_start).astimezone(pytz.utc)), dtend=icalendar.vDatetime(timezone.localize(example.class_end).astimezone(pytz.utc)), dtstamp=icalendar.vDatetime(last_updated), location=icalendar.vText( "{} - {}".format(example.class_location, cued_address) if example.class_location else cued_address ), uid='{0.paper_no}-{0.sheet_no}.{term}.{part}@efw27.user.srcf.net'.format( example, term=term, part=course_year.part ), description=icalendar.vText('Lecturer: {.class_lecturer}'.format(example)) )) # group and order by issue date, ignoring those issued the previous term issue_key = lambda e: e.issue_date examples = filter(issue_key, examples) examples = sorted(examples, key=issue_key) examples = itertools.groupby(examples, issue_key) for i, (issue_date, papers) in enumerate(examples): # consume the iterable so that we can len() it papers = list(papers) events.append(icalendar.Event( summary='Collect {} example paper{}'.format(len(papers), '' if len(papers) == 1 else 's'), dtstart=icalendar.vDate(timezone.localize(issue_date).astimezone(pytz.utc)), dtend=icalendar.vDate(timezone.localize(issue_date).astimezone(pytz.utc)), dtstamp=icalendar.vDatetime(last_updated), location=icalendar.vText(cued_address), uid='collection-{i}.{term}.{part}@efw27.user.srcf.net'.format( i=i, term=term, part=course_year.part ), description=icalendar.vText('\n'.join( 'P{0.paper_no}: {0.name} - Example paper {0.sheet_no}'.format(p) for p in papers )) )) return events
def create_calendar_with_metadata (event_list, request): cal = icalendar.Calendar() cal['prodid'] = icalendar.vText(u'-//Techism//Techism//DE') cal['version'] = icalendar.vText(u'2.0') cal['x-wr-calname'] = icalendar.vText(u'Techism') cal['x-wr-caldesc'] = icalendar.vText(u'Techism - Events, Projekte, User Groups in München') for e in event_list: event = create_ical_entry(e, request) cal.add_component(event) return cal
def duplicate(self): """duplicate this event's PROTO event :rtype: Event """ new_uid = generate_random_uid() vevent = self._vevents['PROTO'].copy() vevent['SEQUENCE'] = 0 vevent['UID'] = icalendar.vText(new_uid) vevent['SUMMARY'] = icalendar.vText(vevent['SUMMARY'] + ' Copy') event = self.fromVEvents([vevent]) event.calendar = self.calendar return event
def __init__(self, context, request): super(AgendaCalendar, self).__init__() self['PRODID'] = \ vText('-//Infrae SilvaNews Calendaring//NONSGML Calendar//EN') self['VERSION'] = '2.0' self['X-WR-CALNAME'] = vText(context.get_title()) self['X-WR-TIMEZONE'] = vText(context.get_timezone_name()) now = datetime.now(UTC) for brain in context.get_items_by_date_range( now + relativedelta(years=-1), now + relativedelta(years=+1)): factory = getMultiAdapter((brain.getObject(), request), IEvent) for event in factory(context): self.add_component(event)
def add_organizer(self, element): value = self._get_element_text(element, 'organizer') parsed = EmailParser().parse(value) if not parsed: return name = parsed[0].strip().strip('"') organizer = vCalAddress('MAILTO:%s' % parsed[1]) organizer.params['cn'] = vText(name) organizer.params['ROLE'] = vText('CHAIR') self.add('organizer', organizer, encode=0)
def icalize(events): cal = Calendar() now = arrow.get() cal.add('prodid', '-//Yaypython//python.org//') cal.add('version', '2.0') for header, description, url, start, end in events: ev = Event() ev.add('summary', vText(header)) ev.add('description', vText(description)) ev.add('location', url) ev.add('dtstart', start.datetime) ev.add('dtend', end.datetime) ev.add('last-modified', now.datetime) cal.add_component(ev) return cal.to_ical().decode('utf-8')
def event_detail_ics(request, slug): event_obj = get_object_or_404(Event.published, slug__exact=slug) calendar = Calendar() calendar.add('prodid', '-//US Ignite//us-ignite.org//') calendar.add('version', '2.0') event = CalEvent() event.add('summary', event_obj.name) url = '%s%s' % (settings.SITE_URL, event_obj.get_absolute_url()) description = event_obj.description + '\n\n' + url event.add('description', description) event.add('url', url) event['location'] = vText(event_obj.address) # Use timezone aware datetime objects: event_tz = pytz.timezone(_swap_timezone(event_obj.timezone)) event.add('dtstart', event_obj.start_datetime.astimezone(event_tz)) if event_obj.end_datetime: event.add('dtend', event_obj.end_datetime.astimezone(event_tz)) event.add('dtstamp', timezone.now()) event['uid'] = 'event-%s/@us-ignite.org' % (event_obj.pk) event.add('priority', 5) calendar.add_component(event) file_name = 'event-%s.ics' % event_obj.slug response = HttpResponse(calendar.to_ical(), content_type='text/calendar') response['Content-Disposition'] = 'attachment; filename="%s"' % file_name return response
def get_ics_event(self): ievent = icalendar.Event() ievent['summary'] = self.event.title ievent['dtstart'] = icalendar.vDatetime(self.when.lower).to_ical() ievent['dtend'] = icalendar.vDatetime(self.when.upper).to_ical() ievent['location'] = icalendar.vText(self.location.name) return ievent
def add_attendee(self, email, cn=None, rsvp=True): """ Add an attendee to the event. If the event is being sent via an email, the recipient should be added as an attendee. :param str email: The attendee's email address. :param str cn: The attendee's common name. :param bool rsvp: Whether or not to request an RSVP response from the attendee. """ attendee = icalendar.vCalAddress('MAILTO:' + email) attendee.params['ROLE'] = icalendar.vText('REQ-PARTICIPANT') attendee.params['PARTSTAT'] = icalendar.vText('NEEDS-ACTION') attendee.params['RSVP'] = icalendar.vText(str(bool(rsvp)).upper()) attendee.params['CN'] = icalendar.vText(cn or email) self._event.add('attendee', attendee)
def export_ical(events): cal = Calendar() site = Site.objects.get_current() cal.add('prodid', '-//%s Events Calendar//%s//' % (site.name, site.domain)) cal.add('version', '2.0') site_token = site.domain.split('.') site_token.reverse() site_token = '.'.join(site_token) for event in events: ical_event = Event() ical_event.add('summary', event.title) ical_event.add('description', event.body) ical_event.add('dtstart', event.start_datetime) ical_event.add('dtend', event.end_datetime) ical_event.add('dtstamp', event.end_datetime) ical_event.add('url', vUri('http://' + site.domain + event.get_absolute_url())) ical_event['location'] = vText(event.location) ical_event['uid'] = '%d.event.events.%s' % (event.id, site_token) cal.add_component(ical_event) return cal
def calendar(content=None,method='PUBLISH',version='2.0',reminder=None): r""" :param content: list of events :type content: list(:class:`icalendar.Event`) :param reminder: reminder :type reminder: :class:`datetime.timedelta` :param method: ics method for the icalendar :type method: :const:`str` :param version: icalendar version;should not be changed :type version: :const:`str` :rtype: :class:`icalendar.Calendar` Return a calendar object listing all the events in *content*, possibly augmented, for those confirmed, with a reminder specified by *reminder* (from start). """ cal = icalendar.Calendar() cal.add('prodid','-//ChronoManager//0.1') cal.add('version',version) cal.add('method',method) alarm = None if reminder is not None: rmdr = icalendar.vDuration(reminder) rmdr.params['related'] = icalendar.vText('START') alarm = icalendar.Alarm() alarm.add('action','DISPLAY') alarm.add('description','REMINDER') alarm.add('trigger',rmdr,0) for evt in content: if evt.get('status')=='CONFIRMED' and alarm is not None: evt.add_component(alarm) cal.add_component(evt) return cal
def create_event(self, name, room, the_day, dBegin, dEnd): event = Event() event.add('summary', name) event.add('dtstart', dBegin) event.add('dtend', dEnd) event['location'] = vText(room) return event
def test_can_download_valid_ical(self): """ 正しい形式のiCalファイルをダウンロードできる """ from icalendar import Calendar from icalendar import vDatetime, vText e = EventFactory() user = PersonaFactory() e.attend(user) e.save() r = self.client.get('/events/{}/calendar/'.format(e.pk)) for content in r.streaming_content: cal = Calendar.from_ical(content) self.assertEqual(cal['version'], '2.0') self.assertEqual(cal['PRODID'], 'Kawaz') for component in cal.walk(): if component.name == 'VEVENT': self.assertEqual(component['summary'], e.title) self.assertEqual(component['description'], e.body) self.assertEqual(component['location'], e.place) self.assertEqual(component['dtstamp'].to_ical(), vDatetime(e.created_at).to_ical()) self.assertEqual(component['dtstart'].to_ical(), vDatetime(e.period_start).to_ical()) self.assertEqual(component['dtend'].to_ical(), vDatetime(e.period_end).to_ical()) self.assertEqual(component['class'].to_ical(), vText('PUBLIC').to_ical()) self.assertEqual(component['organizer'].params['cn'], e.organizer.nickname) self.assertEqual(component['organizer'].params['role'], e.organizer.role) # ATENDEEがセットされている for attendee, cal_attendee in zip(e.attendees.all(), component['attendee']): self.assertEqual(cal_attendee.params['cn'], attendee.nickname) self.assertEqual(cal_attendee.params['role'], attendee.role)
def add_event(cal, summary, start, end, location=u'珠江医院'): print(u'add event {}: from {} to {}'.format(summary, start, end)) e = Event() e.add('dtstart', start) e.add('dtend', end) e.add('summary', summary) e['location'] = vText(location) cal.add_component(e)
def generateEventFeed(event): logger.info(u'Generating ICS feed for event {0}...'.format(event.__unicode__())) cal = icalendar.Calendar() cal.add('prodid', u'-//Niujorko renginių kalendorius//LT//') cal.add('version', '2.0') cal.add('method', 'PUBLISH') cal.add('calscale', 'GREGORIAN') cal.add('x-wr-calname', event.title) cal.add('x-wr-timezone', settings.TIME_ZONE) cal.add('x-original-url', DOMAIN + 'renginiai/{0}'.format(event.id)) e = icalendar.Event() e.add('uid', 'event_{0}@nylithuanian.org'.format(event.id)) e.add('created', event.create_date) e.add('last-modified', event.modify_date) e.add('summary', event.title) e.add('description', defaultfilters.truncatewords(event.body, 100) + '\nDaugiau informacijos: ' + DOMAIN + 'renginiai/{0}'.format(event.id)) e.add('sequence', event.version_number) e.add('class', 'PUBLIC') e.add('status', 'CONFIRMED') e.add('url', DOMAIN + 'renginiai/{0}'.format(event.id)) if not event.start_date: logger.warning(u'Event start date is null, skipping entry in ICS feed...') else: e.add('dtstart', event.start_date) if event.end_date: e.add('dtend', event.end_date) elif event.start_date: e.add('dtend', event.start_date + timedelta(hours=2)) # default event length: 2 hours if event.get_full_address(): e['location'] = icalendar.vText(event.get_full_address()) if event.email_address: organizer = icalendar.vCalAddress("MAILTO:{0}".format(event.email_address)) organizer.params['cn'] = icalendar.vText(event.get_organizer_full_name()) e['organizer'] = organizer cal.add_component(e) logger.info(u'Generated ICS event feed:\n{0}'.format(smart_text(cal.to_ical()))) return cal.to_ical()
def test_str_to_v_text(self): # Arrange. s = 'Hello, world' # Act. v_text = icalendar.vText(s) # Assert. self.assertEqual(type(v_text), icalendar.prop.vText) self.assertEqual(v_text.to_ical(), b'Hello\\, world')
def test_create_entry(pytestconfig): # cook up a datetime for our calendar entry (dt_now, dt_mtg_start, dt_mtg_end) = start_two_hours_from_now() dt_cal_start = dt_now - timedelta(10) # example script to add X-MAINTNOTE to an ical cal = Calendar() cal.add('prodid', '-//Maint Note//https://github.com/maint-notification//') cal.add('version', '2.0') event = xmaintnote.XMaintNoteEvent() event.add('summary', 'Maint Note Example') event.add('uid', '42') event.add('sequence', 1) event.add('dtstart', dt_mtg_start) event.add('dtend', dt_mtg_end) event.add('dtstamp', dt_now) organizer = vCalAddress('mailto:[email protected]') organizer.params['cn'] = vText('Example NOC') event['organizer'] = organizer # maintnote stuff event.add('x-maintnote-provider', 'example.com' ) event.add('x-maintnote-account', '137.035999173' ) event.add('x-maintnote-maintenance-id', 'WorkOrder-31415' ) event.add('x-maintnote-object-id', 'acme-widgets-as-a-service' ) event.add('x-maintnote-impact', "NO-IMPACT"); # test the regex #event.add('x-maintnote-impact', "GARBAGE"); if 0: organizer = vCalAddress('MAILTO:[email protected]') organizer.params['cn'] = vText('Max Rasmussen') organizer.params['role'] = vText('CHAIR') event['organizer'] = organizer event['location'] = vText('Odense, Denmark') event['uid'] = '20050115T101010/[email protected]' event.add('priority', 5) attendee = vCalAddress('MAILTO:[email protected]') attendee.params['cn'] = vText('Max Rasmussen') attendee.params['ROLE'] = vText('REQ-PARTICIPANT') event.add('attendee', attendee, encode=0) attendee = vCalAddress('MAILTO:[email protected]') attendee.params['cn'] = vText('The Dude') attendee.params['ROLE'] = vText('REQ-PARTICIPANT') event.add('attendee', attendee, encode=0) cal.add_component(event) expected_output = pytestconfig.rootdir.join('tests/example.ical') assert display(cal) == expected_output.read().strip()
def main(*, args): params = docopt.docopt( doc=__doc__.format( prog=__prog__, ), argv=args, help=True, version=__version__, options_first=False, ) assert params.pop("--help") == False assert params.pop("--version") == False dtstart = parse_dt(params.pop("START_DT_WITH_TIMEZONE")) dtend = parse_dt(params.pop("END_DT_WITH_TIMEZONE")) summary = params.pop("--summary") or "Event" description = params.pop("--description") or f"Generated By: {__product__}" url = params.pop("--url") attachments = params.pop("--attachment") output_path = params.pop("--output") assert not params, params print("Summary: {}" .format(summary)) print("Start: {:%c %z}".format(dtstart)) print("End: {:%c %z}".format(dtend)) print("Duration: {}" .format(dtend - dtstart)) print("Description: {}" .format(description)) print(file=sys.stderr) event = icalendar.Event() event.add("SUMMARY", icalendar.vText(summary)) event.add("DESCRIPTION", icalendar.vText(description)) event.add("DTSTART", icalendar.vDatetime(dtstart)) event.add("DTEND", icalendar.vDatetime(dtend)) if url is not None: event.add("URL", icalendar.vUri(url)) for path in attachments: add_attachment_to_calendar_event(event, path) calendar = icalendar.Calendar() #TODO:vruyr:bugs Verify with the standard. calendar.add("PRODID", f"-//{__product__}//vruyr.com//EN") calendar.add("VERSION", "2.0") calendar.add_component(event) with open(output_path, "wb") as fo: fo.write(calendar.to_ical())
def get_ical_organizer(self): contact = self.get_organizer() organizer = icalendar.vCalAddress("MAILTO:%s" % contact.email()) name = contact.name() if not name == None and not name == "": organizer.params["CN"] = icalendar.vText(name) return organizer
def _add_participant_to_ical_event(event, participant): """Adds a participant as an attendee to an ical event.""" attendee = _email_to_vcal_address(participant.email) attendee.params['cn'] = vText(participant.name) attendee.params['ROLE'] = vText('REQ-PARTICIPANT') event.add('attendee', attendee, encode=0)
def events_to_ical(events, identifier, contact=True): connection = db.connect() cursor = connection.cursor(db.DictCursor) ical = Calendar() ical.add('calscale', 'GREGORIAN') ical.add('prodid', '-//Oncall//Oncall calendar feed//EN') ical.add('version', '2.0') ical.add('x-wr-calname', '%s Oncall Calendar' % identifier) users = {} for event in events: username = event['user'] if username not in users: if contact: cursor.execute( ''' SELECT `user`.`full_name` AS full_name, `contact_mode`.`name` AS contact_mode, `user_contact`.`destination` AS destination FROM `user_contact` JOIN `contact_mode` ON `contact_mode`.`id` = `user_contact`.`mode_id` JOIN `user` ON `user`.`id` = `user_contact`.`user_id` WHERE `user`.`name` = %s ''', username) else: cursor.execute( ''' SELECT `user`.`full_name` AS full_name FROM `user` WHERE `user`.`name` = %s ''', username) info = {'username': username, 'contacts': {}} for row in cursor: info['full_name'] = row['full_name'] if contact: info['contacts'][row['contact_mode']] = row['destination'] users[username] = info user = users[username] # Create the event itself full_name = user.get('full_name', user['username']) cal_event = Event() cal_event.add('uid', 'event-%s@oncall' % event['id']) cal_event.add('dtstart', dt.fromtimestamp(event['start'], utc)) cal_event.add('dtend', dt.fromtimestamp(event['end'], utc)) cal_event.add('dtstamp', dt.utcnow()) cal_event.add( 'summary', '%s %s shift: %s' % (event['team'], event['role'], full_name)) cal_event.add( 'description', '%s\n' % full_name + ('\n'.join([ '%s: %s' % (mode, dest) for mode, dest in user['contacts'].items() ]) if contact else '')) # Attach info about the user oncall attendee = vCalAddress( 'MAILTO:%s' % (user['contacts'].get('email') if contact else '')) attendee.params['cn'] = vText(full_name) attendee.params['ROLE'] = vText('REQ-PARTICIPANT') cal_event.add('attendee', attendee, encode=0) ical.add_component(cal_event) cursor.close() connection.close() return ical.to_ical()
def next_30_min(h, m): h = (h + (m + 30 == 60)) % 24 m = (m + 30) % 60 return h, m cal = Calendar() with open("data.txt", encoding="utf-8") as f: day = [] for line in f: if not len(line.strip()): pass elif line[0] == "-": # new day from DD/MM/YYYY day = list(map(int, line[1:].split("/")[::-1])) else: p = line.strip().split(" ") time, name, link = p[0], " ".join(p[1:-1]), p[-1] h, m = map(int, time.split("h")) e = Event() e.add("summary", name) e.add('dtstart', datetime(*day, h, m, tzinfo=timezone.utc)) e.add('dtend', datetime(*day, *next_30_min(h, m), tzinfo=timezone.utc)) e["location"] = vText(link) cal.add_component(e) print(cal.to_ical()) with open("out.ics", "w", encoding="utf-8") as o: o.write(cal.to_ical().decode("utf-8").replace("\r\n", "\n"))
def writeIcal(calendarItems): """ Write ICAL and CSV files """ cal = Calendar() cal.add('prodid', '-//Gremien Kalender//opendata.stadt-muenster.de//') cal.add('version', '2.0') with open(OUTPUT_FILE_CSV, 'w', newline='') as csvfile: csvWriter = csv.writer(csvfile, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) csvWriter.writerow([ 'MeetingID', 'Start', 'Ende', 'Gremium', 'Veranstaltung', 'Ort', 'Weitere Information' ]) for key, session in sorted(calendarItems.items()): # Prepare event title (and convert datestrings to datetime objects with timezone) meetingId = session[5] sessionName = session[2] committee = session[3] location = session[4] start = datetime.strptime(session[0], "%Y-%m-%dT%H:%M:%S%z") end = datetime.strptime(session[1], "%Y-%m-%dT%H:%M:%S%z") meetingUrl = OPARL_MEETING_URL.format(meetingId) logging.info("Adding ical: %s %s %s", start, committee, sessionName) # Create ical event (and convert datetimes to UTC) event = Event() event.add('summary', '{} - {}'.format(committee, sessionName)) event.add('dtstart', start.astimezone(pytz.utc)) event.add('dtend', end.astimezone(pytz.utc)) event.add('dtstamp', datetime.now()) event.add('description', meetingUrl) event.add('uid', '20220215T101010/{}@ms'.format(meetingId)) organizer = vCalAddress('MAILTO:[email protected]') organizer.params['cn'] = vText('Stadt Münster') organizer.params['role'] = vText('Ratsinformationssytem') event['organizer'] = organizer event['location'] = vText(location) # Add event to calendar cal.add_component(event) # Add event to CSV csvWriter.writerow([ meetingId, str(start), str(end), committee, sessionName, location, meetingUrl ]) # Write ical file f = open(OUTPUT_FILE_ICS, 'wb') f.write(cal.to_ical()) f.close()
def to_ical(self): participant = vCalAddress("MAILTO:%s" % self.email) participant.params["cn"] = vText(self.name) participant.params["role"] = vText(self.role) return participant
def test_event_alarm(): event = Event.fromString(_get_text('event_dt_simple'), **EVENT_KWARGS) assert event.alarms == [] event.update_alarms([(timedelta(-1, 82800), 'new event')]) assert event.alarms == [(timedelta(-1, 82800), vText('new event'))]
# either of these work fine #event = Event() event = xmaintnote.XMaintNoteEvent() event.add('summary', 'Maint Note Example') event.add('uid', '42') event.add('sequence', 1) #event.add('dtstart', datetime(2015, 10, 10, 8, 0, 0, tzinfo=pytz.utc)) #event.add('dtend', datetime(2015, 10, 10, 10, 0, 0, tzinfo=pytz.utc)) #event.add('dtstamp', datetime(2015, 10, 10, 0, 10, 0, tzinfo=pytz.utc)) event.add('dtstart', dt_mtg_start) event.add('dtend', dt_mtg_end) event.add('dtstamp', dt_now) organizer = vCalAddress('mailto:[email protected]') organizer.params['cn'] = vText('Example NOC') event['organizer'] = organizer # maintnote stuff event.add('x-maintnote-provider', 'example.com') event.add('x-maintnote-account', '137.035999173') event.add('x-maintnote-maintenance-id', 'WorkOrder-31415') maint_object = vText('acme-widgets-as-a-service') maint_object.params['ALTREP'] = vText( 'https://example.org/maintenance?id=acme-widgets-as-a-service') event.add('x-maintnote-object-id', maint_object) event.add('x-maintnote-impact', "NO-IMPACT") event.add('x-maintnote-status', "TENTATIVE") # test the regex
cal.add('prodid', '-//My calendar thing') cal.add('version', '2.0') import pytz event = icalendar.Event() event.add('summary', 'This is the summary :D') event.add('dtstart', datetime(2005, 4, 4, 8, 0, 0, tzinfo=pytz.utc)) event.add('dtend', datetime(2005, 4, 4, 10, 0, 0, tzinfo=pytz.utc)) event.add('dtstamp', datetime(2005, 4, 4, 0, 10, 0, tzinfo=pytz.utc)) from icalendar import vCalAddress, vText organizer = vCalAddress('MAILTO:[email protected]') organizer.params['cn'] = vText('Max Rasmussen') organizer.params['role'] = vText('CHAIR') event['organizer'] = organizer event['location'] = vText('Odense, Denmark') event['uid'] = '20050115T101010/[email protected]' event.add('priority', 5) attendee = vCalAddress('MAILTO:[email protected]') attendee.params['cn'] = vText('Max Rasmussen') attendee.params['ROLE'] = vText('REQ-PARTICIPANT') event.add('attendee', attendee, encode=0) attendee = vCalAddress('MAILTO:[email protected]') attendee.params['cn'] = vText('The Dude') attendee.params['ROLE'] = vText('REQ-PARTICIPANT')
def get(self, request): items = Cohort.objects.all() ids = request.GET.get('academy', '') slugs = request.GET.get('academy_slug', '') ids = ids.split(",") if ids else [] slugs = slugs.split(",") if slugs else [] if ids: items = Cohort.objects.filter(academy__id__in=ids).order_by('id') elif slugs: items = Cohort.objects.filter( academy__slug__in=slugs).order_by('id') else: items = [] if not ids and not slugs: raise ValidationException( "You need to specify at least one academy or academy_slug (comma separated) in the querystring" ) if (Academy.objects.filter(id__in=ids).count() != len(ids) or Academy.objects.filter(slug__in=slugs).count() != len(slugs)): raise ValidationException("Some academy not exist") items = items.exclude(stage='DELETED') upcoming = request.GET.get('upcoming') if upcoming == 'true': now = timezone.now() items = items.filter(kickoff_date__gte=now) academies_repr = ical_academies_repr(ids=ids, slugs=slugs) key = server_id() calendar = iCalendar() calendar.add( 'prodid', f'-//BreatheCode//Academy Cohorts{academies_repr} {key}//EN') calendar.add('X-WR-CALNAME', f'Academy - Cohorts') calendar.add('X-WR-CALDESC', '') calendar.add('REFRESH-INTERVAL;VALUE=DURATION', 'PT15M') url = os.getenv('API_URL') if url: url = re.sub(r'/$', '', url) + '/v1/events/ical/cohorts' if ids or slugs: url = url + '?' if ids: url = url + 'academy=' + ','.join(ids) if ids and slugs: url = url + '&' if slugs: url = url + 'academy_slug=' + ','.join(slugs) calendar.add('url', url) calendar.add('version', '2.0') for item in items: event = iEvent() event.add('summary', item.name) event.add('uid', f'breathecode_cohort_{item.id}_{key}') event.add('dtstart', item.kickoff_date) if item.ending_date: event.add('dtend', item.ending_date) event.add('dtstamp', item.created_at) teacher = CohortUser.objects.filter(role='TEACHER', cohort__id=item.id).first() if teacher: organizer = vCalAddress(f'MAILTO:{teacher.user.email}') if teacher.user.first_name and teacher.user.last_name: organizer.params['cn'] = vText( f'{teacher.user.first_name} ' f'{teacher.user.last_name}') elif teacher.user.first_name: organizer.params['cn'] = vText(teacher.user.first_name) elif teacher.user.last_name: organizer.params['cn'] = vText(teacher.user.last_name) organizer.params['role'] = vText('OWNER') event['organizer'] = organizer location = item.academy.name if item.academy.website_url: location = f'{location} ({item.academy.website_url})' event['location'] = vText(item.academy.name) calendar.add_component(event) calendar_text = calendar.to_ical() response = HttpResponse(calendar_text, content_type='text/calendar') response['Content-Disposition'] = 'attachment; filename="calendar.ics"' return response
def solution_add_to_calender_event(service_user, email, method, params, tag, service_identity, user_details): rogerthat_settings = get_server_settings() settings = get_solution_settings(service_user) service_name = settings.name app = get_app_by_id(user_details[0].app_id) jsondata = json.loads(params) emailSubject = "Event: %s" % jsondata['eventTitle'] if jsondata['eventPlace']: eventPlace = "Place: %s " % jsondata['eventPlace'] else: eventPlace = '' emailBody = u"Title: %s \nDate: %s \nDescription: %s \n%s \n" % ( jsondata['eventTitle'], jsondata['eventDate'], jsondata['eventDescription'], eventPlace) cal = Calendar() cal.add('prodid', '-//My calendar product//mxm.dk//') cal.add('version', '2.0') cal.add('method', 'REQUEST') event = ICalenderEvent() event.add('summary', jsondata['eventTitle']) event.add('description', jsondata['eventDescription']) event.add('location', jsondata['eventPlace']) startDate = datetime.utcfromtimestamp(int(jsondata['eventStart'])) try: endDate = datetime.utcfromtimestamp(int(jsondata['eventEnd'])) except TypeError: endDate = None nowDate = datetime.utcfromtimestamp(time.time()) dtstart = datetime(startDate.year, startDate.month, startDate.day, startDate.hour, startDate.minute, startDate.second, tzinfo=pytz.utc) dtstamp = datetime(nowDate.year, nowDate.month, nowDate.day, nowDate.hour, nowDate.minute, nowDate.second, tzinfo=pytz.utc) event.add('dtstart', dtstart) if endDate: dtend = datetime(endDate.year, endDate.month, endDate.day, endDate.hour, endDate.minute, endDate.second, tzinfo=pytz.utc) event.add('dtend', dtend) event.add('dtstamp', dtstamp) event.add('uid', "%s %s" % (app.dashboard_email_address, jsondata['eventId'])) organizer = vCalAddress('MAILTO:%s' % app.dashboard_email_address) organizer.params['cn'] = vText(service_name) event.add('organizer', organizer) cal.add_component(event) icall = cal.to_ical() attachments = [] attachments.append(("event.ics", base64.b64encode(icall))) from_ = rogerthat_settings.senderEmail if app.type == App.APP_TYPE_ROGERTHAT else ( "%s <%s>" % (app.name, app.dashboard_email_address)) send_mail(from_, email, emailSubject, emailBody, attachments=attachments) r = SendApiCallCallbackResultTO() r.result = u"successfully reminded" r.error = None return r
def get(self, request): items = Event.objects.filter(status='ACTIVE') ids = request.GET.get('academy', '') slugs = request.GET.get('academy_slug', '') ids = ids.split(",") if ids else [] slugs = slugs.split(",") if slugs else [] if ids: items = Event.objects.filter(academy__id__in=ids, status='ACTIVE').order_by('id') elif slugs: items = Event.objects.filter(academy__slug__in=slugs, status='ACTIVE').order_by('id') else: items = [] if not ids and not slugs: raise ValidationException( "You need to specify at least one academy or academy_slug (comma separated) in the querystring" ) if (Academy.objects.filter(id__in=ids).count() != len(ids) or Academy.objects.filter(slug__in=slugs).count() != len(slugs)): raise ValidationException("Some academy not exist") upcoming = request.GET.get('upcoming') if upcoming == 'true': now = timezone.now() items = items.filter(starting_at__gte=now) academies_repr = ical_academies_repr(ids=ids, slugs=slugs) key = server_id() calendar = iCalendar() calendar.add( 'prodid', f'-//BreatheCode//Academy Events{academies_repr} {key}//EN') calendar.add('X-WR-CALNAME', f'Academy - Events') calendar.add('X-WR-CALDESC', '') calendar.add('REFRESH-INTERVAL;VALUE=DURATION', 'PT15M') url = os.getenv('API_URL') if url: url = re.sub(r'/$', '', url) + '/v1/events/ical/events' if ids or slugs: url = url + '?' if ids: url = url + 'academy=' + ','.join(ids) if ids and slugs: url = url + '&' if slugs: url = url + 'academy_slug=' + ','.join(slugs) calendar.add('url', url) calendar.add('version', '2.0') for item in items: event = iEvent() if item.title: event.add('summary', item.title) description = '' description = f'{description}Url: {item.url}\n' if item.academy: description = f'{description}Academy: {item.academy.name}\n' if item.venue and item.venue.title: description = f'{description}Venue: {item.venue.title}\n' if item.event_type: description = f'{description}Event type: {item.event_type.name}\n' if item.online_event: description = f'{description}Location: online\n' event.add('description', description) event.add('uid', f'breathecode_event_{item.id}_{key}') event.add('dtstart', item.starting_at) event.add('dtend', item.ending_at) event.add('dtstamp', item.created_at) if item.author and item.author.email: organizer = vCalAddress(f'MAILTO:{item.author.email}') if item.author.first_name and item.author.last_name: organizer.params['cn'] = vText(f'{item.author.first_name} ' f'{item.author.last_name}') elif item.author.first_name: organizer.params['cn'] = vText(item.author.first_name) elif item.author.last_name: organizer.params['cn'] = vText(item.author.last_name) organizer.params['role'] = vText('OWNER') event['organizer'] = organizer if item.venue and (item.venue.country or item.venue.state or item.venue.city or item.venue.street_address): value = '' if item.venue.street_address: value = f'{value}{item.venue.street_address}, ' if item.venue.city: value = f'{value}{item.venue.city}, ' if item.venue.state: value = f'{value}{item.venue.state}, ' if item.venue.country: value = f'{value}{item.venue.country}' value = re.sub(', $', '', value) event['location'] = vText(value) calendar.add_component(event) calendar_text = calendar.to_ical() response = HttpResponse(calendar_text, content_type='text/calendar') response['Content-Disposition'] = 'attachment; filename="calendar.ics"' return response
def create_school_calendar(details, timetables, hours, name, timetable=True, substitutions=True): logger = logging.getLogger(__name__) calendar = Calendar() calendar.add("prodid", "gimvicurnik") calendar.add("version", "2.0") calendar.add("X-WR-TIMEZONE", "Europe/Ljubljana") calendar.add("X-WR-CALNAME", name) calendar.add("X-WR-CALDESC", name) calendar.add("NAME", name) calendar.add("X-PUBLISHED-TTL", vDuration(timedelta(hours=1))) calendar.add("REFRESH-INTERVAL", vDuration(timedelta(hours=1))) year = datetime.now().year if datetime.now().date() >= date( datetime.now().year, 9, 1) else datetime.now().year - 1 weekdays = ["SU", "MO", "TU", "WE", "TH", "FR", "SA"] weektable = [[None for i in range(10)] for j in range(6)] if timetable: for subject in timetables: with start_span(op="event") as span: span.set_tag("event.type", "timetable") span.set_tag("event.day", subject["day"]) span.set_tag("event.time", subject["time"]) span.set_data("event.source", subject) logger.info("Preparing iCalendar event", extra={ "type": "timetable", "source": subject }) event = Event() event.add("dtstamp", datetime.now()) event.add("CATEGORIES", vText("NORMAL")) event.add("COLOR", vText("green")) event.add( "UID", sha256((str(subject["day"]) + str(subject["time"]) + str(subject["subject"]) + str(subject["class"]) + str(subject["teacher"])).encode()).hexdigest(), ) start = datetime(year, 8, 31) + hours[subject["time"]]["hour"]["start"] event.add("dtstart", start) event["EXDATE"] = vDatetime(start).to_ical().decode("utf-8") event["DURATION"] = "PT45M" event["RRULE"] = ( "FREQ=WEEKLY;BYDAY=" + weekdays[subject["day"]] + ";UNTIL=" + vDatetime( datetime(year + 1, 6, 25)).to_ical().decode("utf-8")) event.add("summary", subject["subject"]) event["organizer"] = vText(subject["teacher"]) event["location"] = vText(subject["classroom"]) weektable[subject["day"]][subject["time"]] = event if substitutions: for subject in details: with start_span(op="event") as span: span.set_tag("event.type", "substitution") span.set_tag("event.date", subject["date"]) span.set_tag("event.day", subject["day"]) span.set_tag("event.time", subject["time"]) span.set_data("event.source", subject) logger.info("Preparing iCalendar event", extra={ "type": "substitution", "source": subject }) event = Event() event.add("dtstamp", datetime.now()) event.add("CATEGORIES", vText("SUBSTITUTION")) event.add("COLOR", vText("darkred")) event.add( "UID", sha256((str(subject["date"]) + str(subject["day"]) + str(subject["time"]) + str(subject["subject"]) + str(subject["class"]) + str(subject["teacher"])).encode()).hexdigest(), ) date_ = datetime.strptime(subject["date"], "%Y-%m-%d") event.add("dtstart", date_ + hours[subject["time"]]["hour"]["start"]) event.add("dtend", date_ + hours[subject["time"]]["hour"]["end"]) event.add("summary", subject["subject"]) event["organizer"] = vText(subject["teacher"]) event["location"] = vText(subject["classroom"]) if weektable[datetime.strptime( subject["date"], "%Y-%m-%d").isoweekday()][subject["time"]]: original = weektable[datetime.strptime( subject["date"], "%Y-%m-%d").isoweekday()][subject["time"]] original["EXDATE"] += "," + event.get( "dtstart").to_ical().decode("utf-8") calendar.add_component(event) for i in range(len(weektable)): for j in range(len(weektable[0])): if weektable[i][j]: calendar.add_component(weektable[i][j]) response = make_response(calendar.to_ical().decode("utf-8").replace( "\\", "")) response.headers[ "Content-Disposition"] = "attachment; filename=calendar.ics" response.headers["Content-Type"] = "text/calendar; charset=utf-8" return response
def get_course_ics(self, course_list, first, name): ics = icalendar.Calendar() ics.add('PRODID', '-//Uestc Course//lc4t.me//') ics.add('version', '2.0') ics.add('X-WR-CALNAME', '%s的课程表' % name) ics.add('X-WR-CALDESC', 'uestc %s的课程表' % name) ics.add('X-WR-TIMEZONE', "Asia/Shanghai") ics.add('CALSCALE', 'GREGORIAN') ics.add('METHOD', 'PUBLISH') tz = pytz.timezone('Asia/Shanghai') for course in course_list: for week in course['week']: day = -1 course_start = -1 course_long = 0 day_list = set() for d in course['day']: for k, v in d.items(): if day == -1 and day != k: day = k course_long += 1 course_start = v elif day != -1 and day != k: day_list.add((day, course_long)) course_long = 1 day = k course_start = v elif day == k: course_long += 1 else: print('error') day_list.add((day, course_start, course_long)) for i in day_list: e = icalendar.Event() start_time, end_time = get_start_end( first, i[1], i[2], i[0], week) e.add('dtstart', tz.localize(start_time)) e.add('dtend', tz.localize(end_time)) e['summary'] = '(%s)%s [%s] @%s' % ( week, course['teacher_name'], course['place'], course['course_name']) e['location'] = icalendar.vText(course['place']) e['TRANSP'] = icalendar.vText('OPAQUE') e['status'] = 'confirmed' _now = datetime.now() now = tz.localize(_now) e.add('created', now) e.add('DTSTAMP', _now) md5 = hashlib.md5() md5.update( ('%s%s' % (str(now), course['course_name'])).encode()) e["UID"] = '*****@*****.**' % md5.hexdigest() e.add('LAST-MODIFIED', _now) ics.add_component(e) print('%s-%s %s' % (str(start_time), str(end_time), e['summary'])) return ics
def createICalFile(courses, name="default.ics", path=os.getcwd()): cal = Calendar() #Some properties are required to be compliant: cal.add('prodid', '-//My calendar product//mxm.dk//') cal.add('version', '2.0') for course in courses: event = Event() summary = course["name"] if isinstance(course["prof"], basestring): summary += " : " + course["prof"] event.add('summary', summary) event.add( 'dtstart', datetime(course["dateStart"].year, course["dateStart"].month, course["dateStart"].day, course["dateStart"].hour - 1, 0, 0, tzinfo=pytz.utc)) event.add( 'dtend', datetime(course["dateEnd"].year, course["dateEnd"].month, course["dateEnd"].day, course["dateEnd"].hour - 1, 0, 0, tzinfo=pytz.utc)) #event.add('dtstamp', datetime(2014, 2, 22, 0, 10, 0, tzinfo=pytz.utc)) #A property with parameters. Notice that they are an attribute on the value: organizer = vCalAddress('MAILTO:[email protected]') #Automatic encoding is not yet implemented for parameter values, so you must use the ‘v*’ types you can import from the icalendar package (they’re defined in icalendar.prop): organizer.params['cn'] = vText(course["prof"]) organizer.params['role'] = vText('CHAIR') event['organizer'] = organizer event['location'] = vText('EPSI') event['uid'] = course["dateStart"].strftime( "%Y-%m-%d%H:%M") + '/[email protected]' event.add('priority', 5) attendee = vCalAddress('MAILTO:[email protected]') attendee.params['cn'] = vText('Etudiant') attendee.params['ROLE'] = vText('REQ-PARTICIPANT') event.add('attendee', attendee, encode=0) attendee = vCalAddress('MAILTO:[email protected]') attendee.params['cn'] = vText('The Dude') attendee.params['ROLE'] = vText('REQ-PARTICIPANT') event.add('attendee', attendee, encode=0) #Add the event to the calendar: cal.add_component(event) #Write to disk: if path is None: path = os.getcwd() f = open(os.path.join(path, name), 'wb') f.write(cal.to_ical()) f.close()
for loc_date in daterange(date_start, date_end): ### time vars time_dawn = dawn(loc.observer, loc_date, tzinfo=loc_tz) time_rise = sunrise(loc.observer, loc_date, tzinfo=loc_tz) time_set = sunset(loc.observer, loc_date, tzinfo=loc_tz) time_dusk = dusk(loc.observer, loc_date, tzinfo=loc_tz) ### description vars event_title_rise = '↑ {0}'.format(time_rise.strftime("%H:%M")) event_title_set = '↓ {0}'.format(time_set.strftime("%H:%M")) # could move coordinates to 'GEO' property, see https://www.kanzaki.com/docs/ical/geo.html event_location = vText('{0} / {1}, {2}'.format(loc_name, loc_lat, loc_long)) # timedelta doesn't allow strftime, find a way to format it better, see https://stackoverflow.com/questions/538666/format-timedelta-to-string event_desc_rise = 'Dawn at {0}, sunrise at {1}. Total sunlight time {2}'.format( time_dawn.strftime("%H:%M"), time_rise.strftime("%H:%M"), str(time_set - time_rise)) event_desc_set = 'Sunset at {0}, dusk at {1}. Total sunlight time {2}'.format( time_set.strftime("%H:%M"), time_dusk.strftime("%H:%M"), str(time_set - time_rise)) # dawn to sunrise daystart = Event() daystart.add('summary', event_title_rise) daystart['uid'] = '{0}/SUNSCRIPT/SUNRISE/{1}'.format( loc_date, loc_name.upper())
col2 = stuff[1] cal = Calendar() cal.add('prodid', '-//Jets Home Games//bgp.guru//') cal.add('version', '2.0') for row in col1.itertuples(): if "@" not in row[4]: lyear, lmonth, lday = parsedate(row[2], year) lhour, lminutes = parsetime(row[3]) #print "%s %d, %d @ %s - %s" % (int_to_month(lmonth), lday, lyear, row[3], row[4]) event = Event() event.add('summary', 'Jets ' + row[4]) event.add('dtstart', datetime(lyear, lmonth, lday, lhour, lminutes, 0, tzinfo=pytz.timezone('US/Central'))) event.add('dtend', datetime(lyear, lmonth, lday, lhour + 3, lminutes, 0, tzinfo=pytz.timezone('US/Central'))) event['location'] = vText('300 Portage Ave, Winnipeg, MB R3P5S4') cal.add_component(event) for row in col2.itertuples(): if "@" not in row[4]: lyear, lmonth, lday = parsedate(row[2], year) lhour, lminutes = parsetime(row[3]) #print "%s %d, %d @ %s - %s" % (int_to_month(lmonth), lday, lyear, row[3], row[4]) event = Event() event.add('summary', 'Jets ' + row[4]) event.add('dtstart', datetime(lyear, lmonth, lday, lhour, lminutes, 0, tzinfo=pytz.timezone('US/Central'))) event.add('dtend', datetime(lyear, lmonth, lday, lhour + 3, lminutes, 0, tzinfo=pytz.timezone('US/Central'))) event['location'] = vText('300 Portage Ave, Winnipeg, MB R3P5S4') cal.add_component(event) dir_path = os.getcwd()
def __init__(self, organizer_email, start, summary, organizer_cn=None, description=None, duration='1h', location=None): """ :param str organizer_email: The email of the event organizer. :param start: The start time for the event. :type start: :py:class:`datetime.datetime` :param str summary: A short summary of the event. :param str organizer_cn: The name of the event organizer. :param str description: A more complete description of the event than what is provided by the *summary* parameter. :param duration: The events scheduled duration. :type duration: int, str, :py:class:`~datetime.timedelta`, :py:class:`.DurationAllDay` :param str location: The location for the event. """ utilities.assert_arg_type(start, datetime.datetime, 2) super(Calendar, self).__init__() if start.tzinfo is None: start = start.replace(tzinfo=dateutil.tz.tzlocal()) start = start.astimezone(dateutil.tz.tzutc()) for case in utilities.switch(duration, comp=isinstance): if case(str): duration = smoke_zephyr.utilities.parse_timespan(duration) duration = datetime.timedelta(seconds=duration) break if case(int): duration = datetime.timedelta(seconds=duration) break if case(datetime.timedelta): break if case(DurationAllDay): break else: raise TypeError('unknown duration type') self.add('method', 'REQUEST') self.add('prodid', 'Microsoft Exchange Server 2010') self.add('version', '2.0') self._event = icalendar.Event() event = self._event self.add_component(event) self.add_component(Timezone()) organizer = icalendar.vCalAddress('MAILTO:' + organizer_email) organizer.params['cn'] = icalendar.vText(organizer_cn or organizer_email) event['organizer'] = organizer event.add('description', description or summary) event.add('uid', str(uuid.uuid4())) event.add('summary', summary) if isinstance(duration, DurationAllDay): event.add('dtstart', start.date()) event.add('dtend', (start + datetime.timedelta(days=duration.days)).date()) else: event.add('dtstart', start) event.add('dtend', start + duration) event.add('class', 'PUBLIC') event.add('priority', 5) event.add('dtstamp', datetime.datetime.now(dateutil.tz.tzutc())) event.add('transp', 'OPAQUE') event.add('status', 'CONFIRMED') event.add('sequence', 0) if location: event.add('location', icalendar.vText(location)) alarm = icalendar.Alarm() alarm.add('description', 'REMINDER') alarm.add('trigger;related=start', '-PT1H') alarm.add('action', 'DISPLAY') event.add_component(alarm)
def main(): response = requests.request("GET", "http://bkjws.sdu.edu.cn/") cookie = '' for x in response.headers.get('Set-Cookie', '').strip().split(','): cookie += x.split(';')[0] + ';' print("Input Username") username = input() username = username.strip() print("Input Password") password = input() password = password.strip() print("Input the first day of term (Format: Year-Month-Day)") year, month, day = list(map(lambda x: int(x), input().split('-'))) fday = datetime.now() fday = fday.replace(year=year, month=month, day=day, hour=0, minute=0, second=0, microsecond=0) login(username, password, cookie) headers = { 'accept': "*/*", 'accept-encoding': "gzip, deflate", 'accept-language': "zh-CN,zh;q=0.8", 'connection': "keep-alive", 'cookie': "index=1;j_username=%s;j_password=%s;%s" % (username, password, cookie), 'cache-control': "no-cache", 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36' } response = requests.request("POST", "http://bkjws.sdu.edu.cn/f/xk/xs/bxqkb", headers=headers) html = pq(response.text) table = html('table#ysjddDataTableId') # 记得改作息 c = Calendar() for i, tr in enumerate(table.items('tr')): if not i: continue td = tr.children('td') name = td.eq(2).text() week = td.eq(8).text() week = list(map(lambda x: x, week.split('周上')[0].split('-'))) day = int(td.eq(9).text()) cls = int(td.eq(10).text()) loc = td.eq(11).text() print(name, week, day, cls, loc) if len(week) == 1: week = str(week[0]) counter = -1 for wk in range(len(week)): if wk <= counter or week[wk] == '0': continue counter = wk delta = timedelta(days=7 * wk) + timedelta(days=((day - fday.isoweekday()) + 7) % 7) nowday = fday + delta t = time() if 5 <= nowday.month < 10: nowday = nowday.combine(nowday.date(), TimeTable['summer'][cls - 1]) else: nowday = nowday.combine(nowday.date(), TimeTable['winter'][cls - 1]) total = 1 tmpwk = wk while tmpwk + 1 < len(week) and week[tmpwk + 1] == '1': tmpday = fday + timedelta(days=7 * (tmpwk + 1)) + timedelta( days=((day - fday.isoweekday()) + 7) % 7) if nowday.month < 5 <= tmpday.month or nowday.month < 10 <= tmpday.month or 5 <= tmpday.month < 10 <= tmpday.month: break total += 1 tmpwk += 1 counter = tmpwk e = Event() e.add("summary", name) e.add("uid", "Event" + name + nowday.strftime("%Y%m%d%H%M%S") + "@JackZ.cn") e.add('location', vText(loc)) e.add("dtstart", nowday) e.add("dtend", nowday + timedelta(hours=1, minutes=50)) e.add('rrule', {'freq': 'weekly', 'interval': '1', 'count': str(total)}) c.add_component(e) else: counter = -1 for wk in range(int(week[0]) - 1, int(week[1])): if wk <= counter: continue counter = wk delta = timedelta(days=7 * wk) + timedelta(days=((day - fday.isoweekday()) + 7) % 7) nowday = fday + delta t = time() if 5 <= nowday.month < 10: nowday = nowday.combine(nowday.date(), TimeTable['summer'][cls - 1]) else: nowday = nowday.combine(nowday.date(), TimeTable['winter'][cls - 1]) total = 1 tmpwk = wk while tmpwk + 1 < int(week[1]): tmpday = fday + timedelta(days=7 * (tmpwk + 1)) + timedelta( days=((day - fday.isoweekday()) + 7) % 7) if nowday.month < 5 <= tmpday.month or nowday.month < 10 <= tmpday.month or 5 <= tmpday.month < 10 <= tmpday.month: break total += 1 tmpwk += 1 counter = tmpwk e = Event() e.add("summary", name) e.add("uid", "Event" + name + nowday.strftime("%Y%m%d%H%M%S") + "@JackZ.cn") e.add('location', vText(loc)) e.add("dtstart", nowday) e.add("dtend", nowday + timedelta(hours=1, minutes=50)) e.add('rrule', {'freq': 'weekly', 'interval': '1', 'count': str(total)}) c.add_component(e) print(c.to_ical()) with open('output.ics', 'wb') as f: f.write(c.to_ical())
def render(self, request): cal = icalendar.Calendar() cal.add('version', '2.0') cal.add('prodid', 'billy') for obj in self.construct(): if not isinstance(obj, dict): continue if obj.get('_type') != 'event': # We can only serialize events continue event = icalendar.Event() if obj.get('all_day', False): event.add('dtstart', obj['when'].date()) event['X-FUNAMBOL-ALLDAY'] = 1 event['X-MICROSOFT-CDO-ALLDAYEVENT'] = 1 else: event['dtstart'] = _vDatetime(obj['when']) end = obj.get('end') if not end: end = obj['when'] + datetime.timedelta(hours=1) event['dtend'] = _vDatetime(end) if obj['type'] == 'committee:meeting': part = obj['participants'][0] comm = part['participant'] chamber = part.get('chamber') if chamber: comm = "%s %s" % (chamber_name(obj[settings.LEVEL_FIELD], chamber), comm) summary = "%s Committee Meeting" % clean_for_ical(comm) elif obj['type'] == 'bill:action': summary = clean_for_ical(obj['description']) else: continue event.add('summary', clean_for_ical(summary)) event.add('location', clean_for_ical( obj.get('location', 'Unknown'))) event['uid'] = clean_for_ical(obj['_id']) status = clean_for_ical(obj.get('status')) if status: event.add('status', clean_for_ical(status.upper())) notes = clean_for_ical(obj.get('notes')) if notes: event.add('description', clean_for_ical(notes)) link = clean_for_ical(obj.get('link')) if link: event.add('attach', clean_for_ical(link)) for participant in obj['participants']: addr = icalendar.vCalAddress('MAILTO:[email protected]') chamber = clean_for_ical(participant.get('chamber')) if chamber: cn = clean_for_ical( chamber_name(obj[settings.LEVEL_FIELD], chamber) + " ") else: cn = "" cn += clean_for_ical(participant['participant']) if participant['type'] == 'committee': cn += ' Committee' addr.params['cn'] = icalendar.vText(cn) #addr.params['ROLE'] = icalendar.vText('COMMITTEE') event.add('attendee', clean_for_ical(addr)) event['organizer'] = clean_for_ical(addr) cal.add_component(event) return cal.to_ical()
def get(self, request, pks): c = Calendar() c.add('prodid', '-//Renew Indianapolis//Property Showings//EN') c.add('version', '2.0') for pk in pks.split(','): obj = propertyShowing.objects.get(pk=pk) data = sorted(obj.inquiries.all(), key=attrgetter('user')) props = [] props_addresses = [] for k, g in groupby(data, attrgetter('Property')): props.append(k) props_addresses.append(k.streetAddress) data = sorted(obj.inquiries.all(), key=attrgetter('user')) users = [] for k, g in groupby(data, attrgetter('user')): users.append(k) e = Event() e.add( 'summary', '{} - Property Showing'.format( ','.join(props_addresses), ).title()) e.add('uid', obj.id) e.add('dtstart', obj.datetime) e.add('dtend', obj.datetime + timedelta(minutes=30)) e.add('dtstamp', now()) e.add('location', '{0}, Indianapolis, IN'.format(','.join(props_addresses), )) people = [] organizer = vCalAddress('MAILTO:{}'.format(request.user.email, )) organizer.params['cn'] = vText('{} {}'.format( request.user.first_name, request.user.last_name)) e.add('organizer', organizer, encode=0) for u in users: try: people.append('{} {} - {} {}'.format( u.first_name, u.last_name, u.email, u.profile.phone_number)) except ApplicantProfile.DoesNotExist: people.append('{} {} - {}'.format(u.first_name, u.last_name, u.email)) attendee = vCalAddress('MAILTO:{}'.format(u.email, )) attendee.params['cn'] = vText('{} {}'.format( u.first_name, u.last_name)) # e.add('attendee', attendee, encode=0) for staff in settings.COMPANY_SETTINGS['city_staff']: a = vCalAddress('MAILTO:{}'.format(staff['email'], )) a.params['cn'] = vText(staff['name']) e.add('attendee', a, encode=0) description = render_to_string( 'property_inquiry/property_showing_ics_description.txt', { 'showing': self, 'properties': props, 'users': people }) e.add('description', description) e.add('status', 'TENTATIVE') c.add_component(e) response = HttpResponse(c.to_ical(), content_type="text/calendar") response['Content-Disposition'] = 'attachment; filename=showings.ics' return response
def comparteixCalendari(request, clau): cal = Calendar() cal.add('method', 'PUBLISH') # IE/Outlook needs this try: dades_adicionals_professor = DadesAddicionalsProfessor.objects.get( clauDeCalendari=clau) professor = dades_adicionals_professor.professor except: return HttpResponseNotFound("") else: #-- imparticions imparticions = list( Impartir.objects.filter(horari__professor=professor). select_related("reserva").select_related( "reserva__aula").select_related("horari").select_related( "horari__hora").select_related("horari__assignatura")) for instance in imparticions: event = Event() assignatura = instance.horari.assignatura.nom_assignatura aula = instance.reserva.aula.nom_aula if hasattr( instance, "reserva") and instance.reserva is not None else "" grup = instance.horari.grup.descripcio_grup if hasattr( instance.horari, "grup") and instance.horari.grup is not None else "" summary = u"{assignatura} {aula} {grup}".format( assignatura=assignatura, aula=aula, grup=grup, ) d = instance.dia_impartir h = instance.horari.hora event.add( 'dtstart', localtime( datetime(d.year, d.month, d.day, h.hora_inici.hour, h.hora_inici.minute, h.hora_inici.second))) event.add( 'dtend', localtime( datetime(d.year, d.month, d.day, h.hora_fi.hour, h.hora_fi.minute, h.hora_fi.second))) event.add('summary', summary) event.add('uid', 'djau-ical-impartir-{0}'.format(instance.id)) event['location'] = vText(aula) cal.add_component(event) #-- sortides q_professor = Q(professor_que_proposa=professor) q_professor |= Q(altres_professors_acompanyants=professor) q_professor |= Q(professors_responsables=professor) sortides = list( Sortida.objects.filter(q_professor).filter( calendari_desde__isnull=False).exclude(estat__in=[ 'E', 'P', ]).distinct()) for instance in sortides: event = Event() summary = u"{ambit}: {titol}".format( ambit=instance.ambit, titol=instance.titol_de_la_sortida) event.add('dtstart', localtime(instance.calendari_desde)) event.add('dtend', localtime(instance.calendari_finsa)) event.add('summary', summary) organitzador = u"\nOrganitza: " organitzador += u"{0}".format( u"Departament" + instance.departament_que_organitza.nom if instance. departament_que_organitza_id else u"") organitzador += " " + instance.comentari_organitza event.add( 'organizer', vText(u"{0} {1}".format( u"Departament " + instance.departament_que_organitza.nom if instance.departament_que_organitza_id else u"", instance.comentari_organitza))) event.add('description', instance.programa_de_la_sortida + organitzador) event.add('uid', 'djau-ical-sortida-{0}'.format(instance.id)) event['location'] = vText(instance.ciutat) cal.add_component(event) return HttpResponse(cal.to_ical())
cal.add('version', '2.0') for index, row in df.iterrows(): print(index, row['name'], row['tags']) event = Event() event['uid'] = row['detailsUrl'] event.add( 'summary', str(row['name']) + ' ' + str(row['tags']) + ' ' + str(row['signUps'])) event.add('dtstart', index) event.add('dtend', index + timedelta(hours=1)) event.add('url', 'https://rgtdb.com' + row['detailsUrl']) event.add('description', row['distance'] + ' ' + 'https://rgtdb.com' + row['detailsUrl']) event.add('color', 'Tomato') event['location'] = vText(row['roadName']) cal.add_component(event) # %% [markdown] # ## Write to File # # Can use to manually import into Google, other calendars # %% import tempfile, os f = open('./rgt_events.ics', 'wb') f.write(cal.to_ical()) f.close() # %% [markdown]
def session_ical(session, rsvp=None): # This function is only called with scheduled sessions. # If for some reason it is used somewhere else and called with an unscheduled session, # this function should fail. if not session.scheduled: raise Exception("{0!r} is not scheduled".format(session)) event = Event() event.add('summary', session.title) organizer = vCalAddress( f'MAILTO:no-reply@{current_app.config["DEFAULT_DOMAIN"]}' # NOQA ) organizer.params['cn'] = vText(session.project.profile.title) event['organizer'] = organizer if rsvp: attendee = vCalAddress('MAILTO:' + str(rsvp.user_email())) attendee.params['RSVP'] = vText('TRUE') if rsvp.state.YES else vText( 'FALSE') attendee.params['cn'] = vText(rsvp.user.fullname) attendee.params['CUTYPE'] = vText('INDIVIDUAL') attendee.params['X-NUM-GUESTS'] = vText('0') event.add('attendee', attendee, encode=0) event.add( 'uid', f'session/{session.uuid_b58}@{current_app.config["DEFAULT_DOMAIN"]}', # NOQA ) # Using localized timestamps will require a `VTIMEZONE` entry in the ics file # Using `session.start_at` without `astimezone` causes it to be localized to # local timezone. We need `astimezone(utc)` to ensure actual UTC timestamps. event.add('dtstart', session.start_at.astimezone(utc)) event.add('dtend', session.end_at.astimezone(utc)) event.add('dtstamp', utcnow()) # Strangely, these two don't need localization with `astimezone` event.add('created', session.created_at) event.add('last-modified', session.updated_at) if session.venue_room: location = [ session.venue_room.title + " - " + session.venue_room.venue.title ] if session.venue_room.venue.city: location.append(session.venue_room.venue.city) if session.venue_room.venue.country: location[len(location) - 1] += ", " + session.venue_room.venue.country else: location.append(session.venue_room.venue.country) event.add('location', "\n".join(location)) if session.venue_room.venue.has_coordinates: event.add('geo', session.venue_room.venue.coordinates) if session.description: event.add('description', session.description.text) if session.proposal: event.add('url', session.url_for(_external=True)) if session.proposal.labels: event.add('categories', [label.title for label in session.proposal.labels]) alarm = Alarm() alarm.add('trigger', timedelta(minutes=-5)) alarm.add('action', 'display') if session.venue_room: desc = _("{session} in {venue} in 5 minutes").format( session=session.title, venue=session.venue_room.title) else: desc = _("{session} in 5 minutes").format(session=session.title) alarm.add('description', desc) event.add_component(alarm) return event
def clear_road_locs(cal): EMPTY = vText('') for ev in cal.walk('vevent'): if '@' in ev.decoded('summary'): ev['location'] = EMPTY return cal
def create_vaddress(user): va = vCalAddress('MAILTO:{}'.format(user.email)) va.params['cn'] = vText(user.nickname) va.params['ROLE'] = vText(user.role) return va
def clear_desc_boilerplate(cal): for ev in cal.walk('vevent'): desc = ev.decoded('description') ev['description'] = vText(desc[0:desc.find('Buy tickets here:')]) return cal
def seperate_lec(source, UID, cal): count = 1 for course in source: if (course[1] == 'Dropped\n'): continue for x in range(6, len(course), 7): event = Event() if (course[x] != ' \n'): name = course[0].replace("\n", "") section = course[x + 1].replace("\n", "") component = course[x + 2].replace("\n", "") # Get date dates = course[x + 6].replace("\n", "").split(' ') if (dates[0] == 'TBA'): continue start_dates = dates[0].split('/') end_dates = dates[2].split('/') # Get time time = course[x + 3].replace("\n", "").split(' ') start_hour, start_minute = parseTime(time[1]) end_hour, end_minute = parseTime(time[3]) # Reccurance week = parseWeek(time[0]) until = datetime(int(end_dates[2]), int(end_dates[1]), int(end_dates[0]), end_hour, end_minute) rec = { 'FREQ': 'WEEKLY', 'INTERVAL': 1, 'BYDAY': week, 'UNTIL': until, 'WKST': 'SU', } week_dic = {'MO': 0, 'TU': 1, 'WE': 2, 'TH': 3, 'FR': 4} # Prepare information summary = name + ' (' + component + ')' uid = UID + '_' + str(count) location = course[x + 4].replace("\n", "") + ', Waterloo, Canada' instructor = course[x + 5].replace("\n", "") description = ( 'Course name: %s %s (%s)\nLocation: %s\nInstructor: %s') % ( name, component, section, location, instructor) # Prepare Date dtstart = datetime( int(start_dates[2]), int(start_dates[1]), int(start_dates[0]), start_hour, start_minute, ) dtend = datetime(int(start_dates[2]), int(start_dates[1]), int(start_dates[0]), end_hour, end_minute) # print(dtstart.weekday() - week_dic[week[0]]) diff = week_dic[week[0]] - dtstart.weekday() dtstart += timedelta(days=diff) dtend += timedelta(days=diff) event['summary'] = vText(summary) event['uid'] = vText(uid) event['dtstamp'] = vDatetime(datetime.now()) event['location'] = vText(location) event['description'] = vText(description) event['dtstart'] = vDatetime(dtstart) event['dtend'] = vDatetime(dtend) event['rrule'] = vRecur(rec) cal.add_component(event) count += 1
def make_ical(data, lang, old): caldata = TranslatedMap(data['calendar'], lang=lang) cal = Calendar() cal.add('prodid', 'yamlical.py') cal.add('version', '2.0') cal.add('method', 'PUBLISH') if 'name' in caldata: cal.add('name', caldata['name']) cal.add('x-wr-calname', caldata['name']) if 'description' in caldata: cal.add('description', caldata['description']) cal.add('x-wr-caldesc', caldata['description']) if 'url' in caldata: cal.add('url', caldata['url']) if 'published' in caldata: pubdata = TranslatedMap(caldata['published'], lang=lang) url = vUri(pubdata['url']) url.params['value'] = 'URI' cal.add('source', url) # Todo: make this come from calendar.published.refresh_interval. refresh_interval = vDuration(timedelta(days=1)) refresh_interval.params['VALUE'] = 'DURATION' cal.add('x-published-ttl', refresh_interval) cal.add('refresh-interval', refresh_interval) add_timezone(cal) if 'organizer' in caldata: organizer = vCalAddress(caldata['organizer']['uri']) organizer.params['cn'] = vText(caldata['organizer']['cn']) else: organizer = None for evdata_raw in data['events']: evdata = TranslatedMap(evdata_raw, lang=lang) if 'overlay' in evdata: apply_overlay(evdata, TranslatedMap(evdata['overlay'], lang=lang)) end = None # default if not specified if 'date' in evdata: # Calculate the start and end timestamps from time/endtime. date = arrow.get(evdata['date'], DATE_FORMATS).date() a_start = arrow.get(evdata['time'], TIME_FORMATS) start = datetime.combine(date, a_start.time()) if 'endtime' in evdata: a_end = arrow.get(evdata['endtime'], TIME_FORMATS) end = datetime.combine(date, a_end.time()) else: start = arrow.get(evdata['start'], DT_FORMATS) if 'end' in evdata: end = arrow.get(evdata['end'], DT_FORMATS) event = Event() uid = evdata.setdefault('uid', make_uid()) # Add uid if needed. event.add('uid', uid) event.add('dtstart', dt_ical(start)) if end: event.add('dtend', dt_ical(end)) event.add('summary', apply_template(evdata, 'title')) if 'location' in evdata: event.add('location', apply_template(evdata, 'location')) if 'url' in evdata: event.add('url', apply_template(evdata, 'url')) if 'description' in evdata: event.add('description', apply_template(evdata, 'description')) if organizer: event.add('organizer', organizer) if evdata.get('cancelled', False): event.add('status', 'CANCELLED') if old and uid in old and events_equal(event, old[uid]): event['DTSTAMP'] = old[uid]['DTSTAMP'] else: event.add('dtstamp', datetime.utcnow()) cal.add_component(event) return cal
def dt_ical(dt): '''Convert a datetime to a vProperty''' arw = arrow.get(dt) prop = vText(arw.format('YYYYMMDDTHHmmss')) prop.params['TZID'] = TZID return prop
def ical_feed(request, cal_id): """ iCal feed Kept up-to-date Parameter: cal_id, which is a guid that is 1:1 with schedules in our database """ cal = Calendar() cal.add('prodid', '-//Recal Course Planner//recal.io//') cal.add('version', '2.0') try: sched = Schedule.objects.get(Q(ical_uuid=uuid.UUID(cal_id))) except Schedule.DoesNotExist: return HttpResponseNotFound("Not Found") semester = sched.semester cal.add('X-WR-CALNAME', 'ReCal %s (%s)' % (unicode(semester), sched.user.netid)) cal.add('X-WR-CALDESC', sched.title) # 'ReCal Schedule' # https://msdn.microsoft.com/en-us/library/ee178699(v=exchg.80).aspx. 15 # minute updates. cal.add('X-PUBLISHED-TTL', 'PT15M') tz = pytz.timezone("US/Eastern") # pytz.utc # recurrence ical_days = {0: 'MO', 1: 'TU', 2: 'WE', 3: 'TH', 4: 'FR'} builtin_days = {'M': 0, 'T': 1, 'W': 2, 'Th': 3, 'F': 4} #data = [hydrate_course_dict(Course.objects.get(Q(id=course['course_id']))) for course in json.loads(sched.enrollments)] # 0-6, monday is 0, sunday is 6. we will have values of 0 (Monday) or 2 # (Wednesday) day_of_week_semester_start = semester.start_date.weekday() for course_obj in json.loads(sched.enrollments): # course = Course.objects.get(Q(id=course_obj['course_id'])) # # course_obj is json object; course is model for section_id in course_obj['sections']: section = Section.objects.get(Q(pk=section_id)) for meeting in section.meetings.all(): event = Event() event.add('summary', unicode(section)) # name of the event event.add('location', vText(meeting.location + ', Princeton, NJ')) # compute first meeting date. # days when the class meets. convert them to day difference # relative to first date of the semester # split by space. format: 0-4. monday is 0, friday is 4. # matches python weekday() format. daysofweek = [builtin_days[i] for i in meeting.days.split()] if len(daysofweek) == 0: # no meetings -- skip continue dayofweek_relative_to_semester_start = [] for dow in daysofweek: diff = dow - day_of_week_semester_start if diff < 0: diff += 7 # add a week dayofweek_relative_to_semester_start.append(diff) # all must be positive assert all( [d >= 0 for d in dayofweek_relative_to_semester_start]) # a T,Th class will have first meeting on T if semester starts # on M, or on Th if semester starts on Wed. first_meeting_dayofweek = min( dayofweek_relative_to_semester_start) # get meeting time # meeting.start_time, meeting.end_time examples: "03:20 PM", # "10:00 AM" start_time = dt_parser.parse(meeting.start_time) end_time = dt_parser.parse(meeting.end_time) # add event time. event.add( 'dtstart', tz.localize( datetime(semester.start_date.year, semester.start_date. month, semester.start_date.day, start_time.hour, start_time.minute, 0) + timedelta(days=first_meeting_dayofweek)) ) # year,month,day, hour,min,second in ET event.add( 'dtend', tz.localize( datetime(semester.start_date.year, semester.start_date. month, semester.start_date.day, end_time.hour, end_time.minute, 0) + timedelta(days=first_meeting_dayofweek))) # "property specifies the DATE-TIME that iCalendar object was created". per 3.8.7.2 of RFC 5545, must be in UTC event.add( 'dtstamp', tz.localize( datetime(semester.start_date.year, semester.start_date.month, semester.start_date.day, 0, 0, 0))) # recurring event config # producing e.g.: RRULE:FREQ=WEEKLY;UNTIL=[LAST DAY OF SEMESTER # + 1];WKST=SU;BYDAY=TU,TH selected_days = [ical_days[i] for i in sorted(daysofweek) ] # formatted for ical end_date = tz.localize( datetime(semester.end_date.year, semester.end_date.month, semester.end_date.day, 0, 0, 0) + timedelta(days=1)) # [LAST DAY OF SEMESTER + 1] event.add( 'rrule', vRecur({ 'FREQ': 'WEEKLY', 'UNTIL': end_date, 'WKST': 'SU', 'BYDAY': selected_days })) cal.add_component(event) ical = cal.to_ical() # filter out blank lines #filtered = filter(lambda x: not re.match(r'^\s*$', x), ical) # print filtered return HttpResponse(ical, 'text/calendar', status=200)
def contacts_ics(): cal = Calendar() cal.add('prodid', vText('-//choochootrain//Auto-generated//EN')) cal.add('version', vText('2.0')) cal.add('calscale', vText('gregorian')) cal.add('method', vText('publish')) cal.add('x-wr-calname', vText('Birthdays')) cal.add('x-wr-timezone', vText('America/Los_Angeles')) cal.add('x-wr-caldesc', vText('Autogenerated calendar of birthday events')) conn = sqlite3.connect("data/contacts.db") cursor = conn.cursor() cursor.execute("SELECT * FROM contacts order by birthyear, birthmonth, birthday") for id, name, day, month, year in cursor.fetchall(): event = Event() event.add('summary', "%s's birthday" % name) start = datetime.datetime(day=day, month=month, year=year if year is not None else 2014) event.add('dtstart', vDDDTypes(start)) event.add('dtend', vDDDTypes(start + datetime.timedelta(days=1))) event.add('rrule', vRecur(freq='yearly')) cal.add_component(event) return Response(cal.to_ical(), mimetype="text/calendar")