#!/usr/bin/env python3 """ Configurable Calendar Generator for ODS format Usage: python3 generate_calendar.py [year] [output_file] Example: python3 generate_calendar.py 2026 calendar_2026.ods """ from datetime import datetime, timedelta import zipfile import sys def create_calendar_ods(year, output_file): month_names = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] day_headers = ['M', 'T', 'W', 'T', 'F', 'S', 'S'] def get_month_calendar(year, month): """Returns list of weeks for a month, each week has 7 days (0 = empty)""" first_day = datetime(year, month, 1) first_weekday = first_day.weekday() # 0=Monday, 6=Sunday if month == 12: last_day = 31 else: last_day = (datetime(year, month + 1, 1) - timedelta(days=1)).day weeks = [] week = [0] * first_weekday for day in range(1, last_day + 1): week.append(day) if len(week) == 7: weeks.append(week) week = [] if week: week.extend([0] * (7 - len(week))) weeks.append(week) return weeks # Generate calendar for all months month_rows_xml = "" for row in range(3): start_month = row * 4 + 1 months_in_row = [start_month, start_month + 1, start_month + 2, start_month + 3] # Title row month_rows_xml += ' \n' for month in months_in_row: month_rows_xml += f' {month_names[month-1]} {year}\n' month_rows_xml += ' \n' month_rows_xml += ' \n' # Day headers month_rows_xml += ' \n' for month in months_in_row: for day_header in day_headers: month_rows_xml += f' {day_header}\n' month_rows_xml += ' \n' month_rows_xml += ' \n' # Get calendar data for all months month_cals = [get_month_calendar(year, m) for m in months_in_row] max_weeks = max(len(cal) for cal in month_cals) # Days for week_idx in range(max_weeks): month_rows_xml += ' \n' for month_idx, month in enumerate(months_in_row): if week_idx < len(month_cals[month_idx]): week = month_cals[month_idx][week_idx] for day_idx, day in enumerate(week): if day == 0: month_rows_xml += ' \n' else: # Weekend is Saturday (day_idx=5) and Sunday (day_idx=6) if day_idx >= 5: month_rows_xml += f' {day}\n' else: month_rows_xml += f' {day}\n' else: for _ in range(7): month_rows_xml += ' \n' month_rows_xml += ' \n' month_rows_xml += ' \n' month_rows_xml += ' \n' content_xml = f''' {month_rows_xml} ''' manifest_xml = ''' ''' styles_xml = ''' ''' meta_xml = f''' Calendar {year} {datetime.now().isoformat()} ''' with zipfile.ZipFile(output_file, 'w', zipfile.ZIP_DEFLATED) as ods: ods.writestr('mimetype', 'application/vnd.oasis.opendocument.spreadsheet', compress_type=zipfile.ZIP_STORED) ods.writestr('META-INF/manifest.xml', manifest_xml) ods.writestr('content.xml', content_xml) ods.writestr('styles.xml', styles_xml) ods.writestr('meta.xml', meta_xml) print(f"✓ Calendar for {year} created: {output_file}") if __name__ == "__main__": if len(sys.argv) < 2: year = int(input("Enter year: ")) output = f"calendar_{year}.ods" else: year = int(sys.argv[1]) output = sys.argv[2] if len(sys.argv) > 2 else f"calendar_{year}.ods" try: create_calendar_ods(year, output) except Exception as e: print(f"Error: {e}") sys.exit(1)