def generate_ics_calendar(self, filename=''): logger.debug(f"Refreshed ICS for {self.username}") @MemoizeWithTimeout() def format_ics_date(event_date): return get_ade_timezone().localize( datetime.strptime(event_date, '%d/%m/%Y %H:%M')) def format_ics_location(classroom): return f'{classroom["name"]} ({", ".join(classroom["genealogy"])})' def format_geolocation(classrooms): try: # Returns the first geolocation found return next(filter( None, (c.get('geolocation') for c in classrooms)))[:2] except Exception: return None @MemoizeWithTimeout() def format_end_date(dt, offset): return dt + timedelta( minutes=(int(offset) * settings.ADE_DEFAULT_DURATION)) def format_description(resources): descriptions = [] # TODO: i18n ? for key, display in {'trainees': 'Filières', 'instructors': 'Intervenants', 'category5s': 'Matières'}.items(): if key in resources: descriptions.append( f'{display} : ' + ','.join([x['name'] for x in resources[key]])) return '\n'.join(descriptions) filename = filename or self.ics_calendar_filename calendar = Calendar() if self.events_nb > settings.ADE_MAX_EVENTS: logger.warning(f'Too much events for {self.username} : {self.events_nb}') e = Event() e.name = "Votre calendrier dépasse le nombre d'événements autorisé" e.begin = format_ics_date('01/01/2000 00:00') e.end = format_ics_date('01/01/2100 00:00') calendar.events.add(e) else: merged_events = self.events events = merged_events.get('events', []) # merged_events = {r: merged_events.get(r, {}) for r in res_list} if events: filename = filename or self.ics_calendar_filename res_list = ('trainees', 'instructors', 'classrooms', 'category5s') for event in events: # Keeps adding 5000 events under 1 sec resources = {} for r in res_list: res = [merged_events[r][e] for e in event.get(r, [])] if res: resources[r] = res classrooms = resources.get('classrooms', ()) begin_time = format_ics_date( f'{event["date"]} {event["startHour"]}') # Genereate ICS event e = Event() e.name = event['name'] e.begin = begin_time e.end = format_end_date(begin_time, event['duration']) e.geo = format_geolocation(classrooms) e.location = ';'.join(map(format_ics_location, classrooms)) # e.last_modified = event['lastUpdate'] e.description = format_description(resources) calendar.events.add(e) if self.events_nb > 0: with default_storage.open(filename, 'w') as fh: return fh.write(str(calendar))
for s in sessions: name, fp1, fp2, fp3, q, r = s.split(',') schedule[name] = [fp1, fp2, fp3, q, r] for race in races: event = Event() today = datetime.datetime.now() gp, circuit, coords, name = race.split(',') if gp != 'JAPAN': dates = get_dates(gp) event.name = f'{name} Grand Prix' event.begin = dates['R'] # event.end = '' event.location = circuit event.geo = [float(i) for i in coords.split()] event.transparent = False event.created = today event.last_modified = today event.extra.extend([ContentLine(name='SEQUENCE', value='0')]) else: event.name = f'{name} Grand Prix' event.begin = '2020-10-11 00:00:00' # event.end = '' event.location = circuit event.geo = [float(i) for i in coords.split()] event.transparent = False event.created = today event.last_modified = today event.extra.extend([ContentLine(name='SEQUENCE', value='0')])