def create_timezone(tz): # Function from https://github.com/pimutils/khal/blob/64d70e3eb59570cfd3af2e10dbbcf0a26bf89111/khal/khalendar/event.py#L287 first_date = datetime.today() last_date = datetime.today() timezone = Timezone() timezone.add('TZID', tz) dst = {one[2]: 'DST' in two.__repr__() for one, two in tz._tzinfos.items()} first_num, last_num = 0, len(tz._utc_transition_times) - 1 first_tt = tz._utc_transition_times[0] last_tt = tz._utc_transition_times[-1] for num, dt in enumerate(tz._utc_transition_times): if dt > first_tt and dt < first_date: first_num = num first_tt = dt if dt < last_tt and dt > last_date: last_num = num last_tt = dt for num in range(first_num, last_num + 1): name = tz._transition_info[num][2] if dst[name]: subcomp = TimezoneDaylight() rrule = {'freq': 'yearly', 'bymonth': 3, 'byday': '2su'} else: subcomp = TimezoneStandard() rrule = {'freq': 'yearly', 'bymonth': 11, 'byday': '1su'} subcomp.add('TZNAME', tz._transition_info[num][2]) subcomp.add( 'DTSTART', tz.fromutc(tz._utc_transition_times[num]).replace(tzinfo=None)) subcomp.add('TZOFFSETTO', tz._transition_info[num][0]) subcomp.add('TZOFFSETFROM', tz._transition_info[num - 1][0]) subcomp.add('RRULE', rrule) timezone.add_component(subcomp) return timezone
def add_vtimezone(cal): tzc = Timezone() tzc.add('tzid', 'Europe/Copenhagen') tzc.add('x-lic-location', 'Europe/Copenhagen') tzs = TimezoneStandard() tzs.add('tzname', 'CET') tzs.add('dtstart', datetime.datetime(1970, 10, 25, 3, 0, 0)) tzs.add('rrule', {'freq': 'yearly', 'bymonth': 10, 'byday': '-1su'}) tzs.add('TZOFFSETFROM', datetime.timedelta(hours=2)) tzs.add('TZOFFSETTO', datetime.timedelta(hours=1)) tzd = TimezoneDaylight() tzd.add('tzname', 'CEST') tzd.add('dtstart', datetime.datetime(1970, 3, 29, 2, 0, 0)) tzs.add('rrule', {'freq': 'yearly', 'bymonth': 3, 'byday': '-1su'}) tzd.add('TZOFFSETFROM', datetime.timedelta(hours=1)) tzd.add('TZOFFSETTO', datetime.timedelta(hours=2)) tzc.add_component(tzs) tzc.add_component(tzd) cal.add_component(tzc)
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)
f = open('TV Operations Schedule Calendar.ics', 'r') print(f) fcal = Calendar.from_ical(f.read()) gcal = Calendar() #begin setting up preamble stuff gcal.add('prodid', '-//My calendar product//mxm.dk//') gcal.add('version', '2.0') gcal.add('calscale', 'GREGORIAN') gcal.add('method', 'PUBLISH') gcal.add('X-WR-CALNAME', 'LyleDistanceF16') gcal.add('X-WR-TIMEZONE', 'America/Chicago') tz = Timezone() #might need to accomodate for DSaveTime dlt = TimezoneDaylight() dlt.add('TZOFFSETFROM', timedelta(hours=-6)) dlt.add('RRULE', {'FREQ': 'YEARLY', 'BYMONTH': '3', 'BYDAY': '2SU'}) #very weird, python 3.5 requires 0o03 instead of 03 dlt['DTSTART'] = datetime(2007, 0o03, 11, 2, 0, 0) dlt.add('TZNAME', 'CDT') dlt.add('TZOFFSETTO', timedelta(hours=-5)) stnd = TimezoneStandard() stnd.add('TZOFFSETFROM', timedelta(hours=-5)) stnd.add('RRULE', {'FREQ': 'YEARLY', 'BYMONTH': '11', 'BYDAY': '1SU'}) stnd['DTSTART'] = datetime(2007, 11, 4, 2, 0, 0) stnd.add('TZNAME', 'CST') stnd.add('TZOFFSETTO', timedelta(hours=-6)) tz.add('TZID', 'America/Chicago') tz.add_component(dlt) tz.add_component(stnd)
def main(infiles=None, locfile=None, **kwargs): locations = {} metadata_file = locfile.read() match = PATTERN2.finditer(metadata_file) for entry in match: locations[entry.group(1)] = demjson.decode(entry.group(2)) tracks = {} match = PATTERN3.finditer(metadata_file) for entry in match: tracks[entry.group(1)] = demjson.decode(entry.group(2)).get('name') events = [] for infile in infiles: data = json.load(infile) if data is None: continue events.extend(data['events']) for track_id, track_name in tracks.items(): cal = Calendar() cal['dtstart'] = '20180519T080000' cal['summary'] = 'OpenStack Summit Vancouver 2018: ' + track_name tz = Timezone(TZID='America/Vancouver') tz.add_component( TimezoneStandard(DTSTART="20171105T020000", TZOFFSETFROM="-0700", TZOFFSETTO="-0800", RDATE="20181104T020000", TZNAME="PST")) tz.add_component( TimezoneDaylight(DTSTART="20180311T020000", TZOFFSETFROM="-0800", TZOFFSETTO="-0700", TZNAME="PDT")) cal.add_component(tz) for session in events: if track_id != str(session.get('track_id')): continue timezone_str = session.get('time_zone_id') tzinfos = {"UN": gettz(timezone_str)} start_datetime_str = session.get('start_datetime') start_datetime = parse(start_datetime_str + " UN", tzinfos=tzinfos) start_datetime_utc = start_datetime.astimezone(utc) end_datetime_str = session.get('end_datetime') end_datetime = parse(end_datetime_str + " UN", tzinfos=tzinfos) end_datetime_utc = end_datetime.astimezone(utc) desc = PATTERN.sub('', session.get('abstract')) for pre, post in REPLACE_MAP.items(): desc = desc.replace(pre, post) event = Event() event.add('dtstart', start_datetime_utc) event.add('dtend', end_datetime_utc) event.add('summary', session.get('title')) event.add( 'location', locations.get(str(session.get('location_id')), {}).get('name_nice', "")) event.add('description', desc) event.add('uid', "%s@openstacksummitboston2017" % session.get('id')) cal.add_component(event) with open("%s.ics" % PATTERN4.sub("-", track_name), "w") as f: f.write(cal.to_ical())
def make_calendar(parsed, pourProf=False, querry_name=None): """ création du calendrier a partir du parseur """ # Création de l'agenda cal = Calendar() # Etablissement du nom du Timezone calname = querry_name or u"ENSEA" caldesc = u""" Parseur de calendrier de %s a partir de webteam.ensea.fr realise par Webtim. \n AUCUNE GARANTIE DE LA FIABILITE DES INFORMATIONS N'EST DONNEE.\n Vous pouvez envoyer des suggestions, rapport de bug, insultes ou remerciments à <webteam at ensea.fr>\n """ % (calname) cal.add('x-wr-calname', calname) cal.add('x-wr-caldesc', caldesc) cal.add('x-wr-relcalid', u"12345") cal.add('x-wr-timezone', u"Europe/Paris") tzc = Timezone() tzc.add('tzid', 'Europe/Paris') tzc.add('x-lic-location', 'Europe/Paris') tzs = TimezoneStandard() tzs.add('tzname', 'CET') tzs.add('dtstart', datetime(1970, 10, 25, 3, 0, 0)) tzs.add('rrule', {'freq': 'yearly', 'bymonth': 10, 'byday': '-1su'}) tzs.add('TZOFFSETFROM', timedelta(hours=2)) tzs.add('TZOFFSETTO', timedelta(hours=1)) tzd = TimezoneDaylight() tzd.add('tzname', 'CEST') tzd.add('dtstart', datetime(1970, 3, 29, 2, 0, 0)) tzs.add('rrule', {'freq': 'yearly', 'bymonth': 3, 'byday': '-1su'}) tzd.add('TZOFFSETFROM', timedelta(hours=1)) tzd.add('TZOFFSETTO', timedelta(hours=2)) tzc.add_component(tzs) tzc.add_component(tzd) cal.add_component(tzc) for i in parsed: event = Event() if len(i) < 7: continue start = datetime.strptime("%s %s" % (i[0], i[1]), "%d/%m/%Y %H:%M") # Correction des horaires pour correspondre à l'ENSEA if start.hour == 10 and start.minute == 0: start = start + timedelta(minutes=10) elif start.hour == 13 and start.minute == 0: start = start + timedelta(minutes=15) elif start.hour == 15 and start.minute == 0: start = start + timedelta(minutes=25) if re.match("^\d{1,2}h$", i[2]): delta = datetime.strptime(i[2], "%Hh") elif re.match("^\d{1,2}min$", i[2]): # /30min/ delta = datetime.strptime(i[2], "%Mmin") else: delta = datetime.strptime(i[2], "%Hh%Mmin") if delta.hour == 2: # prise en compte des pauses pour les séquences de deux heures delta = delta - timedelta(minutes=10) end = start + timedelta(hours=delta.hour, minutes=delta.minute) groups = unicodedata.normalize('NFKD', i[5]).encode('ascii', 'ignore').replace(" ", '') prof = unicodedata.normalize('NFKD', i[6]).encode('ascii', 'ignore') # On inverse nom et prénom pour avoir {prenom nom} prof_lst = prof.split(" ") if len(prof_lst) < 3: prof = prof_lst[-1] + " " + " ".join(prof_lst[0:-1]) # Si le nom est trop long (comme pour les cours de langues), on le coupe et ajoute [...] if len(prof) > 40: prof = prof[:40] + '[...]' room = i[7][:5] name = unicodedata.normalize('NFKD', i[4]).encode('ascii', 'ignore') name = re.sub(u'ŕ', u"a", name) typeevent = re.sub(u'ŕ', u"à", i[3]) # typeevent = unicodedata.normalize('NFKD', i[3]).encode('Utf-8','ignore') if typeevent == "TP" and name.lower().find("projet") >= 0: typeevent = "" start_ical = dateICal(start) end_ical = dateICal(end) if pourProf: if len(typeevent) > 0: summary = "%s de %s avec %s en %s" % (typeevent, name, groups, room) else: summary = "%s avec %s en %s" % (name, groups, room) else: if len(typeevent) > 0: if len(typeevent) > 6: summary = "%s avec %s en %s" % (typeevent, prof, room) else: summary = "%s de %s avec %s en %s" % (typeevent, name, prof, room) else: summary = "%s avec %s en %s" % (name, prof, room) uid = "%s-%s@%s" % (dateICal(start), dateICal(end), room) # event_condensed_name[:10]) # Pour ajouter le timezone proprement à chaque heure d'événements (optionel) hour_start = [int(h) for h in str(start).split(" ")[1].split(':')] hour_end = [int(h) for h in str(end).split(" ")[1].split(':')] date_start = [int(d) for d in str(start).split(" ")[0].split('-')] date_end = [int(d) for d in str(end).split(" ")[0].split('-')] # Le fichier de sortie ne doit pas dépasser 75 caractères par ligne event = Event() event.add('summary', summary) event.add('location', room + ", ENSEA, Cergy") event.add('status', "confirmed") event.add('category', 'Event') event.add('dtstart', datetime(date_start[0], date_start[1], date_start[2], hour_start[0], hour_start[1], hour_start[2], tzinfo=pytz.timezone("Europe/Paris"))) event.add('dtend', datetime(date_end[0], date_end[1], date_end[2], hour_end[0], hour_end[1], hour_end[2], tzinfo=pytz.timezone("Europe/Paris"))) event["uid"] = uid event.add('priority', 0) cal.add_component(event) return cal
def main(): args = docopt(doc=__doc__, version=__version__) log = Quicklog( application_name="celcat_to_ics", enable_colored_logging=False, enable_colored_printing=True, log_filename=args["--log"], print_level=logging.DEBUG if args["-v"] else logging.INFO, logging_level=logging.DEBUG, version=__version__, ) input_files = [stdin ] if args["-"] else [open(i, "r") for i in args["INPUT"]] output_file = stdout if args["-o"] is None else open(args["-o"], "w") # :filter has the form "TPA31,TPA32:Info,Logique+TPA11:Info" # It becomes filter[+ separated items (OR)][0=groups,1=courses)][, separated items (OR)] # <=> ((TPA31 or TPA32) and (Info or Logique)) or (TPA11 and Info) # filter = args["-r"].split("+").split(",") if args["-r"] is not None else None filter_string = ([] if args["-r"] is None else [[x.split(",") for x in e.split(":")] for e in args["-r"].split("+")]) log.begin(show=False) log.debug("Positional parameters:\n" + str(args) + "\n") l = [ " course is {(" + ") or (".join([j for j in i[0]]) + ")}" + "\n and group is {(" + ") or (".join([j for j in i[1]]) + ")}" for i in filter_string ] log.debug("Filters:\n" + "\nOR\n".join(l)) cal = Calendar() cal["VERSION"] = 2.0 cal["PRODID"] = "Some proid" cal["CALSCALE"] = "GREGORIAN" cal["METHOD"] = "PUBLISH" cal["X-WR-CALNAME"] = "Calendar" cal["X-WR-TIMEZONE"] = "Europe/Paris" tz = Timezone() tz["TZID"] = "Europe/Paris" tz["X-LIC-LOCATION"] = "Europe/Paris" tz_day = TimezoneDaylight() tz_day["DTSTART"] = "19810329T020000" tz_day["TZOFFSETFROM"] = "+0100" tz_day["TZOFFSETTO"] = "+0200" tz_day["TZNAME"] = "CEST" tz_day["RRULE"] = "FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU" tz_std = TimezoneStandard() tz_std["DTSTART"] = "19961027T030000" tz_std["TZOFFSETFROM"] = "+0200" tz_std["TZOFFSETTO"] = "+0100" tz_std["TZNAME"] = "CET" tz_std["RRULE"] = "FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU" tz.add_component(tz_day) tz.add_component(tz_std) cal.add_component(tz) for i in input_files: events, calname = parse_celcat(i, filter_string) for e in events: cal.add_component(e) output_file.write(cal.to_ical().decode("utf-8").replace( "\\r\\n", "\n").replace("\;", ";").strip()) log.end()