def get_aggregated_ical(sources): aggregated_calendar = ics.Calendar() for ics_url in glom(sources, ["ics_url"]): minor_calendar = ics.Calendar(requests.get(ics_url).text) aggregated_calendar.events.update(minor_calendar.events) return aggregated_calendar
def load_calendar(filename): try: return ics.Calendar(open(f"{filename}").read()) except: hash_ = open("hashfile.txt", "r").read() save_calendar("calendar.ics", requests.get(f"https://cocktail.insa-rouen.fr/ics/perso/{hash_}").text, hash_) return ics.Calendar(open(f"{filename}").read())
def ical(self, session, **params): icalendar = ics.Calendar() if 'locations' not in params or not params['locations']: locations = [id for id, name in c.EVENT_LOCATION_OPTS] calname = "full" else: locations = json.loads(params['locations']) if len(locations) > 3: calname = "partial" else: calname = "_".join([name for id, name in c.EVENT_LOCATION_OPTS if str(id) in locations]) calname = '{}_{}_schedule'.format(c.EVENT_NAME, calname).lower().replace(' ', '_') for location in locations: for event in session.query(Event)\ .filter_by(location=int(location))\ .order_by('start_time').all(): icalendar.events.add(ics.Event( name=event.name, begin=event.start_time, end=(event.start_time + timedelta(minutes=event.minutes)), description=normalize_newlines(event.description), created=event.created.when, location=event.location_label)) cherrypy.response.headers['Content-Type'] = \ 'text/calendar; charset=utf-8' cherrypy.response.headers['Content-Disposition'] = \ 'attachment; filename="{}.ics"'.format(calname) return icalendar
def class_cal(sched): cal = ics.Calendar() rows = re.split(r"(^\d{2}:\d{2}$)", sched, flags = re.MULTILINE) dates = [23,24,25,26, 23,24,25,26, 27, 23,25, 25, 27, 25] idx = 0 for row in rows[2::2]: row = tuple(filter(not_empty, row.splitlines())) for name, full_name, type_, duration, location in chunks(row, 5): def parse_time(time_str): nonlocal idx time = arrow.get(f"{dates[idx]} {time_str}", "D HH:mm", **arrow_cfg) return time.replace(**{attr: getattr(arrow.now(), attr) for attr in ("year", "month")}) begin, end = map(parse_time, duration.replace(" ", "").split("-")) idx+=1 logging.debug(name) logging.debug(begin.humanize()) cal.events.add(ics.Event(name=name+"\n"+full_name, begin = begin, end = end, location = location)) logging.debug("\n") return cal
def add_events(path): courses = config.courses c = ics.Calendar() start_date = datetime.datetime.strptime(config.start_time, '%Y-%m-%d') tz = pytz.timezone('Asia/Taipei') for course in courses: course_name = course[0] course_description = '学分:' + str(course[1]) course_weeks = course[2] course_week = course[3] course_section = course[4] course_location = course[5] for week in course_weeks: e = ics.Event() e.location = course_location e.description = course_description e.name = course_name delta = datetime.timedelta(days=(week - 1) * 7 + course_week) temp = start_date + delta s_time = temp.strftime('%Y:%m:%d') + ' ' + classStartTimeJA[ course_section[0] - 1] e_time = temp.strftime('%Y:%m:%d') + ' ' + classEndTimeJA[ course_section[-1] - 1] d1 = datetime.datetime.strptime(s_time, '%Y:%m:%d %H:%M:%S') d2 = datetime.datetime.strptime(e_time, '%Y:%m:%d %H:%M:%S') d1 = d1.replace(tzinfo=tz) d2 = d2.replace(tzinfo=tz) delta = datetime.timedelta(minutes=6) d1 = d1 + delta d2 = d2 + delta e.begin = d1 e.end = d2 c.events.append(e) with open(path, 'w') as f: f.writelines(c)
def ical_output(promo, classes): cal = ics.Calendar(creator=PRODID) for c in classes: name = '{}-{}'.format(c.get('name'), c.get('prof')) name = re.sub(r"[^\w]", "_", name) uid = 'chronos-{}-{}-{}'.format(promo, c.get('start'), name) uid = uid.replace(' ', '_') summary = '{}'.format(c.get('name')) if c.get('prof') != '-': summary += ' - {}'.format(c.get('prof')) summary += ' ({})'.format(c.get('room')) description = '\n'.join({ "Cours: {}".format(c.get('name')), "Prof: {}".format(c.get('prof')), "Salle: {}".format(c.get('room')), "Groupes: {}".format('-'.join(c.get('groups'))), }).replace(',', '\\,') paris = pytz.timezone('Europe/Paris') begin, end = map(paris.localize, [c.get('start'), c.get('end')]) cal.events.append( ics.Event(name=summary, begin=begin, end=end, uid=uid, description=description, location=c.get('room').capitalize())) return cal
def save(self, **kwargs): if self.date and self.start_time and self.end_time: begin = datetime.datetime(year=self.date.year, month=self.date.month, day=self.date.day, hour=self.start_time.hour, minute=self.start_time.minute) end = datetime.datetime(year=self.date.year, month=self.date.month, day=self.date.day, hour=self.end_time.hour, minute=self.end_time.minute) tz = pytz.timezone(settings.TIME_ZONE) begin = tz.localize(begin) end = tz.localize(end) sout = cStringIO.StringIO() sout.writelines( ics.Calendar(events=[ ics.Event(name=self.title, begin=begin, end=end, location=str(self.location), description=str(self)) ])) self.ics_file = django.core.files.File(sout, 'event.ics') else: self.ics_file = None super(Event, self).save(**kwargs)
def index(when): date = arrow.get( dateparser.parse(when, settings={"TIMEZONE": "US/Eastern"})) cal = ics.Calendar(requests.get(URL).text) messages = [event.name.lower() for event in cal.timeline.on(date)] message = f"🗑🤖 {when.title()} is {', '.join(messages)}" if messages else "" response = {"date": date.date(), "when": when, "message": message} if message and "sms" in flask.request.args: client = twilio.rest.Client( username=os.getenv("TWILIO_ACCOUNT_SID"), password=os.getenv("TWILIO_AUTH_TOKEN"), ) sids = [] for recipient in os.getenv("SMS_RECIPIENTS").split(","): m = client.messages.create(to=recipient, from_=os.getenv("TWILIO_FROM_NUMBER"), body=message) sids.append(m.sid) response["status"] = "sms sent" response["sids"] = sids elif message: response["status"] = "testing" else: response["status"] = "no messages" return flask.jsonify(response)
def __init__( self ): self.calendar = ics.Calendar() # Not sure why this is necessary. If do everything # the way it says in the docs, we get an error # because calendar.events is initially a set. Thus the # append step doesn't work. This alleviates the problem. self.calendar.events = [ ]
def _process_calendar(calendar_file, start_date, end_date, allday, grouping_regex_strs): """Processes a calendar, grouping events by name. Args: calendar_file: the ics calendar file start_date: the starting date, or None end_date: the end date, or None allday: if true, includes all day events in processing grouping_regex_strs: regular expressions for grouping patterns """ print('Processing events from {0} to {1}'.format(start_date, end_date)) regexes = _parse_regexes(grouping_regex_strs) calendar = ics.Calendar(calendar_file) groups = defaultdict(lambda: 0) total_seconds = 0 for event in calendar.events: if not allday and event.all_day: continue if start_date and arrow.get(event.begin) < start_date: continue if end_date and arrow.get(event.end) > end_date: continue total_seconds += event.duration.total_seconds() event_name = _group(event.name, regexes) groups[event_name] += event.duration.total_seconds() for name, duration in sorted(groups.items(), key=lambda item: item[1], reverse=True): print('{0}: {1}'.format(name, _total_hours(duration)))
def list_events(): """ Function that outputs a list of events on the user's calendar. Calls the methods to calculate the time spend in each category. """ # Future Monday end = (get_previous_byday('Monday') + datetime.timedelta(days=7)) # Past Monday start = get_previous_byday('Monday') #start = arrow.get('2018-02-04T00:00:00Z') #end = arrow.get('2018-02-11T00:00:00Z') with open('cal.ics', 'rb') as f: c = ics.Calendar(f.read().decode('utf-8')) events = c.events[start:end] if not events: print('No upcoming events found.') for event in events: print(event.begin, event.name, event.duration) weekly_hours_time = event_sum_timedelta(event.name, event.duration) # Sum the total weekly number of hours weekly_hours = weekly_hours_time.total_seconds() / float(3600) weekly_hours_formated = strfdelta(weekly_hours_time, "%D days %H:%M:%S") data_to_csv(weekly_hours_formated, weekly_hours, start_event=str(start).split('T')[0])
def test_ical_generation(test_client): response = test_client.get('events.ics') assert response.status_code == 200 assert 'text/calendar' in response.headers['content-type'] assert ics.Calendar(response.get_data(as_text=True))
def course_calendar_ics(course_slug): try: course = g.model.courses[course_slug] except KeyError: abort(404) if not course.start_date: abort(404) events = [] for session in course.sessions.values(): time = getattr(session, 'time', None) if time is None: # Sessions without times don't show up in the calendar continue created = os.environ.get('NAUCSE_CALENDAR_DTSTAMP', None) cal_event = ics.Event( name=session.title, begin=time['start'], end=time['end'], uid=session.get_url(external=True), created=created, ) events.append(cal_event) cal = ics.Calendar(events=events) return Response(str(cal), mimetype="text/calendar")
def get_coming_events(ics_file, gap_before=3600): with open(ics_file, "r") as ics_file_: events = [ e for e in ics.Calendar(ics_file_).events if e.begin.timestamp >= time.time() - gap_before ] return events
def render_to_response(self, context, **response_kwargs): calendar = ics.Calendar(events=[ event.to_ics() for event in self.object.events.filter( visibility=Event.VISIBILITY_PUBLIC) ]) return HttpResponse(calendar, content_type="text/calendar")
def _process_calendar(calendar_file): """Processes a calendar, grouping events by name. Parameters: ----------- calendar_file: the ics calendar file start_date: the starting date, or None end_date: the end date, or None allday: if true, includes all day events in processing grouping_regex_strs: regular expressions for grouping patterns Returns: -------- DataFrame cal_df : Calender DataFrame grouped by event """ calendar = ics.Calendar(open(calendar_file).read()) cal_df = pd.DataFrame( columns=['day', 'month', 'year', 'hour', 'event_name', 'duration']) groups = defaultdict(lambda: 0) total_seconds = 0 i = 0 for event in calendar.events: start_date = arrow.get(event.begin) end_date = arrow.get(event.end) cal_df.loc[i] = [ start_date.datetime.day, start_date.datetime.month, start_date.datetime.year, start_date.datetime.hour, event.name, event.duration.total_seconds() ] i += 1 return cal_df
def get_unamur_events(): """ Get the events from the ADE of Unamur, from one week ago until the end of the academic year (12 september). :throws SynchronizationError: if the application fails to synchronize with ADE :return: The ical events from ADE of Unamur (Set[ics.Event]) """ now = datetime.date.today() begin = now - datetime.timedelta(weeks=1) end = datetime.date(year=now.year, month=9, day=12) if now >= end: end = datetime.date(year=end.year + 1, month=end.month, day=end.day) ade_first_date = begin.isoformat() ade_last_date = end.isoformat() url = get_unamur_ade_ical_url(ade_first_date, ade_last_date) try: response = requests.get(url) calendar = ics.Calendar(response.text) return calendar.events except (requests.ConnectionError, ics.parse.ParseError): raise SynchronizationError( 'Failed to fetch the events from the ADE of Unamur')
def parse(self, response): """ Convert the website reponse into Meeting objects The Bethel Park website allows you to download their calendar in the icalendar format. This function parses the icalendar file and converts each event into a Meeting. Arguments: response: The response from the website. We expect the body of this response to contain icalendar data Return: Yields a meeting object for each event in the calendar """ raw_calendar = response.body.decode("utf-8") ics_calendar = ics.Calendar(raw_calendar) for event in ics_calendar.events: meeting = Meeting( title=self.normalize(event.name), description=self.normalize(event.description), classification=NOT_CLASSIFIED, start=self._parse_start(event), end=self._parse_end(event), all_day=False, time_notes=None, location={ "address": self.normalize(event.location), "name": "" }, links=[], source=event.url, ) meeting["status"] = self._get_status(meeting) meeting["id"] = self._get_id(meeting) yield meeting
async def from_link(cls, link): '''create `Reminder` object from ical link''' async with aiohttp.ClientSession() as sess: async with sess.get(link) as resp: text = await resp.text() cal = ics.Calendar(text) return cls(cal)
def get_calendar(path, output_path=None, rounds=5): cal = ics.Calendar() output_path = os.path.splitext(path)[0] + '.ics' for event in _get_events(path): cal.events.add(event) _write_calendar(cal, output_path)
def ical(self) -> ics.Calendar: calendar = ics.Calendar(creator=self.creator, events=self.make_ical_events(self.events)) calendar.extra.append(ContentLine(name="X-WR-CALNAME", value=self.creator)) calendar.extra.append(ContentLine(name="X-WR-TIMEZONE", value=str(self.timezone))) calendar.extra.append(ContentLine(name="TZ", value="+00")) return calendar
async def calendar(self): try: async with aiohttp.ClientSession() as session: async with session.get(SUPER_F1_CALENDAR, timeout=5) as resp: self._calendar = ics.Calendar(await resp.text()) return self._calendar except: return self._calendar
def get_skip_calendars(path, rounds=5, skip=None): teams = get_teams(path) if skip: for teamid, v in teams.items(): if v['name'].lower() == skip.lower(): cals = {teamid: ics.Calendar()} else: cals = {teamid: ics.Calendar() for teamid in teams.keys()} for event in _get_events(path): for teamid, cal in cals.items(): if teams[teamid]['name'] in event.name: cal.events.add(event) for teamid, cal in cals.items(): output_path = f"{teams[teamid]['name']}.ics" _write_calendar(cal, output_path)
def parse_calendar(calendar_url): c = ics.Calendar(requests.get(calendar_url).text) processed_calendar = apply_filters(c, app.config['filters']) response = flask.make_response(str(processed_calendar)) response.headers[ "Content-Disposition"] = "attachment; filename=calendar.ics" response.headers["Content-Type"] = "text/calendar" return response
def as_ical(self): ical = ics.Calendar() for day in self.days: event = ics.Event(name=day.description, description=day.source, begin=day.date) event.make_all_day() ical.events.add(event) return ical
def _get_next_matches(self): now = datetime.now(UTC) events = ics.Calendar(requests.get(self.CALENDAR_URL).text).events events = sorted( [event for event in events if event.end.astimezone(UTC) >= now], key=lambda event: event.begin)[:self.NUM_EVENTS] matches = [] for event in events: # Example event title: "Dignitas vs. Tempo Storm" title_words = event.name.split(' ') team1, team2 = '', '' for i, word in enumerate(title_words): if word.lower() in ['vs', 'vs.', '-']: team1 = ' '.join(title_words[:i]) team2 = ' '.join(title_words[i + 1:]) break if not team1 and not team2: split_i = len(title_words) // 2 team1 = ' '.join(title_words[:split_i]) team2 = ' '.join(title_words[split_i:]) # Location should have a list of reddit-formatted URLs, like: # "[Stream](...) | [Bracket](...) | [Liquipedia](...)" re_matches = self.url_regex.finditer(event.location) stream_url = '' bracket_url = '' for re_match in re_matches: name, url = re_match.group(1), re_match.group(2) if not stream_url and 'stream' in name.lower(): stream_url = url if not bracket_url and not 'stream' in name.lower(): bracket_url = url if bracket_url: url = bracket_url elif stream_url: url = stream_url else: url = 'https://liquipedia.net/heroes/Main_Page' # The regex breaks on things like: # [Liquipedia](https://liquipedia.net/heroes/Nexus_Cup_\(French_Tournament\)) # This is a "fix" so it at least doesn't break reddit formatting. if url.endswith('\\'): url += ')' # Event description can be for example "Nexus Cup - semifinal". # The " - " would often be at line end on old reddit, so delete it. match = { 'starts_in': event.begin.astimezone(UTC) - now, 'team1': team1, 'team2': team2, 'tournament': event.description.replace(' - ', ' '), 'url': url } # Empty ~~~~ could break some reddit formatting. for key, value in match.items(): if not value: match[key] = '-' matches.append(match) return matches
def __init__(self, file_or_url, now=arrow.now()): self._url = None self._current_hour = None if file_or_url.startswith('https://'): self._last_fetch = None self._url = file_or_url self.RefreshCal() else: self._cal = ics.Calendar(open(file_or_url).read()) self.UpdateBoxes(now)
def apply_filters(calendar, filters): filtered_calendar = ics.Calendar() for event in calendar.events: filtered_event = filter_event(event, filters) if not filtered_event: continue filtered_calendar.events.add(filtered_event) return filtered_calendar
def get_events(self, date): """Get events on a date and return them as a list. date: Date object! Returns: list: {"datetime", "event"} """ if self.server is False: events = [] # The calendar is on the device # Check if it needs to be made... fs = FileSystemAccess(str(self.skill_id)) if fs.exists("calendar.ics"): # YAY! exists calendar = self.read_file("calendar.ics") c = ics.Calendar(imports=calendar) for event in c.timeline.on(day=arrow.get(date)): event_dict = { "datetime": event.begin.datetime, "event": event.name } events.append(event_dict) return events else: return [] elif self.server is True: url = "http://{}:{}@{}:{}/".format(self.user, self.password, self.server_address, self.port) try: client = caldav.DAVClient(url) principal = client.principal() # Select calendar events = [] for calendar in principal.calendars(): for event in calendar.events(): event_text = event.data cal = vobject.readOne(event_text) event_date = cal.vevent.dtstart.value.date() # If in date, append. if event_date == date: event_dict = { "datetime": cal.vevent.dtstart.value, "event": cal.vevent.summary.valueRepr() } events.append(event_dict) return events except: self.speak_dialog("error.logging.in") return None else: raise ("Wrong input")
def generate(ical, only_future=False): table = {} timeline = ics.Calendar(ical).timeline if only_future: timeline = timeline.start_after(arrow.now()) for event in sorted(timeline): name = event.name table[name] = table.get(name, []) table[name].append(arrow.get(event.begin)) return table