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 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 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 __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 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 import_calendars(user_dir, username, zadmin, zadmin_password): IGNORE_DUPLICATE = True url = "https://127.0.0.1:8443/ical/"+username merged_ical = os.path.join(user_dir, 'merged.ics') now = datetime.datetime.now() icals = get_files([user_dir], ['.ics']) # do nothing if no ics files found if not icals: return # this set will be used fo find duplicate events eventSet = set() if DEBUG: if IGNORE_DUPLICATE: print 'ignore duplicated events' # Open the new calendarfile and adding the information about this script to it newcal = Calendar() newcal.add('prodid', '-//py_zarafa_pst_importer//') newcal.add('version', '2.0') newcal.add('x-wr-calname', 'Default') if DEBUG: print 'new calendar ' + merged_ical + ' started' # we need to add a timezone, because some clients want it (e.g. sunbird 0.5) newtimezone = Timezone() newtimezone.add('tzid', OUR_TIMEZONE) newcal.add_component(newtimezone) # Looping through the existing calendarfiles for ical in icals: try: # open the file and read it with open(ical,'rb') as calfile: cal = Calendar.from_ical(calfile.read()) if DEBUG: print 'reading file ' + ical # every part of the file... for component in cal.subcomponents: # ...which name is VEVENT will be added to the new file if component.name == 'VEVENT': try: if IGNORE_DUPLICATE: eventId = str(component['dtstart']) + ' | ' + str(component['dtend']) + ' | ' + str(component['summary']) if eventId not in eventSet: eventSet.add(eventId) else: if DEBUG: print 'skipped duplicated event: ' + eventId continue except: # ignore events with missing dtstart, dtend or summary if DEBUG: print '! skipped an event with missing dtstart, dtend or summary. likely historic or duplicated event.' continue newcal.add_component(component) except: # if the file was not readable, we need a errormessage ;) print 'Merge iCals: Error: reading file:', sys.exc_info()[1] print ical # After the loop, we have all of our data and can write the file now try: with open(merged_ical, 'wb') as f: f.write(newcal.to_ical()) if DEBUG: print 'new calendar written' except: print 'Merge iCals: Error: ', sys.exc_info()[1] s = requests.Session() s.auth = (zadmin, zadmin_password) try: #print "Importing Calendar" with open(merged_ical, 'rb') as f: r = s.put(url, verify=False, data=f) if r.status_code == 200: print "Successfully imported calendar" else: print "Failed to import calendar" except: print "Failed to connect with server"
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())
DEBUGMSG = DEBUGMSG + 'import of glob and sys done\n' # We need the iCalendar package from http://codespeak.net/icalendar/ from icalendar import Calendar, Event, Timezone DEBUGMSG = DEBUGMSG + 'inport of icalendar done\n' # Open the new calendarfile and adding the information about this script to it newcal = Calendar() newcal.add('prodid', '-//' + MY_NAME + '//' + MY_DOMAIN + '//') newcal.add('version', '2.0') newcal.add('x-wr-calname', CALENDARNAME) DEBUGMSG = DEBUGMSG + 'new calendar started\n' # we need to add a timezone, because some clients want it (e.g. sunbird 0.5) newtimezone = Timezone() newtimezone.add('tzid', OUR_TIMEZONE) newcal.add_component(newtimezone) # Looping through the existing calendarfiles for s in glob.glob(CALDIR + '*.ics'): try: # open the file and read it calfile = open(s,'rb') cal = Calendar.from_string(calfile.read()) # every part of the file... for component in cal.subcomponents: if component.name == 'VEVENT': # ...which name is VEVENT will be added to the new file newcal.add_component(component) # close the existing file
def parsePage(page, username): soup = BeautifulSoup(page) #print(soup.prettify()) geroosterd = soup.find('span', id="RoosterIngeroosterd0").find('table', "OraTableContent") ingeloggedstring = soup.find(text=re.compile("Laatst ingelogd")) m = re.search('(\d{4})',ingeloggedstring) jaar = int(m.group(0)) #print 'Niet geroosterd' #print soup('span', id="RoosterNietIngeroosterd0")[0].find('table', "x1h") #setup calendar cal = Calendar() cal.add('version', '2.0') cal.add('prodid', '-//Mijn Rooster//osiris.uu.nl//') cal.add('x-wr-calname', 'Rooster') cal.add('X-WR-TIMEZONE', 'Europe/Amsterdam') newtimezone = Timezone() newtimezone.add('tzid', "Europe/Amsterdam") cal.add_component(newtimezone) #get the data out and into the calendar maand = 0 dag = 0 for tr in geroosterd: if tr.contents[0].contents[0].name == 'table': #get the day dag = int(tr.contents[0].tr.contents[1].span.string) if len(tr.contents[0].tr.contents[1].span.string) > 1 else dag #get the time tijd = tr.contents[0].tr.contents[2].span.string startuur = int(tijd[1:3]) startmin = int(tijd[4:6]) enduur = int(tijd[10:12]) endmin = int(tijd[13:15]) #get the other data vakcode = tr.contents[1].span.string naam = tr.contents[3].span.string ctype = tr.contents[5].span.string groep = tr.contents[7].span.string if tr.contents[7].span != None else '' gebouw = tr.contents[9].a.string if tr.contents[9].a != None else '' ruimte = tr.contents[11].span.string if tr.contents[11].span != None else '' docent = tr.contents[13].span.string if tr.contents[13].span != None else '' description = groep + '\n' if groep != '' else '' description += 'docent: ' + docent if docent != '' else '' #make an event and add it event = Event() event.add('summary', ctype + ' ' + naam) event.add('location', gebouw + ' ' + ruimte) event.add('description', description) event.add('dtstart', datetime(jaar,maand,dag,startuur,startmin,0)) event.add('dtend', datetime(jaar,maand,dag,enduur,endmin,0)) event.add('dtstamp', datetime.now()) event['uid'] = str(jaar)+str(maand)+str(dag)+'T'+str(startuur)+str(startmin)+'00/'+username+vakcode+str(datetime.now().toordinal())+'*****@*****.**' cal.add_component(event) elif tr.contents[0].name == 'td': #record the new month and check if we are in the next year maand = monthnames.index(tr.contents[0].span.string) + 1 if maand == 1: jaar = jaar + 1 return cal
def get_cal(page_content): soup = BS(page_content, features="html.parser") tables = soup.find_all(class_="page_table") courses_info = [] for i in range(len(tables) // 2): table = tables[i * 2 + 1] rows = table.find('tbody').find_all('tr') cols_num = len(rows[0].find_all('td')) for row in rows: course_info = {} cols = row.find_all('td') course_info.update({ 'course_name': cols[1].text.split(']')[-1] + ("" if cols_num == 13 else "(实验)") }) course_info.update( {'teacher': cols[-4 if cols_num == 13 else -5].text}) course_info.update({'weeks': cols[-3].text}) course_info.update({'time': cols[-2].text.replace('节]', '')}) course_info.update({'location': cols[-1].text}) courses_info.append(course_info) for i in range(len(courses_info)): if courses_info[i]['course_name'] == '' or courses_info[i][ 'course_name'] == '(实验)': courses_info[i]['course_name'] = courses_info[i - 1]['course_name'] chinese_to_numbers = { '一': 0, '二': 1, '三': 2, '四': 3, '五': 4, '六': 5, '日': 6 } coursenum_to_time = { '1': (timedelta(hours=8, minutes=30), timedelta(hours=9, minutes=15)), '2': (timedelta(hours=9, minutes=25), timedelta(hours=10, minutes=10)), '3': (timedelta(hours=10, minutes=30), timedelta(hours=11, minutes=15)), '4': (timedelta(hours=11, minutes=25), timedelta(hours=12, minutes=10)), '5': (timedelta(hours=13, minutes=30), timedelta(hours=14, minutes=15)), '6': (timedelta(hours=14, minutes=25), timedelta(hours=15, minutes=10)), '7': (timedelta(hours=15, minutes=20), timedelta(hours=16, minutes=5)), '8': (timedelta(hours=16, minutes=25), timedelta(hours=17, minutes=10)), '9': (timedelta(hours=17, minutes=20), timedelta(hours=18, minutes=5)), '10': (timedelta(hours=19, minutes=0), timedelta(hours=19, minutes=45)), '11': (timedelta(hours=19, minutes=55), timedelta(hours=20, minutes=40)), '12': (timedelta(hours=20, minutes=50), timedelta(hours=21, minutes=35)), '13': (timedelta(hours=21, minutes=45), timedelta(hours=22, minutes=30)), } term_start_time = datetime(year=int(config["term_start_time"]["year"]), month=int(config["term_start_time"]["month"]), day=int(config["term_start_time"]["day"]), tzinfo=pytz.timezone('Asia/Shanghai')) events = [] for course in courses_info: week_nums = [] week_segs = course['weeks'].split(',') for seg in week_segs: delimiter = [int(i) for i in seg.split('-')] start = delimiter[0] end = delimiter[1] if len(delimiter) == 2 else start for i in range(start, end + 1): week_nums.append(i) day = chinese_to_numbers[course['time'].split('[')[0]] seg = course['time'].split('[')[1].split('-') if len(seg) == 2: inweek_delta_start = timedelta( days=day) + coursenum_to_time[seg[0]][0] inweek_delta_end = timedelta( days=day) + coursenum_to_time[seg[1]][1] for week_num in week_nums: event_start_datetime = term_start_time + ( week_num - 1) * timedelta(days=7) + inweek_delta_start event_end_datetime = term_start_time + ( week_num - 1) * timedelta(days=7) + inweek_delta_end event = Event() event.add( 'summary', '[{}]{}'.format(course['teacher'], course['course_name'])) event.add('location', course['location']) event.add('dtstart', event_start_datetime) event.add('dtend', event_end_datetime) # Fix #2: 添加 dtstamp 与 uid 属性 event.add('dtstamp', datetime.utcnow()) namespace = uuid.UUID( bytes=int(event_start_datetime.timestamp()).to_bytes( length=8, byteorder='big') + int(event_end_datetime.timestamp()).to_bytes( length=8, byteorder='big')) event.add( 'uid', uuid.uuid3(namespace, f"{course['course_name']}-{course['teacher']}")) events.append(event) cal = Calendar() cal.add( 'prodid', f'-//重庆大学课表//{config["user_info"]["username"]}//Powered By cqu-kb//') cal.add('version', '2.0') cal.add_component( Timezone.from_ical("BEGIN:VTIMEZONE\n" "TZID:Asia/Shanghai\n" "X-LIC-LOCATION:Asia/Shanghai\n" "BEGIN:STANDARD\n" "TZNAME:CST\n" "DTSTART:16010101T000000\n" "TZOFFSETFROM:+0800\n" "TZOFFSETTO:+0800\n" "END:STANDARD\n" "END:VTIMEZONE\n")) for event in events: cal.add_component(event) return cal
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
""" import hashlib import os from datetime import datetime, timedelta from typing import Dict, List, Tuple import pytz from ddtrace import tracer from icalendar import Alarm, Calendar, Event, Timezone, TimezoneStandard from everyclass.common.time import get_time from everyclass.server.config import get_config from everyclass.server.models import Semester from everyclass.server.utils import calendar_dir 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)) def generate(name: str, cards: Dict[Tuple[int, int], List[Dict]], semester: Semester, filename: str) -> None: """ 生成 ics 文件并保存到目录 :param name: 姓名 :param cards: 参与的课程
DEBUGMSG = DEBUGMSG + 'import of glob and sys done\n' # We need the iCalendar package from http://codespeak.net/icalendar/ from icalendar import Calendar, Event, Timezone DEBUGMSG = DEBUGMSG + 'inport of icalendar done\n' # Open the new calendarfile and adding the information about this script to it newcal = Calendar() newcal.add('prodid', '-//' + MY_NAME + '//' + MY_DOMAIN + '//') newcal.add('version', '2.0') newcal.add('x-wr-calname', CALENDARNAME) DEBUGMSG = DEBUGMSG + 'new calendar started\n' # we need to add a timezone, because some clients want it (e.g. sunbird 0.5) newtimezone = Timezone() newtimezone.add('tzid', OUR_TIMEZONE) newcal.add_component(newtimezone) # Looping through the existing calendarfiles for s in glob.glob(CALDIR + '*.ics'): try: # open the file and read it calfile = open(s, 'rb') cal = Calendar.from_string(calfile.read()) # every part of the file... for component in cal.subcomponents: if component.name == 'VEVENT': # ...which name is VEVENT will be added to the new file newcal.add_component(component) # close the existing file
import configparser import datetime import uuid import json from io import BytesIO from openpyxl import load_workbook from icalendar import Calendar, Event, Timezone, vDDDTypes __all__ = ('mkical', 'load_from_xlsx', 'loadIO_from_xlsx', 'load_from_json', 'loadIO_from_json') VTIMEZONE = Timezone.from_ical("""BEGIN:VTIMEZONE TZID:Asia/Shanghai X-LIC-LOCATION:Asia/Shanghai BEGIN:STANDARD TZNAME:CST TZOFFSETFROM:+0800 TZOFFSETTO:+0800 DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE""") TIMEZONE = VTIMEZONE.to_tz() time_dict = { 1: [(8, 30), (9, 15)], 2: [(9, 25), (10, 10)], 3: [(10, 30), (11, 15)], 4: [(11, 25), (12, 10)], 5: [(13, 30), (14, 15)], 6: [(14, 25), (15, 10)], 7: [(15, 20), (16, 0o5)], 8: [(16, 25), (17, 10)], 9: [(17, 20), (18, 0o5)],
def get_cal(self, course_info): chinese_to_numbers = { "一": 0, "二": 1, "三": 2, "四": 3, "五": 4, "六": 5, "日": 6 } coursenum_to_time = { "1": (timedelta(hours=8, minutes=30), timedelta(hours=9, minutes=15)), "2": (timedelta(hours=9, minutes=25), timedelta(hours=10, minutes=10)), "3": (timedelta(hours=10, minutes=30), timedelta(hours=11, minutes=15)), "4": (timedelta(hours=11, minutes=25), timedelta(hours=12, minutes=10)), "5": (timedelta(hours=13, minutes=30), timedelta(hours=14, minutes=15)), "6": (timedelta(hours=14, minutes=25), timedelta(hours=15, minutes=10)), "7": (timedelta(hours=15, minutes=20), timedelta(hours=16, minutes=5)), "8": (timedelta(hours=16, minutes=25), timedelta(hours=17, minutes=10)), "9": (timedelta(hours=17, minutes=20), timedelta(hours=18, minutes=5)), "10": (timedelta(hours=19, minutes=0), timedelta(hours=19, minutes=45)), "11": (timedelta(hours=19, minutes=55), timedelta(hours=20, minutes=40)), "12": (timedelta(hours=20, minutes=50), timedelta(hours=21, minutes=35)), "13": (timedelta(hours=21, minutes=45), timedelta(hours=22, minutes=30)), } term_start_time = datetime( year=int(config["term_start_time"]["year"]), month=int(config["term_start_time"]["month"]), day=int(config["term_start_time"]["day"]), tzinfo=pytz.timezone("Asia/Shanghai"), ) events = [] for course in course_info: week_nums = [] week_segs = course["weeks"].split(",") for seg in week_segs: delimiter = [int(i) for i in seg.split("-")] start = delimiter[0] end = delimiter[1] if len(delimiter) == 2 else start for i in range(start, end + 1): week_nums.append(i) if not course["time"].split("[")[0].isdigit(): day = chinese_to_numbers[course["time"].split("[")[0]] else: day = int(course["time"].split("[")[0]) seg = course["time"].split("[")[1].split("-") if len(seg) == 2: inweek_delta_start = timedelta( days=day) + coursenum_to_time[seg[0]][0] inweek_delta_end = timedelta( days=day) + coursenum_to_time[seg[1]][1] for week_num in week_nums: event_start_datetime = ( term_start_time + (week_num - 1) * timedelta(days=7) + inweek_delta_start) event_end_datetime = (term_start_time + (week_num - 1) * timedelta(days=7) + inweek_delta_end) event = Event() event.add( "summary", "[{}]{}".format(course["teacher"], course["course_name"]), ) event.add("location", course["location"]) self._add_datetime(event, "dtstart", event_start_datetime) self._add_datetime(event, "dtend", event_end_datetime) # Fix #2: 添加 dtstamp 与 uid 属性 event.add("dtstamp", datetime.utcnow()) namespace = uuid.UUID( bytes=int(event_start_datetime.timestamp()).to_bytes( length=8, byteorder="big") + int(event_end_datetime.timestamp()).to_bytes( length=8, byteorder="big")) event.add( "uid", uuid.uuid3( namespace, f"{course['course_name']}-{course['teacher']}"), ) events.append(event) cal = Calendar() cal.add( "prodid", f'-//重庆大学课表//{config["user_info"]["username"]}//Powered By cqu-kb//', ) cal.add("version", "2.0") cal.add_component( Timezone.from_ical("BEGIN:VTIMEZONE\n" "TZID:Asia/Shanghai\n" "X-LIC-LOCATION:Asia/Shanghai\n" "BEGIN:STANDARD\n" "TZNAME:CST\n" "DTSTART:16010101T000000\n" "TZOFFSETFROM:+0800\n" "TZOFFSETTO:+0800\n" "END:STANDARD\n" "END:VTIMEZONE\n")) for event in events: 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()