def generate(dates, output_filename, *, name=None, description=None, uid=None): c = ical.Calendar() c.add("prodid", "-//electioncal.us generator//circuitpython.org//") c.add("version", "2.0") path_parts = output_filename.split("/") c.add( "url", ical.vUri("https://electioncal.us/" + "/".join(path_parts[1:-1]) + "/")) c.add("source", ical.vUri("https://electioncal.us/" + "/".join(path_parts[1:]))) # c.add('REFRESH-INTERVAL'VALUE=DURATION:P1W, value) if name: c.add("name", name) if description: c.add("description", description) if uid: c.add("uid", uid) last_modified = None for date in dates: event = ical.Event() event.add("summary", date["name"]) event.add("dtstart", ical.vDate(date["date"])) c.add_component(event) if description: c.add("last-modified", ical.vDate(date["date"])) with open(output_filename, "wb") as f: f.write(c.to_ical())
def shift_dates(cal, change): for event in cal.walk('vevent'): #loops through calendar events start_date = event.get('dtstart').dt start_new_date = start_date + timedelta(days=change) #gets initial date and applies shift if hasattr(start_new_date, 'tzinfo'): #converts to correct format for calendar file start_shifted_date = vDatetime(start_new_date) else: start_shifted_date = vDate(start_new_date) event['dtstart'] = start_shifted_date #applies new date to event end_date = event.get('dtend').dt end_new_date = end_date + timedelta(days=change) if hasattr(end_new_date, 'tzinfo'): end_shifted_date = vDatetime(end_new_date) else: end_shifted_date = vDate(end_new_date) event['dtend'] = end_shifted_date output_calendar = cal.to_ical() #converts calendar file to text return output_calendar
def generate_ical_event(event, now): cal_event = Event() cal_event.add('DTSTAMP', vDatetime(now)) cal_event.add('SEQUENCE', 0) cal_event.add('UID', 'event_{}@foss.events'.format(event['id'])) cal_event.add('summary', event['label']) cal_event.add('dtstart', vDate(event['start_date'])) cal_end_date = event['end_date'] + timedelta(days=1) cal_event.add('dtend', vDate(cal_end_date)) cal_event.add('location', event['readable_location']) cal_event.add('url', vUri(event['abs_details_url'])) description = event['description'] or '' description += '\n\n' if event['has_details']: description += 'Read everything about ' + event['label'] + ' in a nutshell on // foss.events: ' + event['abs_details_url'] + '\n\n' description += 'Official Homepage: ' + event['homepage'] + '\n\n' if event['osm_link']: description += 'Find your way: ' + event['osm_link'] + '\n' cal_event['description'] = remove_tags(description) if event['lat'] and event['lon']: cal_event['geo'] = vGeo([event['lat'], event['lon']]) return cal_event
def events_to_private_ical_feed(user): """ Generate an ICAL feed for all events associated with the given user. :param user: The user to generate an ICAL feed for. :return: An ICAL string of all the user's events. """ timezone.activate(pytz.timezone(user.settings.time_zone)) calendar = _create_calendar(user) for event in user.events.iterator(): calendar_event = icalendar.Event() calendar_event["UID"] = "he-{}-{}".format(user.pk, event.pk) calendar_event["SUMMARY"] = event.title calendar_event["DTSTAMP"] = icalendar.vDatetime(timezone.localtime(event.created_at)) if not event.all_day: calendar_event["DTSTART"] = icalendar.vDatetime(timezone.localtime(event.start)) calendar_event["DTEND"] = icalendar.vDatetime(timezone.localtime(event.end)) else: calendar_event["DTSTART"] = icalendar.vDate(event.start) calendar_event["DTEND"] = icalendar.vDate((event.end + datetime.timedelta(days=1))) calendar_event["DESCRIPTION"] = _create_event_description(event) calendar.add_component(calendar_event) timezone.deactivate() return calendar.to_ical()
def homework_to_private_ical_feed(user): """ Generate an ICAL feed for all homework associated with the given user. :param user: The user to generate an ICAL feed for. :return: An ICAL string of all the user's homework. """ timezone.activate(pytz.timezone(user.settings.time_zone)) calendar = _create_calendar(user) for homework in Homework.objects.for_user(user.pk).iterator(): calendar_event = icalendar.Event() calendar_event["UID"] = "he-{}-{}".format(user.pk, homework.pk) calendar_event["SUMMARY"] = homework.title calendar_event["DTSTAMP"] = icalendar.vDatetime(timezone.localtime(homework.created_at)) if not homework.all_day: calendar_event["DTSTART"] = icalendar.vDatetime(timezone.localtime(homework.start)) calendar_event["DTEND"] = icalendar.vDatetime(timezone.localtime(homework.end)) else: calendar_event["DTSTART"] = icalendar.vDate(homework.start) calendar_event["DTEND"] = icalendar.vDate((homework.end + datetime.timedelta(days=1))) calendar_event["DESCRIPTION"] = _create_homework_description(homework) calendar.add_component(calendar_event) timezone.deactivate() return calendar.to_ical()
def examples_for_term(course_year, term): examples = list(course_year.examples(term)) events = [] for example in examples: events.append(icalendar.Event( summary='P{0.paper_no}: {0.name} - Example paper {0.sheet_no}'.format(example), dtstart=icalendar.vDatetime(timezone.localize(example.class_start).astimezone(pytz.utc)), dtend=icalendar.vDatetime(timezone.localize(example.class_end).astimezone(pytz.utc)), dtstamp=icalendar.vDatetime(last_updated), location=icalendar.vText( "{} - {}".format(example.class_location, cued_address) if example.class_location else cued_address ), uid='{0.paper_no}-{0.sheet_no}.{term}.{part}@efw27.user.srcf.net'.format( example, term=term, part=course_year.part ), description=icalendar.vText('Lecturer: {.class_lecturer}'.format(example)) )) # group and order by issue date, ignoring those issued the previous term issue_key = lambda e: e.issue_date examples = filter(issue_key, examples) examples = sorted(examples, key=issue_key) examples = itertools.groupby(examples, issue_key) for i, (issue_date, papers) in enumerate(examples): # consume the iterable so that we can len() it papers = list(papers) events.append(icalendar.Event( summary='Collect {} example paper{}'.format(len(papers), '' if len(papers) == 1 else 's'), dtstart=icalendar.vDate(timezone.localize(issue_date).astimezone(pytz.utc)), dtend=icalendar.vDate(timezone.localize(issue_date).astimezone(pytz.utc)), dtstamp=icalendar.vDatetime(last_updated), location=icalendar.vText(cued_address), uid='collection-{i}.{term}.{part}@efw27.user.srcf.net'.format( i=i, term=term, part=course_year.part ), description=icalendar.vText('\n'.join( 'P{0.paper_no}: {0.name} - Example paper {0.sheet_no}'.format(p) for p in papers )) )) return events
def icalendar_event(self): if self.context.birth_date is None: return summary = '%s (*%s)' % (icemac.addressbook.interfaces.ITitle( self.context), self.context.birth_date.year) return icalendar.Event( uid=self.url(self.context, 'iCalendar'), summary=summary, dtstart=icalendar.vDate(self.context.birth_date), dtend=icalendar.vDate(self.context.birth_date + ONE_DAY), rrule=icalendar.vRecur(freq='yearly'))
def to_ical_event(self) -> IEvent: dtstart = datetime(self.year, self.month_from, self.day_from) dtend = datetime(self.year, self.month_to, self.day_to) dtend += timedelta(days=+1) e = IEvent() e.add("summary", self.subject) e.add("dtstart", vDate(dtstart)) e.add("dtend", vDate(dtend)) return e
def examples_for_term(course_year, term): examples = list(course_year.examples(term)) events = [] for example in examples: events.append( icalendar.Event( summary='P{0.paper_no}: {0.name} - Example paper {0.sheet_no}'. format(example), dtstart=icalendar.vDatetime( timezone.localize(example.class_start).astimezone( pytz.utc)), dtend=icalendar.vDatetime( timezone.localize(example.class_end).astimezone(pytz.utc)), dtstamp=icalendar.vDatetime(last_updated), location=icalendar.vText( "{} - {}".format(example.class_location, cued_address) if example.class_location else cued_address), uid='{0.paper_no}-{0.sheet_no}.{term}.{part}@efw27.user.srcf.net' .format(example, term=term, part=course_year.part), description=icalendar.vText( 'Lecturer: {.class_lecturer}'.format(example)))) # group and order by issue date, ignoring those issued the previous term issue_key = lambda e: e.issue_date examples = filter(issue_key, examples) examples = sorted(examples, key=issue_key) examples = itertools.groupby(examples, issue_key) for i, (issue_date, papers) in enumerate(examples): # consume the iterable so that we can len() it papers = list(papers) events.append( icalendar.Event( summary='Collect {} example paper{}'.format( len(papers), '' if len(papers) == 1 else 's'), dtstart=icalendar.vDate( timezone.localize(issue_date).astimezone(pytz.utc)), dtend=icalendar.vDate( timezone.localize(issue_date).astimezone(pytz.utc)), dtstamp=icalendar.vDatetime(last_updated), location=icalendar.vText(cued_address), uid='collection-{i}.{term}.{part}@efw27.user.srcf.net'.format( i=i, term=term, part=course_year.part), description=icalendar.vText('\n'.join( 'P{0.paper_no}: {0.name} - Example paper {0.sheet_no}'. format(p) for p in papers)))) return events
def generateICS(name, month, duties): td = date.today() cal = Calendar() start_day = date(td.year, month, 1) cal['dtstart'] = start_day for duty in duties: et = Event() et['dtstart'] = vDate(start_day) end_day = start_day + timedelta(days=1) et['dtend'] = vDate(end_day) et['summary'] = duty cal.add_component(et) start_day = end_day with open('./' + name + '-' + str(month) + '月.ics', 'w') as ics: ics.write( str(cal.to_ical(), encoding='utf-8').replace('\r\n', '\n').strip())
def mk_time(value): try: return vDate(datetime.strptime(value, "%a %b %d %Y")) except ValueError: try: return vDatetime(datetime.strptime(value, "%a %b %d %H:%M %Y")) except ValueError: raise DateParseError(value)
def main(): """メイン関数.""" p = ArgumentParser(description='札幌市家庭ゴミ収集日カレンダーCSVをical化する') p.add_argument('-a', '--area', help='地域名') p.add_argument( 'input', type=FileType(encoding='utf-8'), help='札幌市家庭ゴミ収集日カレンダーCSV') args = p.parse_args() df = pandas.read_csv(args.input, dtype='object') if args.area is None: print('入力可能な地域名:', file=sys.stderr) for area in df.columns[2:]: print(' ' + area, file=sys.stderr) return if args.area not in df.columns[2:]: print('地域名が見つかりません.', file=sys.stderr) return gctypes = { '1': '燃やせるゴミ', '2': '燃やせないゴミ', '8': 'びん・缶・ペット', '9': '容器プラ', '10': '雑がみ', '11': '枝・葉・草' } ical = Calendar() for datestr, gctype in zip(df['日付'], df[args.area]): if gctype in gctypes: dt = dateutil.parser.parse(datestr) event = Event() event.add('SUMMARY', gctypes[gctype]) event.add('DTSTART', vDate(dt)) event.add('DTEND', vDate(dt)) event.add('TRANSP', 'TRANSPARENT') ical.add_component(event) print(ical.to_ical().decode('utf-8'))
def shift_dates(cal, change): for event in cal.walk('vevent'): start_date = event.get('dtstart').dt start_new_date = start_date + timedelta(days=change) if hasattr(start_new_date, 'tzinfo'): start_shifted_date = vDatetime(start_new_date).to_ical() else: start_shifted_date = vDate(start_new_date).to_ical() original_date = event.get('dtstart').to_ical() shifts_to_do[original_date] = start_shifted_date end_date = event.get('dtend').dt end_new_date = end_date + timedelta(days=change) if hasattr(end_new_date, 'tzinfo'): end_shifted_date = vDatetime(end_new_date).to_ical() else: end_shifted_date = vDate(end_new_date).to_ical() end_original_date = event.get('dtend').to_ical() shifts_to_do[end_original_date] = end_shifted_date
def generate_event_ical_files(events): for event in events: cal = Calendar() cal.add('prodid', '-//foss.events//foss.events//') cal.add('version', '1.3.3.7') cal_event = Event() cal_event.add('summary', event['label']) cal_event.add('dtstart', vDate(event['start_date'])) cal_end_date = event['end_date'] + timedelta(days=1) cal_event.add('dtend', vDate(cal_end_date)) cal_event.add('location', event['readable_location']) cal_event.add('url', vUri(event['abs_details_url'])) description = event['description'] or '' description += '\n\n' if event['has_details']: description += 'Read everything about ' + event[ 'label'] + ' in a nutshell on // foss.events: ' + event[ 'abs_details_url'] + '\n\n' description += 'Official Homepage: ' + event['homepage'] + '\n\n' if event['osm_link']: description += 'Find your way: ' + event['osm_link'] + '\n' cal_event['description'] = remove_tags(description) cal.add_component(cal_event) if event['lat'] and event['lon']: cal_event['geo'] = vGeo([event['lat'], event['lon']]) filepath = generate_event_ical_path(event) with open('build/' + filepath, 'wb') as f: f.write(cal.to_ical())
def testDate(self): day = dt.date(1979, 8, 16) v = vDt(day) self.assertTrue(v) self.assertEqual(v, day) self.assertEqual(v, vDate(day)) self.assertEqual(v, vDate.from_ical("19790816")) self.assertEqual(v.date(), day) self.assertEqual(v.time(), None) self.assertEqual(v.datetime(), getLocalDatetime(day, dt.time.min)) self.assertEqual(v.tzinfo(), None) self.assertEqual(v.zone(), None) self.assertEqual(v.timezone(), pytz.timezone("Asia/Tokyo"))
def __init__(self, info, occurrence, viewer=None): super(AgendaEvent, self).__init__() if viewer is not None: timezone = viewer.get_timezone() else: timezone = occurrence.get_timezone() cdate = occurrence.get_calendar_datetime() start_dt = cdate.get_start_datetime(timezone) end_dt = cdate.get_end_datetime(timezone) if occurrence.is_all_day(): start_date = date(start_dt.year, start_dt.month, start_dt.day) # end date is exclusive end_date = date(end_dt.year, end_dt.month, end_dt.day) + \ relativedelta(days=+1) self['DTSTART'] = vDate(start_date) if end_date != start_date: self['DTEND'] = vDate(end_date) else: self['DTSTART'] = vDatetime(start_dt.astimezone(UTC)) self['DTEND'] = vDatetime(end_dt.astimezone(UTC)) rrule_string = occurrence.get_recurrence() if rrule_string is not None: self['RRULE'] = rrule_string location = occurrence.get_location() if location: self['LOCATION'] = vText(location) # Generic properties self['URL'] = info.url self['UID'] = info.uid() self['SUMMARY'] = vText(info.summary) if info.created: self['CREATED'] = vDatetime(info.created) if info.last_modified: self['LAST-MODIFIED'] = vDatetime(info.last_modified) if info.description: self['DESCRIPTION'] = vText(info.description)
def courseschedules_to_private_ical_feed(user): """ Generate an ICAL feed for all course schedules associated with the given user. The IDs given for each event are sequential, unique only amongst the results of this particular query, and not guaranteed to be consistent across calls. :param user: The user to generate an ICAL feed for. :return: An ICAL string of all the user's course schedules. """ calendar = _create_calendar(user) events = [] for course in Course.objects.for_user(user.pk).iterator(): events += coursescheduleservice.course_schedules_to_events(course, course.schedules) timezone.activate(pytz.timezone(user.settings.time_zone)) for event in events: calendar_event = icalendar.Event() calendar_event["UID"] = "he-{}-{}".format(user.pk, event.pk) calendar_event["SUMMARY"] = event.title calendar_event["DTSTAMP"] = icalendar.vDatetime(timezone.localtime(event.created_at)) if not event.all_day: calendar_event["DTSTART"] = icalendar.vDatetime(timezone.localtime(event.start)) calendar_event["DTEND"] = icalendar.vDatetime(timezone.localtime(event.end)) else: calendar_event["DTSTART"] = icalendar.vDate(event.start) calendar_event["DTEND"] = icalendar.vDate((event.end + datetime.timedelta(days=1))) calendar_event["DESCRIPTION"] = _create_event_description(event) calendar.add_component(calendar_event) timezone.deactivate() return calendar.to_ical()
def get(self): self.response.headers['Content-Type'] = 'text/calendar' calendar = memcache.get("ksc-calendar") if calendar: self.response.out.write(calendar) return cal = Calendar() cal.add('version', '2.0') cal.add('prodid', '-//Kennedy Space Center launches by Chad//NONSCML//EN') cal.add('X-WR-CALID', '8293bcab-1b27-44dd-8a3c-2bb045888629') cal.add('X-WR-CALNAME', 'KSC launches by Chad') cal.add( 'X-WR-CALDESC', "NASA publishes a web page of scheduled launches, but an iCalendar/RFC5545 feed would be so much better and useful. So, ( https://chad.org/ ) Chad made one. Enjoy!" ) cal.add('X-WR-TIMEZONE', 'US/Eastern') launch_calendar_id = 6089 two_months_ago = datetime.utcnow() + timedelta(days=-60) one_year_from_now = datetime.utcnow() + timedelta(days=365) index_json = urllib2.urlopen( "https://www.nasa.gov/api/1/query/calendar.json?timeRange={0}--{1}&calendars={2}" .format(two_months_ago.strftime("%Y%m%d0000"), one_year_from_now.strftime("%Y%m%d0000"), launch_calendar_id)) index = json.load(index_json) for index_event in index["calendarEvents"]: assert index_event["type"] == "calendar_event" ev_url = "https://www.nasa.gov/api/1/query/node/{0}.json?{1}".format( index_event["nid"], index_event["urlQuery"]) event_json = urllib2.urlopen(ev_url) event_info = json.load(event_json) if "eventDate" in event_info["calendarEvent"]: for i, event_occurance in enumerate( event_info["calendarEvent"]["eventDate"]): event = Event() event.add( 'uid', event_info["calendarEvent"]["uuid"] + "_" + str(i)) event.add('summary', event_info["calendarEvent"]["title"]) event.add('description', event_info["calendarEvent"]["description"]) event.add( 'dtstamp', datetime.fromtimestamp( int(event_info["calendarEvent"]["changed"]))) date_start = datetime.strptime( event_occurance["value"][:-5], "%Y-%m-%dT%H:%M:%S-") date_end = datetime.strptime( event_occurance["value2"][:-5], "%Y-%m-%dT%H:%M:%S-") if event_occurance["date_type"] == "date": event.add("dtstart;value=date", icalendar.vDate(date_start).ical()) event.add("dtend;value=date", icalendar.vDate(date_end).ical()) else: event.add("dtstart", date_start) event.add("dtend", date_end) cal.add_component(event) self.response.out.write(cal.as_string()) for retry in range(3): if not memcache.add("ksc-calendar", cal.as_string(), 60 * 5): logging.warn("Failed to add data to Memcache.") time.sleep(0.5) else: break
description_key = [dk for dk in data.keys() if dk.endswith("Mission")][0] event = Event() event.add( 'summary', "%s launch from %s" % (data.get( "Mission", "unlisted"), data.get("Launch Site", "unlisted site"))) event.add( 'description', data.get(description_key) + " // last verified " + datetime.now().isoformat()[:-10]) event.add('dtstamp', datetime.now()) # todo: make this the modtime of page if type(d) == datetime: event.add('dtstart', d) else: event.add('dtstart;value=date', icalendar.vDate(d).ical()) if type(d) == datetime: event.add('dtend', d + timedelta(minutes=10)) else: event.add('dtend;value=date', icalendar.vDate(d).ical()) event["uid"] = "*****@*****.**" % (data.get( "Mission", "MISSION").replace(" ", "-").lower(), ) return event class EventsListingCal(webapp.RequestHandler): def get(self): self.response.headers['Content-Type'] = 'text/calendar' calendar = memcache.get("ksc-calendar")
CALENDAR_URL = "https://www.seiyu.co.jp/service/5off/" if __name__ == '__main__': html = urllib.request.urlopen(CALENDAR_URL).read().decode("utf-8") bs = BeautifulSoup(html, "lxml") c = Calendar() c.add("version", "2.0") year = datetime.today().year base_month = datetime.today().month items = bs.find_all("ul", class_="off_calendar_list") for item in items: month = int( item.find("span", class_="off_calendar_month").text.strip("/")) if month < base_month: base_month = month year = year + 1 for i in item.find_all("span", class_="off_calendar_day"): day = int(i.text) e = Event() e.add("summary", "西友 5% OFF 開催日") e.add("dtstart", vDate(datetime(year, month, day))) c.add_component(e) print(c.to_ical().decode("utf-8").strip())
def doctree_resolved(app, doctree, docname): builder = app.builder for node in doctree.traverse(PendingICS): series_name = node._series_name data = node._data LOG.info('building {} calendar'.format(series_name)) cal = icalendar.Calendar() cal.add('prodid', '-//releases.openstack.org//EN') cal.add('X-WR-CALNAME', '{} schedule'.format(series_name)) for week in data['cycle']: if not week.get('name'): continue event = icalendar.Event() summary = [] for item in week.get('x-project', []): try: # Look up the cross-reference name to get the # section, then get the title from the first child # node. title = doctree.ids[item].children[0].astext() except Exception as e: # NOTE(dhellmann): Catching "Exception" is a bit # ugly, but given the complexity of the expression # above there are a bunch of ways things might # fail. LOG.info('could not get title for {}: {}'.format(item, e)) title = item summary.append(title) if summary: summary_text = ' (' + '; '.join(summary) + ')' else: summary_text = '' event.add( 'summary', '{} {}{}'.format(series_name.title(), week['name'], summary_text), ) event.add('dtstamp', node.last_update) event.add('uid', '%s-%s' % (series_name, week.get('name'))) start = datetime.datetime.strptime(week['start'], '%Y-%m-%d') event.add('dtstart', icalendar.vDate(start.date())) # NOTE(dhellmann): ical assumes a time of midnight, so in # order to have the event span the final day of the week # we have to add an extra day. raw_end = datetime.datetime.strptime(week['end'], '%Y-%m-%d') end = raw_end + datetime.timedelta(days=1) event.add('dtend', icalendar.vDate(end.date())) # Look up the cross-reference name to get the # section, then add the full description to the # text. description = [ _format_description(doctree.ids[item]) for item in week.get('x-project', []) if item in doctree.ids ] if description: event.add('description', '\n\n'.join(description)) cal.add_component(event) _global_calendar.add_component(event) output_full_name = os.path.join( builder.outdir, docname + '.ics', ) output_dir_name = os.path.dirname(output_full_name) if not os.path.exists(output_dir_name): os.makedirs(output_dir_name) destination = FileOutput( destination_path=output_full_name, encoding='utf-8', ) LOG.info('generating {}'.format(output_full_name)) destination.write(cal.to_ical()) # Remove the node that the writer won't understand. node.parent.replace(node, [])
cal.add('prodid', '-//Google Inc//Google Calendar 70.9054//EN') cal.add('calscale', 'GREGORIAN') cal.add('method', 'PUBLISH') cal.add('X-WR-CALNAME', 'Toronto Events Calendar') cal.add('X-WR-TIMEZONE', 'America/Toronto') cal.add('X-ORIGINAL-URL', 'http://scraperwikiviews.com/run/torontoca_events_calendar_ical/') for row_num, ev in enumerate(data): event = Event() event.add('summary', ev['name'].replace(",","\,")) event.add('description', ev['description'].replace(",","\,").replace(";","\;")) startdt = enddt = datetime.datetime.strptime(ev['date'], "%Y-%m-%d") event.add('dtstart;VALUE=DATE', vDate(startdt).ical()) event.add('dtend;VALUE=DATE', vDate(enddt).ical()) event.add('dtstamp;VALUE=DATE-TIME', vDatetime(startdt).ical()) event.add('uid', str(row_num)+"@toronto-events") event.add('class', 'PUBLIC') cal.add_component(event) scraperwiki.utils.httpresponseheader("Content-Type", "text/calendar") scraperwiki.utils.httpresponseheader("Content-Disposition", "inline; filename=toronto-events.ics") print cal.as_string()import scraperwiki from icalendar import Calendar, Event, UTC, vDate, vDatetime import datetime from pytz import timezone
def main(): # 津山工業高等専門学校 行事予定 URL(2016/08/17現在) # まあ毎年URL変わるようだったら入力制にするかも URL = "http://www.tsuyama-ct.ac.jp/gyoujiVer4/gyouji.html" # カレンダーで読み込み可能にする為の.csv用ヘッダ CSV_HEAD = 'Subject,Start Date,End Date,All Day Event\n' # ファイルタイプ FILE_TYPE = ["csv", "ics"] # argparseの設定 parser = argparse.ArgumentParser(description="4月~3月までの一年間の行事予定を出力します" + URL) parser.add_argument("year", type=int, help="予定表に対応する年度の西暦") parser.add_argument("type", choices=FILE_TYPE, help="予定表の出力形式") # コマンドライン引数の値を取得 args = parser.parse_args() # Requests オブジェクト r = requests.get(URL) if r.status_code != 200: # ステータスコードによる例外処理 raise ConnectionError("\tStatus Code is not equal 200.\n\tStatus Code: " + r.status_code) if r.encoding == 'ISO-8859-1': # Encodingをutf-8に変更 r.encoding = 'utf-8' # 行ごとに分割 lines = r.text.split("\n") del r csv_f = tempfile.TemporaryFile("r+") # .csvにヘッダを書き込む csv_f.write(CSV_HEAD) # iCalヘッダ生成 cal = Calendar() cal.add('proid', '津山高専行事予定' + str(args.year) + '年度版(calconv)') cal.add('version', '2.0') # 後ろの改行文字を取り除く for i, line in enumerate(lines): lines[i] = line.rstrip() # 予定表部分終了部分(テキストそのままのため、何か終了検出方法を考えるべき) SCHEDULE_END = '</div>' # 4月の予定が読み込み開始されたかのフラグ month_start_flag = False # 予定がコメントアウト中の行にあるかのフラグ comout_flag = False i = 0 # for-eachで一行のリストごとに処理 for line in lines: # 検出に必要のない文字列を取り除く line = remove_garbage(line) # 曜日を$に置換 line = replace_week(line) # 改行のみの行を取り除く # remove_garbage()のガバガバ操作の影響でソースが気持ち悪い # 変なHTMLソースに対応するため if line != " ": # print(line) month_searching = month_search(line) # 月の行以外はmonthを変えない if month_search(line) >= 1: month = month_searching if month_searching == 4: month_start_flag = True if month_start_flag: # 予定表部分が終了した場合,breakする if SCHEDULE_END in line: break # コメントアウト行終了時にフラグを下ろす elif month_searching == -1: comout_flag = False # コメントアウト行開始時にフラグを立てる elif month_searching == -2: comout_flag = True # コメントアウト行でないかつ月表示の行でない場合の処理 elif not comout_flag and month_searching == 0: # 構造体を渡す csv_write = CSV_Struct() if month <= 12: csv_write.start = digit_conv(month) + '/' # 期間予定かの検出 date_end = [] # date_end初期化 span = span_search(line) csv_write.start = csv_write.start + date_start_search(line) + '/' # 一日予定 if span == -1: # 月末の場合は次の月の始めを設定 date_end = date_end_next(args.year, month, int(date_start_search(line))) if date_end[0]: if month == 12: jan = '01' csv_write.end = jan + '/' else: csv_write.end = digit_conv(month + 1) + '/' else: csv_write.end = digit_conv(month) + '/' csv_write.end = csv_write.end + date_end[1] + '/' # 期間予定 elif span == 0: date_end = date_end_next(args.year, month, int(date_end_search(line))) if date_end[0]: if month == 12: jan = '01' csv_write.end = jan + '/' else: csv_write.end = digit_conv(month + 1) + '/' else: csv_write.end = digit_conv(month) + '/' csv_write.end = csv_write.end + date_end[1] + '/' # 月と書かれた期間予定 elif span == -2: mde = month_date_end_search(line) date_end = date_end_next(args.year, int(mde[0]), int(mde[1])) if date_end[0]: if month == 12: jan = '01' csv_write.end = jan + '/' else: csv_write.end = digit_conv(int(mde[0]) + 1) + '/' else: csv_write.end = digit_conv(int(mde[0])) + '/' csv_write.end = csv_write.end + date_end[1] + '/' # 1日 first = '01' # startは1~3月なら次の年を設定 if month < 4: csv_write.start = csv_write.start + str(args.year + 1) else: csv_write.start = csv_write.start + str(args.year) decem = 12 # endは12月予定かつ月を跨いでいるまたは,1~3月なら次の年を設定 if month == decem and span == -2 or month == decem and date_end[0] or month < 4: csv_write.end = csv_write.end + str(args.year + 1) else: csv_write.end = csv_write.end + str(args.year) csv_write.sub = sub_search(line) # 各種表示 # print("start: " + csv_write.start) # print("end: " + csv_write.end) # print("sub: " + csv_write.sub) # iCal形式の作成 event = Event() event.add('summary', csv_write.sub) dt = datetime.datetime.strptime(csv_write.start, "%m/%d/%Y") event.add('dtstart', vDate(dt)) dt = datetime.datetime.strptime(csv_write.end, "%m/%d/%Y") event.add('dtend', vDate(dt)) # .csvに書き込む csv_f.write(csv_write.sub + "," + csv_write.start + "," + csv_write.end + "," + csv_write.ALL_DAY + "\n") # cal(iCal)に書き込む cal.add_component(event) # .icsに書き込む ics_f = tempfile.TemporaryFile("r+") # print(cal.to_ical().decode('utf-8')) ics_f.write(cal.to_ical().decode('utf-8')) return_str = "" # 指定形式の文字列を返す if args.type == FILE_TYPE[0]: csv_f.seek(0) return_str = csv_f.read() elif args.type == FILE_TYPE[1]: ics_f.seek(0) return_str = ics_f.read() # ファイルクローズ csv_f.close() ics_f.close() return return_str