import argparse import bottle import datetime from . import google_calendar import config TEMPLATE_INDEX = bottle.SimpleTemplate(name = "templates/index.html") # Template rendering def last_day_of_month(date): date = date.replace(day = 28) + datetime.timedelta(days = 5) date = date.replace(day = 1) date = date - datetime.timedelta(days = 1) return date def range_to_render(today): first_day_of_month = today.replace(day = 1) start = first_day_of_month - datetime.timedelta(days = first_day_of_month.weekday()) end = last_day_of_month(today) return (start, end) def render_calendar(events_map, today): days = [] start, end = range_to_render(today) date = start while date <= end: days.append({ 'date': date, 'is_weekend': date.isoweekday() == 6 or date.isoweekday() == 7, 'week_of_year': int(date.strftime('%W')), 'days_from_now': (date - today).days, 'events': events_map.get(date, []), }) date += datetime.timedelta(days = 1) header = today.strftime('%B %Y') return TEMPLATE_INDEX.render(days = days, header = header) def get_events_map() -> tuple[dict[datetime.date, list[str]], datetime.date]: today = datetime.date.today() events_map = { } for prefix, url in config.ICAL_LINKS.items(): for date, event in google_calendar.get_events_for_month(url, today): text = '{}: {}'.format(prefix, event.summary) events_map.setdefault(date, []).append(text) del date, event, text return events_map, today ## Paths @bottle.route('/static/') def static(path): return bottle.static_file(path, root = './static') @bottle.route('/') def month_calendar(): events_map, today = get_events_map() return render_calendar(events_map, today) def main(): ## Argument parsing parser = argparse.ArgumentParser() parser.add_argument('--hostname', action='store', default = 'localhost', dest='hostname') parser.add_argument('--port', action='store', default = 8080, dest='port', type = int) args = parser.parse_args() # Initialization bottle.run(host=args.hostname, port=args.port) if __name__ == '__main__': main()