def parse_tz_posix_env_var(posix_env_var): """ Get the details regarding a timezone by parsing the POSIX style TZ environment variable. :param str posix_env_var: The POSIX style TZ environment variable. :return: The parsed TZ environment variable. :rtype: :py:class:`.TimezoneOffsetDetails` """ match = POSIX_VAR_OFFSET.match(posix_env_var) if match is None: return match = match.groupdict() offset = get_timedelta_for_offset(match['offset']) if match['offset_dst'] is None: offset_dst = None elif len(match['offset_dst']): offset_dst = get_timedelta_for_offset(match['offset_dst']) else: # default to an hour difference if it's not specified offset_dst = offset - datetime.timedelta(0, SECONDS_IN_ONE_HOUR) dst_start = None dst_end = None match = POSIX_VAR.match(posix_env_var) if match: match = match.groupdict() dst_start = match['start'] dst_end = match['end'] match = POSIX_VAR_DST_RRULE.match(dst_start) details = match.groupdict() byday = details['week'] + DAY_ABBREVIATIONS[int(details['day'])] dst_start = icalendar.vRecur({ 'BYMONTH': details['month'], 'FREQ': 'YEARLY', 'INTERVAL': 1, 'BYDAY': byday }) match = POSIX_VAR_DST_RRULE.match(dst_end) details = match.groupdict() byday = details['week'] + DAY_ABBREVIATIONS[int(details['day'])] dst_end = icalendar.vRecur({ 'BYMONTH': details['month'], 'FREQ': 'YEARLY', 'INTERVAL': 1, 'BYDAY': byday }) else: # remove the dst offset if not rrule is present on when it's active offset_dst = None details = TimezoneOffsetDetails(offset, offset_dst, dst_start, dst_end) return details
def makeEvent(term_start, term_end, section, meeting_time, uid): event = icalendar.Event() event.add('uid', uid) event.add('summary', '%s %s' % (section['course_code'], section['section'])) first_day = firstOccurrence(term_start, meeting_time['days']) event.add('dtstart', replaceTime(first_day, meeting_time['start'])) event.add('dtend', replaceTime(first_day, meeting_time['end'])) event.add('dtstamp', section['user_updated']) event.add('categories', 'CLASS') rrule = icalendar.vRecur( freq='weekly', byday=icalDaysOfWeek(meeting_time['days']), until=term_end, ) event.add('rrule', rrule) descr = io.StringIO() descr.write(section['course_name']) if 'type' in meeting_time: descr.write('\n' + meeting_time['type']) if section['instructors']: descr.write('\n\nInstructor') if len(section['instructors']) > 1: descr.write('s') descr.write(': ') descr.write(', '.join( util.name(instr) for instr in section['instructors'])) event.add('description', descr.getvalue()) if meeting_time.get('building') or meeting_time.get('room'): loc = '%s %s' % (meeting_time.get('building', ''), meeting_time.get('room', '')) event.add('location', loc.strip()) return event
def mk_ical(lvinfos, endtimes): cal = Calendar() cal.add('prodid', '-//swt-ps//python-icalendar//DE') cal.add('version', '2.0') for uri in lvinfos: title,start,end,day,location = lvinfos[uri] event = Event() event.add('uid', uri) start_day = time_conversion.first_day(lvinfos[uri][3][:2]) shour, sminute = start.split(':') ehour, eminute = end.split(':') sttime = datetime.datetime(start_day.year, start_day.month,\ start_day.day, hour = int(shour), minute = int(sminute)) endtime = datetime.datetime(start_day.year, start_day.month,\ start_day.day, hour = int(ehour), minute = int(eminute)) event.add('dtstamp', datetime.datetime.today()) event.add('summary', title) recur = vRecur(byday=biweekly[day][0], freq='weekly',\ until=endtimes[uri]) if biweekly[day][1] == "A": if start_day.isocalendar()[1] % 2 == 0: sttime = sttime + datetime.timedelta(weeks=1) endzeit = endzeit + datetime.timedelta(weeks=1) recur['interval'] = 2 elif biweekly[day][1] == "B": if start_day.isocalendar()[1] % 2 == 1: sttime = sttime + datetime.timedelta(weeks=1) endtime = endtime + datetime.timedelta(weeks=1) recur['interval'] = 2 event.add('dtstart', sttime) event.add('dtend', endtime) event.add('rrule', recur) cal.add_component(event) return cal
def convert(content): soup = BeautifulSoup(content) entries = [cell.span.text for cell in soup.find_all(name="td", attrs={"class": "allocated"})] entries = [filter(lambda x: len(x) > 0, map(lambda x: x.strip(), e.split("\n"))) for e in entries] d = datetime.datetime(datetime.date.today().year - 1, 1, 1, tzinfo=pytz.timezone("Europe/Ljubljana")) d = d - datetime.timedelta(d.weekday()) # find monday cal = Calendar() cal.add("prodid", "-//FRiCal//SL") cal.add("version", "2.0") for e in entries: dt_tokens = e[0].split(" ") # u'sreda 08:00 - 11:00' weekday = weekday_names.index(dt_tokens[0]) time_start = int(dt_tokens[1].split(":")[0]) time_end = int(dt_tokens[3].split(":")[0]) d_start = d + datetime.timedelta(days=weekday, hours=time_start) d_end = d + datetime.timedelta(days=weekday, hours=time_end) summary = "%s; %s" % (e[2], e[1]) description = "%s\n%s" % (e[3], "\n".join(e[4:])) event = Event() event.add("dtstart", d_start) event.add("dtend", d_end) event.add("dtstamp", d) event.add("rrule", vRecur(freq="daily", interval=7)) event.add("summary", summary) event.add("description", description) cal.add_component(event) return cal.to_ical()
def add_all_saints_eve(self, year): """Add recurring event for all saint's eve.""" event = Holiday(date(year, 1, 1), 'Allhelgonaafton', Work.DEPENDS) rrule = vRecur() rrule['FREQ'] = vFrequency('YEARLY') rrule['BYDAY'] = vWeekday('FR') rrule['BYMONTHDAY'] = (30, 31) rrule['BYMONTH'] = 10 event.add('rrule', rrule) self.add_component(event) event2 = Holiday(date(year, 1, 1), 'Allhelgonaafton', Work.DEPENDS) rrule2 = vRecur() rrule2['FREQ'] = vFrequency('YEARLY') rrule2['BYDAY'] = vWeekday('FR') rrule2['BYMONTHDAY'] = (1, 2, 3, 4, 5) rrule2['BYMONTH'] = 11 event2.add('rrule', rrule2) self.add_component(event2)
def add_all_saints_day(self, year): """Add recurring event for all saint's day.""" event = Holiday(date(year, 1, 1), 'Alla helgons dag') rrule = vRecur() rrule['FREQ'] = vFrequency('YEARLY') rrule['BYDAY'] = vWeekday('SA') rrule['BYMONTHDAY'] = 31 rrule['BYMONTH'] = 10 event.add('rrule', rrule) self.add_component(event) event2 = Holiday(date(year, 1, 1), 'Alla helgons dag') rrule2 = vRecur() rrule2['FREQ'] = vFrequency('YEARLY') rrule2['BYDAY'] = vWeekday('SA') rrule2['BYMONTHDAY'] = (1, 2, 3, 4, 5, 6) rrule2['BYMONTH'] = 11 event2.add('rrule', rrule2) self.add_component(event2)
def test_parse_tz_posix_env_var_australia_melbourne(self): expected = ics.TimezoneOffsetDetails( offset=datetime.timedelta(0, 36000), offset_dst=datetime.timedelta(0, 32400), dst_start=icalendar.vRecur({ 'BYMONTH': '10', 'FREQ': 'YEARLY', 'INTERVAL': 1, 'BYDAY': '1SU' }), dst_end=icalendar.vRecur({ 'BYMONTH': '4', 'FREQ': 'YEARLY', 'INTERVAL': 1, 'BYDAY': '1SU' }) ) self.assertParsedTimezoneOffsetDetailsMatch('Australia/Melbourne', expected)
def test_parse_tz_posix_env_var_america_new_york(self): expected = ics.TimezoneOffsetDetails( offset=datetime.timedelta(-1, 68400), offset_dst=datetime.timedelta(-1, 64800), dst_start=icalendar.vRecur({ 'BYMONTH': '3', 'FREQ': 'YEARLY', 'INTERVAL': 1, 'BYDAY': '2SU' }), dst_end=icalendar.vRecur({ 'BYMONTH': '11', 'FREQ': 'YEARLY', 'INTERVAL': 1, 'BYDAY': '1SU' }) ) self.assertParsedTimezoneOffsetDetailsMatch('America/New_York', expected)
def test_parse_tz_posix_env_var_australia_melbourne(self): expected = ics.TimezoneOffsetDetails( offset=datetime.timedelta(0, 36000), offset_dst=datetime.timedelta(0, 32400), dst_start=icalendar.vRecur({ 'BYMONTH': '10', 'FREQ': 'YEARLY', 'INTERVAL': 1, 'BYDAY': '1SU' }), dst_end=icalendar.vRecur({ 'BYMONTH': '4', 'FREQ': 'YEARLY', 'INTERVAL': 1, 'BYDAY': '1SU' })) self.assertParsedTimezoneOffsetDetailsMatch('Australia/Melbourne', expected)
def test_parse_tz_posix_env_var_america_new_york(self): expected = ics.TimezoneOffsetDetails( offset=datetime.timedelta(-1, 68400), offset_dst=datetime.timedelta(-1, 64800), dst_start=icalendar.vRecur({ 'BYMONTH': '3', 'FREQ': 'YEARLY', 'INTERVAL': 1, 'BYDAY': '2SU' }), dst_end=icalendar.vRecur({ 'BYMONTH': '11', 'FREQ': 'YEARLY', 'INTERVAL': 1, 'BYDAY': '1SU' })) self.assertParsedTimezoneOffsetDetailsMatch('America/New_York', expected)
def add_midsummer_day(self, year): """Add recurring event for the midsummer day.""" event = Holiday(date(year, 1, 1), 'Midsommardagen') rrule = vRecur() rrule['FREQ'] = vFrequency('YEARLY') rrule['BYDAY'] = vWeekday('SA') rrule['BYMONTHDAY'] = (20, 21, 22, 23, 24, 25, 26) rrule['BYMONTH'] = 6 event.add('rrule', rrule) self.add_component(event)
def parse_tz_posix_env_var(posix_env_var): """ Get the details regarding a timezone by parsing the POSIX style TZ environment variable. :param str posix_env_var: The POSIX style TZ environment variable. :return: The parsed TZ environment variable. :rtype: :py:class:`.TimezoneOffsetDetails` """ match = POSIX_VAR_OFFSET.match(posix_env_var) if match is None: return match = match.groupdict() offset = get_timedelta_for_offset(match['offset']) if match['offset_dst'] is None: offset_dst = None elif len(match['offset_dst']): offset_dst = get_timedelta_for_offset(match['offset_dst']) else: # default to an hour difference if it's not specified offset_dst = offset - datetime.timedelta(0, SECONDS_IN_ONE_HOUR) dst_start = None dst_end = None match = POSIX_VAR.match(posix_env_var) if match: match = match.groupdict() dst_start = match['start'] dst_end = match['end'] match = POSIX_VAR_DST_RRULE.match(dst_start) details = match.groupdict() byday = details['week'] + DAY_ABBREVIATIONS[int(details['day'])] dst_start = icalendar.vRecur({'BYMONTH': details['month'], 'FREQ': 'YEARLY', 'INTERVAL': 1, 'BYDAY': byday}) match = POSIX_VAR_DST_RRULE.match(dst_end) details = match.groupdict() byday = details['week'] + DAY_ABBREVIATIONS[int(details['day'])] dst_end = icalendar.vRecur({'BYMONTH': details['month'], 'FREQ': 'YEARLY', 'INTERVAL': 1, 'BYDAY': byday}) else: # remove the dst offset if not rrule is present on when it's active offset_dst = None details = TimezoneOffsetDetails(offset, offset_dst, dst_start, dst_end) return details
def add_midsummers_eve(self, year): """Add recurring event for midsummer's eve.""" event = Holiday(date(year, 1, 1), 'Midsommarafton', Work.DEFACTO) rrule = vRecur() rrule['FREQ'] = vFrequency('YEARLY') rrule['BYDAY'] = vWeekday('FR') rrule['BYMONTHDAY'] = (19, 20, 21, 22, 23, 24, 25) rrule['BYMONTH'] = 6 event.add('rrule', rrule) self.add_component(event)
def on_button_ok__clicked(self, *args): new_recur = icalendar.vRecur() if self.radio_once.get_active(): new_recur = {} elif self.radio_daily.get_active(): new_recur['FREQ'] = ['DAILY'] new_recur['INTERVAL'] = [self.spinbutton_daily_interval.get_value()] elif self.radio_weekly.get_active(): new_recur['FREQ'] = ['WEEKLY'] new_recur['INTERVAL'] = [self.spinbutton_weekly_interval.get_value()] byday = [] if self.checkbutton_weekly_mon.get_active(): byday.append('MO') if self.checkbutton_weekly_tue.get_active(): byday.append('TU') if self.checkbutton_weekly_wed.get_active(): byday.append('WE') if self.checkbutton_weekly_thu.get_active(): byday.append('TH') if self.checkbutton_weekly_fri.get_active(): byday.append('FR') if self.checkbutton_weekly_sat.get_active(): byday.append('SA') if self.checkbutton_weekly_sun.get_active(): byday.append('SU') if byday: new_recur['BYDAY'] = byday elif self.radio_monthly.get_active(): new_recur['FREQ'] = ['MONTHLY'] new_recur['INTERVAL'] = [self.spinbutton_monthly_interval.get_value()] if self.radiobutton_monthly_recur_mday.get_active(): bmd_index = self.combobox_monthly_recur_mday.get_active() if bmd_index > 30: bmd_index = 29 - bmd_index bmd_index += 1 new_recur['BYMONTHDAY'] = [bmd_index] elif self.radiobutton_monthly_recur_week.get_active(): bd_index = self.combobox_monthly_recur_week_nr.get_active() if bd_index > 4: bd_index = 3 - bd_index bd_index += 1 wd_index = self.combobox_monthly_recur_week_day.get_active() new_recur['BYDAY'] = ['%i%s' % (bd_index, weekdays[wd_index])] elif self.radio_yearly.get_active(): new_recur['FREQ'] = ['YEARLY'] new_recur['INTERVAL'] = [self.spinbutton_yearly_interval.get_value()] if self.radiobutton_yearly_recur_dom.get_active(): new_recur['BYMONTHDAY'] = [self.spinbutton_yearly_recur_dom_nr.get_value()] new_recur['BYMONTH'] = [self.combobox_yearly_recur_dom_month.get_active() + 1] elif self.radiobutton_yearly_recur_wom.get_active(): bd_index = self.combobox_yearly_recur_wom_nr.get_active() if bd_index > 4: bd_index = 3 - bd_index bd_index += 1 dow_index = self.combobox_yearly_recur_wom_dow.get_active() new_recur['BYDAY'] = ['%i%s' % (bd_index, weekdays[dow_index])] new_recur['BYMONTH'] = [self.combobox_yearly_recur_wom_month.get_active() + 1] elif self.radiobutton_yearly_recur_doy.get_active(): new_recur['BYYEARDAY'] = [self.spinbutton_yearly_recur_doy_nr.get_value()] self.recur = new_recur self.quit()
def crearEvento(fe, nom, desc): evento = Event() time.sleep( 0.10 ) # Genero un retardo para que aquellos cumpleaños con misma fecha puedan almacenarse correctamente evento.add('summary', 'Cumpleaños de ' + nom) evento.add('dtstart', fe) evento.add('dtend', fe) evento.add('rrule', vRecur(freq='yearly')) evento.add('description', desc) return evento
def icalendar_event(self): if self.context.birth_date is None: return summary = '%s (*%s)' % (icemac.addressbook.interfaces.ITitle( self.context), self.context.birth_date.year) return icalendar.Event( uid=self.url(self.context, 'iCalendar'), summary=summary, dtstart=icalendar.vDate(self.context.birth_date), dtend=icalendar.vDate(self.context.birth_date + ONE_DAY), rrule=icalendar.vRecur(freq='yearly'))
def serialize_repeatability(startDT, endDT, repType): intervals = { RepeatabilityEnum.onceAWeek: 1, RepeatabilityEnum.onceEvery2Weeks: 2, RepeatabilityEnum.onceEvery3Weeks: 3 } recur = ical.vRecur() recur['until'] = endDT if repType == RepeatabilityEnum.daily: recur['freq'] = 'daily' elif repType in intervals.keys(): recur['freq'] = 'weekly' recur['interval'] = intervals[repType] elif repType == RepeatabilityEnum.onceAMonth: recur['freq'] = 'monthly' recur['byday'] = str(weekNumber(startDT)) + WEEK_DAYS[startDT.weekday()] return recur
def add_timezone(cal): cal.add('x-wr-timezone', TZID) timezone = Timezone() timezone.add('tzid', TZID) tz_std = TimezoneStandard() tz_std.add('dtstart', vText(arrow.get('2006-11-06 02:00').format('YYYYMMDDTHHmmss'))) tz_std.add('rrule', vRecur(freq='YEARLY', bymonth='11', byday='+1SU')) tz_std.add('tzoffsetfrom', timedelta(hours=-4)) tz_std.add('tzoffsetto', timedelta(hours=-5)) tz_std.add('tzname', "EST") timezone.add_component(tz_std) tz_dst = TimezoneDaylight() tz_dst.add('dtstart', vText(arrow.get('2006-03-13 02:00').format('YYYYMMDDTHHmmss'))) tz_dst.add('rrule', vRecur(freq='YEARLY', bymonth='3', byday='+2SU')) tz_dst.add('tzoffsetfrom', timedelta(hours=-5)) tz_dst.add('tzoffsetto', timedelta(hours=-4)) tz_dst.add('tzname', "EDT") timezone.add_component(tz_dst) cal.add_component(timezone)
def serialize_repeatability(startDT, endDT, repType): intervals = { RepeatabilityEnum.onceAWeek: 1, RepeatabilityEnum.onceEvery2Weeks: 2, RepeatabilityEnum.onceEvery3Weeks: 3, } recur = ical.vRecur() recur["until"] = endDT if repType == RepeatabilityEnum.daily: recur["freq"] = "daily" elif repType in intervals.keys(): recur["freq"] = "weekly" recur["interval"] = intervals[repType] elif repType == RepeatabilityEnum.onceAMonth: recur["freq"] = "monthly" recur["byday"] = str(weekNumber(startDT)) + WEEK_DAYS[startDT.weekday()] return recur
def kurzusize(nap, darabos, hely, kurzus): event = Event() event.add("summary", kurzus) # 0: vasárnap, hogy könnyen tudjuk felpakolni az első hétre az eseményeket. # darabos óra + 1? időzóna, my friend. utc-ben dolgozunk, mert különben kéne időzónát gyártani, # viszont errefelé utc+1/utc+2 van. szerencsére nem kavar be a márciusvégi időszámítás-váltás, # a hozzáadáskori időzónához igazodik a kliens, ha jól nézem. hozzaadando = ahetnapjai.index(nap) event.add("dtstart", datetime(2010, 2, 7 + hozzaadando, darabos[0] - 1, darabos[1], 0, tzinfo=UTC)) event.add("dtend", datetime(2010, 2, 7 + hozzaadando, darabos[2] - 1, darabos[3], 0, tzinfo=UTC)) event.add( "dtstamp", datetime(2010, 1, 29, 0, 10, 0, tzinfo=UTC) ) # "mikor adták hozzá vagy módosították az eseményt". lényegtelen, de kell. event.add("location", hely) recur = vRecur(freq="weekly", byday=nap, count=15) # kézzel számoltam, vigyázz! event.add("rrule", recur) return event
def icalevent(e): if not all(prop in e for prop in ['date', 'title']): return iev = Event() iev.add('dtstamp', datetime.now()) iev.add('dtstart', e['date']) iev.add('dtend', e['date'] + timedelta(1)) rrule = vRecur() rrule['freq'] = vFrequency('yearly') iev.add('rrule', rrule) iev.add('summary', vText("{:04d}: {}".format(e['date'].year, e['title']))) iev.add('uid', "{}@icalaniversary.invalid".format(slugify(iev['summary']))) desc = [e.get('link'), e.get('desc')] if any(desc): desc = "\n".join([x for x in desc if x]) iev.add('description', vText(desc)) return iev
def build_calendar(daily_events, day2abrev, day2key, code2name, end_date, repeat): end_grad = datetime.datetime.strptime(end_date, '%Y-%m-%d') cal = Calendar() now = datetime.datetime.now() year = now.year month = now.month weekday = now.day days_left = end_grad - now if not repeat: weeks_left = int(days_left.days / 7) + 1 else: weeks_left = int(repeat) + 1 for day, events in daily_events.items(): next_day = now + datetime.timedelta(days=(day2key[day] - now.weekday()) % 7) next_day = next_day.day for ev in events: if ev: event = Event() begin = ev[0][0] end = ev[0][1] description = ev[1].split("-")[0] title = code2name[description] place = ev[2] event.add('summary', title) event.add('location', place) event.add('description', description) begin_hour, begin_minute = begin.split(":") end_hour, end_minute, end_second = end.split(":") event.add('dtstart', datetime.datetime(year, month, next_day, \ hour=int(begin_hour), minute=int(begin_minute))) event.add('dtend', datetime.datetime(year, month, next_day, \ hour=int(end_hour), minute=int(end_minute))) event['RRULE'] = vRecur({'COUNT': [weeks_left], \ 'FREQ': ['WEEKLY'], \ 'BYDAY': day2abrev[day]}) cal.add_component(event) return cal
def addEvent(self, node, date): strings = node.findAll(text=True) event = Event() event.add("summary", strings[0]) match = re.search("(\d\d?:\d\d [ap]m)-(\d\d?:\d\d [ap]m)", strings[2]) if match is None: print >> stderr, "Warning: Could not parse time string, %s" % strings[2] return False else: event.add("dtstart", datetime.strptime(date + match.group(1), "%Y-%m-%d %I:%M %p")) event.add("dtend", datetime.strptime(date + match.group(2), "%Y-%m-%d %I:%M %p")) if self.enddate is not None: recur = vRecur(freq="WEEKLY", until=self.enddate) event.add("rrule", recur, encode=0) event.add("location", strings[3]) self.calendar.add_component(event)
def add_event(self, ev): """ Add a new recurrent event to this schedule """ day = self._get_first_weekday(ev.day) dtstart = datetime.combine(day, ev.tstart) dtend = datetime.combine(day, ev.tend) tz_params = {'tzid': 'Europe/Paris'} iev = Event() iev.add('uid', str(uuid4())) iev.add('status', 'confirmed') iev.add('dtstart', dtstart, parameters=tz_params) iev.add('dtend', dtend, parameters=tz_params) iev.add('rrule', vRecur(self._recur_params(ev.day))) iev.add('summary', '%s %s' % (ev.type_, ev.title)) iev.add('location', ev.room) iev.add('description', ev.description) self.cal.add_component(iev)
def fill_term(self, schedule, term): parser = PeriodParser(schedule['year'], term) for evt in schedule[term]: vevt = Event() dtstart, dtend = parser.parse(evt) vevt.add('dtstart', dtstart) vevt.add('dtend', dtend) # set info vevt.add('summary', evt['summary']) vevt.add('description', evt['description']) # set RRULE rec = vRecur() rec['FREQ'] = 'WEEKLY' rec['BYDAY'] = evt['weekday'] rec['UNTIL'] = parser.eot vevt.add('RRULE', rec) self.ical.add_component(vevt)
def create_events( first: date, last: date, excludes: List[date], timetable: List[Tuple[str, List[int], time, time, str]], ) -> Iterator[icalendar.Event]: for summary, days, start, end, location in timetable: event = icalendar.Event() first_day = get_first_day(first, days) event.add("DTSTART", datetime.combine(first_day, start)) event.add("DTEND", datetime.combine(first_day, end)) event.add("SUMMARY", summary) event.add("LOCATION", location) recur = icalendar.vRecur() recur["FREQ"] = "WEEKLY" recur["UNTIL"] = datetime.combine(last, end) recur["BYDAY"] = list(map(DAYS.get, days)) event.add("RRULE", recur) for exclude in excludes: event.add("EXDATE", datetime.combine(exclude, start)) yield event
def as_ical(self, description=None, rrule=None, url=None): """ Returns the occurrence as iCalendar string. """ event = icalendar.Event() event.add("summary", self.title) event.add("dtstart", to_timezone(self.start, UTC)) event.add("dtend", to_timezone(self.end, UTC)) event.add("last-modified", self.modified or self.created or datetime.utcnow()) event["location"] = icalendar.vText(self.location) if description: event["description"] = icalendar.vText(description) if rrule: event["rrule"] = icalendar.vRecur(icalendar.vRecur.from_ical(rrule.replace("RRULE:", ""))) if url: event.add("url", url) cal = icalendar.Calendar() cal.add("prodid", "-//OneGov//onegov.event//") cal.add("version", "2.0") cal.add_component(event) return cal.to_ical()
def lesson_as_ical_event(lesson, lesson_date, timetable): event = Event() event.add('uuid', lesson_uuid(lesson)) event.add('summary', lesson.subject) addr = vCalAddress('MAILTO:[email protected]') addr.params['CN'] = lesson.tutor.encode('utf-8') event['organizer'] = addr event.add('location', lesson.auditory) event.add('rrule', vRecur({'freq': 'WEEKLY', 'interval': 2})) start_time = timetable.start(lesson.number) end_time = timetable.end(lesson.number) event['dtstart'] = vDatetime( datetime(lesson_date.year, lesson_date.month, lesson_date.day, start_time.hour, start_time.minute, tzinfo=start_time.tzinfo)) event['dtend'] = vDatetime( datetime(lesson_date.year, lesson_date.month, lesson_date.day, end_time.hour, end_time.minute, tzinfo=end_time.tzinfo)) return event
def genICal(data, modCode, index): cal = icalendar.Calendar() cal.add('prodid', '-//NTUmodswap bot//') cal.add('version', '2.0') cal.add('method', 'PUBLISH') for i in data[index]: event = icalendar.Event() event.add('summary', modCode + " " + i.type) event.add('location', i.loc) if i.type == "TUT": event.add( 'dtstart', timedelta(days=7) + transformTime(i.day, int(i.time[0:2]), int(i.time[2:4]))) event.add( 'dtend', timedelta(days=7) + transformTime(i.day, int(i.time[5:7]), int(i.time[7:9]))) else: event.add('dtstart', transformTime(i.day, int(i.time[0:2]), int(i.time[2:4]))) event.add('dtend', transformTime(i.day, int(i.time[5:7]), int(i.time[7:9]))) event.add('dtstamp', datetime.now()) event.add('rrule', icalendar.vRecur({ "FREQ": "WEEKLY", "UNTIL": semEnd })) event.add( 'exdate', transformTime(i.day, int(i.time[0:2]), int(i.time[2:4]), recess)) cal.add_component(event) # print(str(cal.to_ical())) return cal.to_ical()
def rrule(self): byweekday = '+{}{}'.format(self.week, dateutil.rrule.weekday(self.day_of_the_week)) return icalendar.vRecur(freq='MONTHLY', interval=self.skip_months + 1, byday=byweekday)
start_date = datetime.datetime.strptime( (date["start_date"]), "%Y-%m-%d") + d end_date = datetime.datetime.strptime( (date["end_date"]), "%Y-%m-%d") + d start_hour = datetime.timedelta(hours=ev['start_time']) duration = datetime.timedelta(hours=int(ev['duration'])) start_date_time = (start_date + start_hour) end_date_time = (start_date_time + duration) event = Event() event.add('summary', ev['title']) event.add('location', ev['location']) recur = vRecur(FREQ='weekly', UNTIL=end_date) event.add('rrule', recur) event.add('dtstart', start_date_time) # Add an extra day as RFC2445 appears to suggest that is the correct way, # and that's the way Google Calendar treats it event.add('dtend', end_date_time) event.add('class', 'PUBLIC') cal.add_component(event) sys.stdout.write(cal.to_ical()) # should validate at http://icalvalid.cloudapp.net/ import dateutil.parser import datetime, time import scraperwiki
startdate = date(year, startmonth, startday) startWeekday = startdate.weekday() delta = 0 while (startWeekday not in courseStartWeekdays): delta += 1 startWeekday += 1 if (startWeekday > 6): startWeekday = 0 startdate += timedelta(days=delta) # Make .ics file cal = Calendar() cal.add('prodid', 'I School Course Calendar') cal.add('version', '2.0') event = Event() event.add('summary', coursetitle) event.add('location', course.location) event.add('dtstart', datetime(year,startdate.month, startdate.day,starthour,startminute,0)) event.add('dtend', datetime(year,startdate.month,startdate.day,endhour,endminute,0)) event.add('tzid', 'California-Los_Angeles') finishedt = datetime(year,endmonth,endday,0,0,0) event.add('rrule', vRecur(freq='weekly', byday=coursedays, until=finishedt)) cal.add_component(event) f = open(coursetitle + '.ics', 'wb') f.write(cal.as_string()) print 'Wrote: ' + coursetitle + '.ics' f.close()
def rrule(self): return icalendar.vRecur(freq='MONTHLY', interval=self.skip_months + 1, bymonthday=self.date)
def __init__(self, dtstart, summary, work=Work.FREE): super().__init__(dtstart, summary, work) rrule = vRecur() rrule['FREQ'] = vFrequency('YEARLY') self.add('rrule', rrule)
def rrule(self): byday = dateutil.rrule.weekday(self.day_of_the_week) return icalendar.vRecur(freq='weekly', interval=self.skip_weeks + 1, byday=byday)
def generate_recurrence_rule(interval, lastdate): until = lastdate + timedelta(hours=23, minutes=59, seconds=59) # 最后一周结束 return vRecur(freq="WEEKLY", until=until, interval=interval)
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 to_ical(self): rrule = icalendar.vRecur( dict((k, v) for k, v in self.to_dict(True).items() if not (type(v) == str and v == '' or type(v) == list and len(v) == 0))) return rrule
delta += 1 startWeekday += 1 if (startWeekday > 6): startWeekday = 0 startdate += timedelta(days=delta) # Make .ics file cal = Calendar() cal.add('prodid', 'I School Course Calendar') cal.add('version', '2.0') event = Event() event.add('summary', coursetitle) event.add('location', course.location) event.add( 'dtstart', datetime(year, startdate.month, startdate.day, starthour, startminute, 0)) event.add( 'dtend', datetime(year, startdate.month, startdate.day, endhour, endminute, 0)) event.add('tzid', 'California-Los_Angeles') finishedt = datetime(year, endmonth, endday, 0, 0, 0) event.add('rrule', vRecur(freq='weekly', byday=coursedays, until=finishedt)) cal.add_component(event) f = open(coursetitle + '.ics', 'wb') f.write(cal.as_string()) print 'Wrote: ' + coursetitle + '.ics' f.close()
def map_event(self, e): """Convert a palmFile event into an icalendar.Event.""" event = icalendar.Event() event.add('dtstart', self.mkdate(e['startTime'], e['untimed'])) event.add('dtend', self.mkdate(e['endTime'], e['untimed'])) event.add('summary', self.clean(e['text'])) if e['note']: event.add('description', self.clean(e['note'])) if e['category']: event.add('categories', self.categories[e['category']]) repeat = e['repeatEvent'] if repeat['repeatEventFlag'] == 0: # No recurrence return event if repeat.get('dateExceptions'): event['exdate'] = icalendar.prop.vDDDLists([self.mkdate(exc, e['untimed']) for exc in repeat['dateExceptions']]) recur = icalendar.vRecur() recur['until'] = self.mkdate(repeat['endDate'], e['untimed']) if repeat['interval'] != 1: recur['interval'] = repeat['interval'] if repeat['brand'] == 1: # Daily recur['freq'] = 'daily' # Repeat every sth day of the week recur['byday'] = [self.DAY_NAMES[repeat['brandDayIndex']]] elif repeat['brand'] == 2: # weekly recur['freq'] = 'weekly' # Mask of week days to use # 1 => Sunday, 2 => Monday, 4 => Tuesday, 64 => Saturday days_mask = ord(repeat['brandDaysMask']) for day_mask, day in self.DAYMASK_TRANSLATION.items(): days = [] if days_mask & day_mask: days.append(day) if days: recur['byday'] = days elif repeat['brand'] == 3: # monthly, by day recur['freq'] = 'monthly' # Day of the week recur['byday'] = [self.DAY_NAMES[repeat['brandDayIndex']]] # Week of the month if repeat['brandWeekIndex'] == 4: # Last week of the month recur['bysetpos'] = -1 else: recur['bysetpos'] = repeat['brandWeekIndex'] elif repeat['brand'] == 4: # monthly, by date recur['freq'] = 'monthly' # Day in the month recur['bymonthday'] = repeat['brandDayNumber'] elif repeat['brand'] == 5: # yearly, by date recur['freq'] = 'yearly' # Day in the month recur['bymonthday'] = repeat['brandDayNumber'] # Month in the year recur['bymonth'] = repeat['brandMonthIndex'] + 1 elif repeat['brand'] == 6: # yearly, by day recur['freq'] = 'yearly' event['rrule'] = recur return event
def create_ics(courses, filename): cal = Calendar() for c in courses: course = courses[c] # create a new calender event for each lecture time (for classes like ENGR 120) for schedule in course["schedule"]: event = Event() # Time formatting is similar to unix "date" command start_time = datetime.strptime( f'{schedule["start_date"]} {schedule["start_time"]}', '%b %d, %Y %I:%M %p') end_time = datetime.strptime( f'{schedule["start_date"]} {schedule["end_time"] }', '%b %d, %Y %I:%M %p') end_date = datetime.strptime( f'{schedule["end_date"] } {schedule["end_time"] }', '%b %d, %Y %I:%M %p') days = schedule["days"] numeric_days = [] for d in days: numeric_days.append(ics_day_to_number(d)) # fix if the start date is not an included day while start_time.weekday() not in numeric_days: try: start_time = start_time.replace(day=start_time.day + 1) except ValueError: if start_time.month == 12: start_time = start_time.replace(day=1, month=1, year=start_time.year + 1) else: start_time = start_time.replace( day=1, month=start_time.month + 1) else: # update end time accordingly end_time = datetime.combine(date=start_time.date(), time=end_time.time()) event.add("summary", f"{course['code']} {course['section']}") event.add("dtstart", start_time) event.add("dtend", end_time) event.add("dtstamp", datetime.now()) event.add("location", schedule["location"]) event.add( 'rrule', vRecur({ "freq": "WEEKLY", "interval": 1, "until": end_date, "byday": days })) cal.add_component(event) with open(f"{filename}.ics", "wb") as f: f.write(cal.to_ical()) f.close()
start_date = datetime.datetime.strptime((date["start_date"]), "%Y-%m-%d")+d end_date = datetime.datetime.strptime((date["end_date"]), "%Y-%m-%d")+d start_hour = datetime.timedelta(hours=ev['start_time']) duration = datetime.timedelta(hours=int(ev['duration'])) start_date_time = (start_date+start_hour) end_date_time = (start_date_time+duration) event = Event() event.add('summary', ev['title']) event.add('location', ev['location']) recur = vRecur(FREQ='weekly', UNTIL=end_date) event.add('rrule', recur) event.add('dtstart',start_date_time) # Add an extra day as RFC2445 appears to suggest that is the correct way, # and that's the way Google Calendar treats it event.add('dtend', end_date_time) event.add('class', 'PUBLIC') cal.add_component(event) sys.stdout.write(cal.to_ical()) # should validate at http://icalvalid.cloudapp.net/ import dateutil.parser import datetime, time import scraperwiki
def test_recur(): event = Event.fromString(_get_text('event_dt_rr'), **EVENT_KWARGS) assert event.recurring is True assert event.recurpattern == 'FREQ=DAILY;COUNT=10' assert event.recurobject == vRecur({'COUNT': [10], 'FREQ': ['DAILY']})
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 recurobject(self): if 'RRULE' in self._vevents[self.ref]: return self._vevents[self.ref]['RRULE'] else: return icalendar.vRecur()
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")