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 ical_init(): cal = Calendar() cal.add('prodid', '-//CSPay calendar//EN/') cal.add('version', '2.0') TZ = Timezone() TZ.add('tzid','Europe/Bucharest') TZS = StandardT() TZS.add('TZOFFSETFROM',timedelta(hours=3)) TZS.add('TZOFFSETTO',timedelta(hours=2)) TZS.add('TZNAME','EET') TZS.add('DTSTART',datetime(1997,10,26)) TZS.add('rrule',vRecur.from_ical('FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU')) TZ.add_component(TZS) TZS = DaylightT() TZS.add('TZOFFSETFROM',timedelta(hours=2)) TZS.add('TZOFFSETTO',timedelta(hours=3)) TZS.add('TZNAME','EEST') TZS.add('DTSTART',datetime(1997,03,30)) TZS.add('rrule',vRecur.from_ical('FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU')) TZ.add_component(TZS) cal.add_component(TZ) return cal
def _create_timezone(): tz = Timezone() tz.add("TZID", "Asia/Shanghai") tz_standard = TimezoneStandard() tz_standard.add("DTSTART", datetime.datetime(1970, 1, 1)) tz_standard.add("TZOFFSETFROM", datetime.timedelta(hours=8)) tz_standard.add("TZOFFSETTO", datetime.timedelta(hours=8)) tz.add_component(tz_standard) return tz
def create_ical_object(): cal = Calendar() cal['prodid'] = '-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN' cal['version'] = '2.0' cal['method'] = 'REQUEST' tz = Timezone() tz['tzid'] = 'America/Los_Angeles' tz['x-lic-location'] = 'America/Los_Angeles' daylight = TimezoneDaylight() daylight['tzoffsetfrom'] = '-0800' daylight['tzoffsetto'] = '-0700' daylight['tzname'] = 'PDT' daylight['dtstart'] = '19700308T020000' daylight.add('rrule', '', parameters={'freq': '3DYEARLY', 'byday': '3D2SU', 'bymonth': '3D3'}) tz.add_component(daylight) std = TimezoneStandard() std['tzoffsetfrom'] = '-0700' std['tzoffsetto'] = '-0800' std['tzname'] = 'PST' std['dtstart'] = '19701101T020000' std.add('rrule', '', parameters={'freq': '3DYEARLY', 'byday': '3D1SU', 'bymonth': '3D11'}) tz.add_component(std) cal.add_component(tz) event = Event() event['created'] = '20150623T162711Z' event['last-modified'] = '20150623T162740Z' event['dtstamp'] = '20150623T162740Z' event['uid'] = '51ae3508-fe9e-4519-9756-6b4cc4fcae05' event['summary'] = 'Nylas Developer Night' event.add('organizer', 'mailto:[email protected]', parameters={'rsvp': '3DTRUE', 'partstat': '3DNEEDS-ACTION', 'role': 'RDREQ-PARTICIPANT'}) event.add('attendee', 'mailto:[email protected]', parameters={'rsvp': '3DTRUE', 'partstat': '3DNEEDS-ACTION', 'role': '3DREQ-PARTICIPANT'}) event['transp'] = 'OPAQUE' event['dtstart'] = '20150624T190000' event['dtend'] = '20150624T210000' cal.add_component(event) return cal
def make_icalendar_data(uid, summary, current, end, begin, account_id, create_flag=False): """ Generate iCalendar data format message body. reference - https://developers.worksmobile.com/jp/document/1007011?lang=en """ cal = Calendar() cal.add('PRODID', 'Works sample bot Calendar') cal.add('VERSION', '2.0') standard = TimezoneStandard() standard.add('DTSTART', datetime(1970, 1, 1, 0, 0, 0, tzinfo=pytz.timezone(TZone))) standard.add('TZOFFSETFROM', current.utcoffset()) standard.add('TZOFFSETTO', current.utcoffset()) standard.add('TZNAME', current.tzname()) tz = Timezone() tz.add_component(standard) tz.add('TZID', tz) event = Event() event.add('UID', uid) if create_flag: event.add('CREATED', current) event.add('DESCRIPTION', account_id) event.add('SUMMARY', summary) event.add('DTSTART', begin) event.add('DTEND', end) event.add('LAST-MODIFIED', current) event.add('DTSTAMP', current) cal.add_component(event) cal.add_component(tz) schedule_local_string = bytes.decode(cal.to_ical()) LOGGER.info("schedule:%s", schedule_local_string) return schedule_local_string
def gen_calendar(class_dict: dict, schedule_list: list) -> Calendar: calendar = Calendar() calendar['version'] = '2.0' calendar['prodid'] = '-//HFUT//xCalendar//CN' cst_timezone = Timezone() cst_timezone['tzid'] = 'Asia/Shanghai' cst_std = TimezoneStandard() cst_std['DTSTART'] = '16010101T000000' cst_std.add('TZOFFSETFROM', datetime.timedelta(hours=8)) cst_std.add('TZOFFSETTO', datetime.timedelta(hours=8)) cst_timezone.add_component(cst_std) calendar.add_component(cst_timezone) merged_schedule_list: List[dict] = [] for lesson in schedule_list: if (not merged_schedule_list) or (not ( lesson["lessonId"] == merged_schedule_list[-1]["lessonId"] and lesson["date"] == merged_schedule_list[-1]["date"] and lesson['startTime'] == merged_schedule_list[-1]["startTime"])): merged_schedule_list.append(lesson) else: merged_schedule_list[-1].update( personName=merged_schedule_list[-1]["personName"] + ' ' + lesson["personName"]) for lesson in merged_schedule_list: event = Event() event.add("summary", class_dict[lesson["lessonId"]]) event.add("description", lesson["personName"]) event.add("location", (lesson["room"] is None) and " " or lesson["room"]["nameZh"]) schedule_time_of_start = '{0} {1}:{2}:00'.format( lesson["date"], lesson['startTime'] // 100, lesson['startTime'] % 100) schedule_time_of_end = '{0} {1}:{2}:00'.format( lesson["date"], lesson['endTime'] // 100, lesson['endTime'] % 100) cst_tz = pytz.timezone('Asia/Shanghai') dtstart = datetime.datetime.strptime( schedule_time_of_start, "%Y-%m-%d %H:%M:%S").replace(tzinfo=cst_tz) dtend = datetime.datetime.strptime( schedule_time_of_end, "%Y-%m-%d %H:%M:%S").replace(tzinfo=cst_tz) event.add('dtstart', dtstart) event.add('dtend', dtend) event.add('uid', str(uuid1()) + '@HFUT') event.add("dtstamp", datetime.datetime.now()) calendar.add_component(event) return calendar
def __init__(self, name=u'Jリーグ'): cal = Calendar() cal['method'] = 'PUBLISH' cal['prodid'] = '-//J-League Calendar//S.Kitazaki//' cal['version'] = '2.0' cal.set('X-WR-CALNAME', name) cal['X-WR-TIMEZONE'] = 'Asia/Tokyo' tz = Timezone() tz['TZID'] = 'Asia/Tokyo' tz['X-LIC-LOCATION'] = 'Asia/Tokyo' c = Component() c.name = 'STANDARD' c['TZOFFSETFROM'] = '+0900' c['TZOFFSETTO'] = '+0900' c['TZNAME'] = 'JST' c['DTSTART'] = '19700101T000000' tz.add_component(c) cal.add_component(tz) self.cal = cal
def create_timezone(): central = Timezone() central.add("tzid", CLASS_TIMEZONE) central.add("x-lic-location", CLASS_TIMEZONE) tzs = TimezoneStandard() tzs.add("tzname", "CST") tzs.add("dtstart", datetime(1970, 10, 25, 3, 0, 0)) tzs.add("rrule", {"freq": "yearly", "bymonth": 10, "byday": "-1su"}) tzs.add("TZOFFSETFROM", timedelta(hours=-5)) tzs.add("TZOFFSETTO", timedelta(hours=-6)) tzd = TimezoneDaylight() tzd.add("tzname", "CDT") tzd.add("dtstart", datetime(1970, 3, 29, 2, 0, 0)) tzd.add("rrule", {"freq": "yearly", "bymonth": 3, "byday": "-1su"}) tzd.add("TZOFFSETFROM", timedelta(hours=-6)) tzd.add("TZOFFSETTO", timedelta(hours=-5)) central.add_component(tzs) central.add_component(tzd) return central
def make_icalendar_data(uid, summary, current, end, begin, account_id, create_flag=False): cal = Calendar() cal.add('PRODID', 'Works sample bot Calendar') cal.add('VERSION', '2.0') tz = load_time_zone() standard = TimezoneStandard() standard.add('DTSTART', datetime(1970, 1, 1, 0, 0, 0, tzinfo=pytz.timezone(tz))) standard.add('TZOFFSETFROM', current.utcoffset()) standard.add('TZOFFSETTO', current.utcoffset()) standard.add('TZNAME', current.tzname()) tz = Timezone() tz.add_component(standard) tz.add('TZID', tz) event = Event() event.add('UID', uid) if create_flag: event.add('CREATED', current) event.add('DESCRIPTION', account_id) event.add('ATTENDEE', account_id) event.add('SUMMARY', summary) event.add('DTSTART', begin) event.add('DTEND', end) event.add('LAST-MODIFIED', current) event.add('DTSTAMP', current) cal.add_component(event) cal.add_component(tz) schedule_local_string = bytes.decode(cal.to_ical()) LOGGER.info("schedule:%s", schedule_local_string) return schedule_local_string
def ical_creat(filename): courselist = JsonLoadHandle(filename) cal = Calendar() cal.add('prodid', '-//My CourseTable//') cal.add('version', '2.0') cal.add('CALSCALE', 'GREGORIAN') cal.add('method', 'PUBLISH') tz = Timezone() tzst = TimezoneStandard() tzst.add('tzoffsetfrom', timedelta(hours=8)) tzst.add('tzoffsetto', timedelta(hours=8)) tzst.add('tzname', 'CST') tzst.add('dtstart', datetime(1970, 1, 1, 0, 0, 0)) tz.add('tzid', 'Asia/Shanghai') tz.add_component(tzst) cal.add_component(tz) for course in courselist: cal.add_component(course.getEvent()) f = open(os.path.abspath('cache/ics/' + filename + '.ics'), 'wb') f.write(cal.to_ical()) f.close()
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 writeIcs(): cal = Calendar() cal.add('PRODID', '-//Dayfacto Journal//dpd//') cal.add('VERSION', '1.0') cal.add('VERSION', 'GREGORIAN') timezone = Timezone() timezone.add('TZID', 'Europe/London') daylight = TimezoneDaylight() daylight.add('TZOFFSETFROM', datetime.timedelta(hours=0)) daylight.add('TZOFFSETTO', datetime.timedelta(hours=1)) daylight.add('TZNAME', 'BST') timezone.add_component(daylight) standard = TimezoneStandard() standard.add('TZNAME', 'GMT') standard.add('TZOFFSETFROM', datetime.timedelta(hours=1)) standard.add('TZOFFSETTO', datetime.timedelta(hours=0)) timezone.add_component(standard) cal.add_component(timezone) evtList = fetchAllEvents() count = 0 for evt in evtList: event = Event() event.add('SUMMARY', evt[0]) event.add('DTSTART', evt[2]) if evt[5] > 1: event.add('RRULE', {'freq': numPeriod[evt[4]], 'interval': evt[6], 'count': evt[5]}) event['uid'] = str(datetime.datetime.today().time()) + str(evt[8]) \ + '*****@*****.**' # event.add('DESCRIPTION', 'This is another description') # event.add('VJOURNAL', 'This is another journal entry') cal.add_component(event) # print(numPeriod[evt[4]]) count += 1 print(count) f = open('example.ics', 'wb') f.write(cal.to_ical()) f.close()
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 generate(student_id: str, student_name: str, student_classes, semester_string: str, semester): """ 生成 ics 文件并保存到目录 :param student_id: 学号 :param student_name: 姓名 :param student_classes: classes student are taking :param semester_string: 学期字符串,显示在日历标题中,如 `17-18-1` :param semester: 当前导出的学期,三元组 :return: True """ # 创建 calender 对象 cal = Calendar() cal.add('prodid', '-//Admirable//EveryClass//EN') cal.add('version', '2.0') cal.add('calscale', 'GREGORIAN') cal.add('method', 'PUBLISH') cal.add('X-WR-CALNAME', student_name + '的' + semester_string + '学期课表') cal.add('X-WR-TIMEZONE', 'Asia/Shanghai') # 时区 tzc = Timezone() tzc.add('tzid', 'Asia/Shanghai') tzc.add('x-lic-location', 'Asia/Shanghai') tzs = TimezoneStandard() tzs.add('tzname', 'CST') tzs.add('dtstart', datetime(1970, 1, 1, 0, 0, 0)) tzs.add('TZOFFSETFROM', timedelta(hours=8)) tzs.add('TZOFFSETTO', timedelta(hours=8)) tzc.add_component(tzs) cal.add_component(tzc) # 创建 events for time in range(1, 7): for day in range(1, 8): if (day, time) in student_classes: for every_class in student_classes[(day, time)]: # 每一节课 durations = re.split(r',', every_class['duration']) for each_duration in durations: # 空区间 bug fix if not each_duration: continue # 每一段上课周 if len(re.findall(r'\d{1,2}', each_duration)) == 1: # 仅当周 dur_starting_week = dur_ending_week = re.findall( r'\d{1,2}', each_duration)[0] else: # X 到 X 周 dur_starting_week, dur_ending_week = re.findall( r'\d{1,2}', each_duration) if every_class['week'] == '周': interval = 1 else: interval = 2 if every_class['week'] == '双周' and int( dur_starting_week) % 2 != 0: dur_starting_week = str(int(dur_starting_week) + 1) if every_class['week'] == '单周' and int( dur_starting_week) % 2 == 0: dur_starting_week = str(int(dur_starting_week) + 1) dtstart = __get_datetime(dur_starting_week, day, get_time(time)[0], semester) dtend = __get_datetime(dur_starting_week, day, get_time(time)[1], semester) until = __get_datetime(dur_ending_week, day, get_time(time)[1], semester) + timedelta(days=1) # 参数:课程名称、初次时间[start、end、interval、until、duration]、循环规则、地点、老师、学生 ID cal.add_component( __add_event(name=every_class['name'], times=[ dtstart, dtend, interval, until, each_duration, every_class['week'] ], location=every_class['location'], teacher=every_class['teacher'], student_id=student_id, day=day, time=time)) # 写入文件 import os with open( os.path.join( os.path.dirname(__file__), '../../../calendar_files/%s-%s.ics' % (student_id, semester_string)), 'w') as f: f.write(cal.to_ical().decode(encoding='utf-8')) return True
#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) gcal.add_component(tz) #end setting up preamble stuff room = { ##'J205':' ##'J203' ##'J113' ##'J101' 'C161': 'CH157encoder161', 'C184': 'CH157encoder184', 'C179': 'CH157encoder179', 'C183': 'CH157encoder183' } #checks all scheduled events
schedule_url = f'http://www.1spbgmu.ru/ruz/?timetable&group={group_id}' html_source = requests.get(schedule_url).text schedule = html.fromstring(html_source) cal = Calendar() # timezone info tz = Timezone() tz.add('TZID', '(UTC+03:00) Moscow, St. Petersburg, Volgograd') tz_st = TimezoneStandard() tz_st.add('DTSTART', datetime(1601, 1, 1)) tz_st.add('TZOFFSETFROM', timedelta(hours=4)) tz_st.add('TZOFFSETTO', timedelta(hours=3)) tz.add_component(tz_st) cal.add_component(tz) h4 = schedule.xpath("//h4") group_name = h4[0].text if h4 else group_id p_status = schedule.xpath("//p[contains(@class, 'status')]") status = p_status[0].text if p_status else 'unknown status' for day_info in schedule.xpath("//div[contains(@class, 'list')]"): day_of_week_node = day_info.xpath("*[contains(@class, 'dayofweek')]") try: event_date = datetime.strptime( day_of_week_node[0].text.split(',')[1].strip(), '%d.%m.%Y').date() except (IndexError, ValueError): logging.warning(f'Incorrect day of week info: {day_of_week_node}') continue
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()
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(osm, auth, sections, outdir): assert os.path.exists(outdir) and os.path.isdir(outdir) for section in sections: assert section in list(Group.SECTIONIDS.keys()) + ['Group'], \ "section must be in {!r}.".format(Group.SECTIONIDS.keys()) osm_sections = osm.OSM(auth, Group.SECTIONIDS.values()) tzc = Timezone() tzc.add('tzid', 'Europe/London') tzc.add('x-lic-location', 'Europe/London') tzs = TimezoneStandard() tzs.add('tzname', 'GMT') tzs.add('dtstart', datetime.datetime(1970, 10, 25, 2, 0, 0)) tzs.add('rrule', {'freq': 'yearly', 'bymonth': 10, 'byday': '-1su', 'interval': '1'}) tzd = TimezoneDaylight() tzd.add('tzname', 'BST') tzd.add('dtstart', datetime.datetime(1970, 3, 29, 1, 0, 0)) tzd.add('rrule', {'freq': 'yearly', 'bymonth': 3, 'byday': '-1su', 'interval': '1'}) tzd.add('TZOFFSETFROM', datetime.timedelta(hours=0)) tzd.add('TZOFFSETTO', datetime.timedelta(hours=1)) for section in sections: i = Calendar() tzc.add_component(tzs) tzc.add_component(tzd) i.add_component(tzc) if section == "Group": i['x-wr-calname'] = '7th Lichfield: Group Calendar' i['X-WR-CALDESC'] = 'Current Programme' i['calscale'] = 'GREGORIAN' i['X-WR-TIMEZONE'] = 'Europe/London' for s in Group.SECTIONIDS.keys(): section_obj = osm_sections.sections[Group.SECTIONIDS[s]] [meeting2ical(s, event, i) for event in section_obj.programme.events_by_date()] [event2ical(s, event, i) for event in section_obj.events] open(os.path.join(outdir, section + ".ical"), 'w').write(i.to_ical().decode()) else: section_obj = osm_sections.sections[Group.SECTIONIDS[section]] i['x-wr-calname'] = '7th Lichfield: {}'.format(section) i['X-WR-CALDESC'] = '{} Programme'.format(section_obj.term['name']) i['calscale'] = 'GREGORIAN' i['X-WR-TIMEZONE'] = 'Europe/London' [meeting2ical(section, event, i) for event in section_obj.programme.events_by_date()] [event2ical(section, event, i) for event in section_obj.events] open(os.path.join(outdir, section + ".ical"), 'w').write(i.to_ical().decode())