#!/usr/bin/env python """ CHURCH CALENDAR CSV GENERATOR """ import calendar from dataclasses import dataclass from datetime import datetime from pprint import pprint import sys import click from dataclass_csv import DataclassWriter from events import EVENT_LIST, YEAR, DEBUG def debug_print(data, condition=True, end="\n"): """Conditionally print data using pprint. Args: data: The data to be printed. condition: A boolean value. If True, the data will be printed. """ if condition: print(data, end=end) """ build a list of months / weeks / day of the month in those weeks months 1-12, weeks 0-5 days of week 5 6 are the 1st and 2nd of month MONTHS[1] [0] [ 0 0 0 0 0 1 2 ] due to how months work week 0 can have null days (represented by 0's) weeks 1 - 4 will have all 7 days present week 5 may have 7 days or nulls week 6 can have a monday and/or tuesday in them if the 1st falls on a saturday or sunday in week 0 EVENT_LIST has weeks as 1-6 while MONTHS has weeks as 0-5, offsetting will be necessary """ MONTHS: dict[int, list[list[int]]] MONTHS = dict(enumerate([calendar.monthcalendar(YEAR, month) for month in range(1, 13)], start=1)) """ convert EVENT_LIST into monthly_events """ monthly_events = [[] for _ in range(7)] for event in EVENT_LIST: monthly_events[event[0]].append(event[1:]) @dataclass class Event(): """Event for CSV export""" # pylint: disable=too-many-instance-attributes event_name: str venue_name: str organizer_name: str start_date: str start_time: str end_date: str end_time: str all_day_event: str categories: str event_cost: str event_phone: str event_website: str show_map_link: str show_map: str event_description: str def suffix(day: int) -> str: """convert day to suffix""" result: str = 'th' if day in [1, 21, 31]: result = 'st' elif day in [2, 22]: result = 'nd' elif day in [3, 23]: result = 'rd' return result def sort_events(events: list[Event]) -> list[Event]: """sort events""" events = sorted(events, key=lambda k: (k.start_date, k.start_time)) return events def create_event(name: str, location: str, categories: str, description: str, start, finish) -> None: """create event""" # pylint: disable=too-many-arguments event = Event(name, location, "", start.strftime("%Y-%m-%d"), start.strftime("%I:%M %p"), finish.strftime("%Y-%m-%d"), finish.strftime("%I:%M %p"), "FALSE", categories, "", "", "", "", "", description) return event # events.append(event) def write_calendar(events: list[Event]) -> None: """write calendar to csv file""" with open("calendar.csv", "w", encoding="utf-8") as handle: writer =DataclassWriter(handle, events, Event) writer.map("event_name").to("EVENT NAME") writer.map("venue_name").to("VENUE NAME") writer.map("organizer_name").to("ORGANIZER NAME") writer.map("start_date").to("START DATE") writer.map("start_time").to("START TIME") writer.map("end_date").to("END DATE") writer.map("end_time").to("END TIME") writer.map("all_day_event").to("ALL DAY EVENT") writer.map("categories").to("CATEGORIES") writer.map("event_cost").to("EVENT COST") writer.map("event_phone").to("EVENT PHONE") writer.map("event_website").to("EVENT_WEBSITE") writer.map("show_map_link").to("SHOW MAP LINK?") writer.map("show_map").to("SHOW MAP?") writer.map("event_description").to("EVENT DESCRIPTION") writer.write() def process_day(events, year, month, day, day_events): """process all events for one day""" for event_item in day_events: start = datetime(year, month, day, event_item[0], event_item[1]) finish = datetime(year, month, day, event_item[2], event_item[3]) debug_print(f" {start:%H:%M}-{finish:%H:%M} {event_item[6]:25} {event_item[4]:11} {event_item[5]:16} {event_item[7]:70.70}", DEBUG) event = create_event(event_item[6], event_item[4], event_item[5], event_item[7], start, finish) events.append(event) return events def process_month(MONTHS, monthly_events, year, month, week_of_month, week, events): """process one MONTHS of events""" for day_of_week, day in enumerate(week): if day > 0: """ month, week_of_month, day_of_week, day use monthly_events[day_of_week] """ debug_print(f" {day_of_week}-{day:02d}", DEBUG) day_events = [x[1:] for x in monthly_events[day_of_week] if week_of_month + 1 in x[0]] events = process_day(events, year, month, day, day_events) debug_print("", DEBUG) return events def process_months(MONTHS, monthly_events, year): """process full year of MONTHS and return list of events""" events = [] for month in range(1, 13): debug_print(f"MONTH: {month}", DEBUG) for week_of_month, week in enumerate(MONTHS[month]): debug_print(f"{week_of_month} {week}", DEBUG) events = process_month(MONTHS, monthly_events, year, month, week_of_month, week, events) return events @click.command() def main(): """create csv file""" events = process_months(MONTHS, monthly_events, YEAR) events = sort_events(events) write_calendar(events) sys.exit(0) if __name__ == "__main__": main() # pylint: disable=E1120