Metadata-Version: 2.4
Name: calendargen
Version: 0.1.0
Summary: Generate an iCalendar file from a TOML class schedule.
License-Expression: MIT
Project-URL: Repository, https://github.com/Harumaru169/calendargen
Project-URL: Issues, https://github.com/Harumaru169/calendargen/issues
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: icalendar
Requires-Dist: tzlocal
Provides-Extra: dev
Requires-Dist: ipython; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Dynamic: license-file

# CalendarGen

CalendarGen turns a declarative TOML schedule into an iCalendar (`.ics`) file. It is designed for events that usually happen every week, such as university lectures. Define the term dates, class times, and weekly events once; CalendarGen expands them into individual calendar events.

## Install

Requires Python 3.12 or later.

```sh
pip install calendargen
```

With [uv](https://docs.astral.sh/uv/), install the CLI as a tool:

```sh
uv tool install calendargen
```

To install from a local checkout for development, use `uv tool install --editable .`. You can also run it from this repository without a separate installation:

```sh
uv run calendargen init calendar.toml
uv run calendargen gen calendar.toml calendar.ics
```

## Usage

Create a starter schedule, edit it, and generate an ICS file:

```sh
calendargen init calendar.toml
calendargen gen calendar.toml calendar.ics
```

Import `calendar.ics` into a calendar application that supports iCalendar files. `init` creates a new file and will not overwrite an existing one.

### Updating an imported schedule

Edit `calendar.toml` and run `calendargen gen calendar.toml calendar.ics` again. Before importing the new ICS file, remove the events from the previous import in your calendar application. A distinctive `description_footer` helps you find those events; importing the new file alone may leave duplicates, depending on the application. Import the regenerated ICS file after removing the old events.

## Schedule format

```toml
term_start = 2026-10-01
term_end = 2027-01-22
excluded_dates = [2026-11-03]
description_footer = "Generated by CalendarGen (Fall 2026)"

[time_slots]
"period 2" = { start = "10:30", end = "12:00" }

[[courses]]
title = "Applied Algebra"
weekday = "mon"
time_slot = "period 2"
location = "Room 201"
description = "Professor Smith"

[[day_overrides]]
date = 2026-10-15
use_weekday = "mon"
all_day_event_title = "Monday schedule"
```

- `term_start` and `term_end` are inclusive TOML dates.
- `excluded_dates` skips all events on the listed dates. It can be omitted.
- Each `time_slots` entry defines a named local start and end time. Courses refer to these names through `time_slot`.
- Each `[[courses]]` entry defines a weekly event. `title`, `weekday`, and `time_slot` are required; `location` and `description` are optional. Weekdays are `mon`, `tue`, `wed`, `thu`, `fri`, `sat`, or `sun`.
- A `[[day_overrides]]` entry uses another weekday's course schedule on a specific date. In the example, October 15 follows the Monday schedule. Overrides are optional and cannot share a date with `excluded_dates`.
- `all_day_event_title` is an optional text field on a day override. When nonblank, it creates an additional all-day event on that date with the text as its title. Omit it on overrides that need no all-day event.
- `description_footer` is optional. When set, CalendarGen appends it after a blank line to each course description and adds it as the description of events that have none, including all-day override events. Omit it or set it to a blank string to leave descriptions unchanged. A distinctive footer makes it easier to search for and delete all generated events after importing an ICS file, so you can revise the schedule and import it again.

Unknown field names in the schedule, time slots, courses, or day overrides are errors. Dates in `excluded_dates` and `day_overrides` must fall between `term_start` and `term_end`, inclusive; out-of-range dates are also errors. CalendarGen does not create or replace the ICS file when validation fails.

Event times use the local timezone of the machine running CalendarGen. The generated ICS file contains one event for each occurrence within the term.

## License

MIT. See [LICENSE](https://github.com/Harumaru169/calendargen/blob/main/LICENSE).
