Skip to content

πŸ“… Calendar Module

The Calendar module displays a monthly calendar along with optional upcoming events parsed from one or more iCalendar (.ics) feeds.
It is one of the most popular Inkycal modules and is fully configurable via the web-UI.

This page explains:

  • What the module does
  • How configuration works
  • How calendar rendering is performed
  • How event parsing works
  • How to debug issues with calendars
  • How to write custom ICS preprocessing logic

🧭 Overview

The Calendar module:

  • Renders a 6Γ—7 monthly grid
  • Displays weekday names in your chosen language
  • Highlights today’s date with a colored circle
  • Marks days containing events
  • Displays upcoming events below the calendar
  • Supports multiple .ics URLs or local files
  • Handles all-day events and multi-day events cleanly

πŸ“¦ Example Output

(You can later replace these mock images with actual screenshots)

+--------------------------------------------+
|                 March 2025                 |
+--------------------------------------------+
| Mon   Tue   Wed   Thu   Fri   Sat   Sun    |
|  3     4     5     6     7     8     9     |
| ...                                        |
|           [ ● 12 ]                         |
| ...                                        |
+--------------------------------------------+
| Upcoming Events:                           |
| 12 Mar – Doctor appointment 10:00          |
| 14 Mar – Anna’s Birthday                   |
| ...                                        |
+--------------------------------------------+

Today’s date is drawn with a circle and white number.
Days with events receive a border highlight.


βš™οΈ Configuration Options

These options appear in the Web-UI under module settings.

Required configuration

The Calendar module has no required parameters. It runs out-of-the-box.


Optional configuration

Key Description Type Default
week_starts_on Choose whether weeks start on Monday or Sunday "Monday", "Sunday" "Monday"
show_events Whether to show upcoming events bool True
ical_urls One or more ICS URLs (comma-separated) str None
ical_files One or more local ICS files str None
date_format Arrow format string for dates str "D MMM"
time_format Arrow format string for event times str "HH:mm"
language Locale used for month and weekday names str "en"

🧠 How Rendering Works

1️⃣ Layout allocation

The module receives a rendering area:

(width, height)

After subtracting padding, the area is split into:

  1. Month title
  2. Weekday header row
  3. Calendar grid (6 Γ— 7)
  4. Events section (only if show_events = True)

2️⃣ Drawing the calendar grid

Each day is placed in a cell:

row = week index
col = day index

Bounding boxes for all grid cells are precomputed:

grid_coordinates = [
    (grid_start_x + icon_width * x, grid_start_y + icon_height * y)
    for y in range(calendar_rows)
    for x in range(calendar_cols)
]

3️⃣ Highlighting today

A separate temporary Canvas is used to draw:

  • A circle centered in the day cell
  • The day number in white
  • Properly centered using anchor="mm"

This ensures pixel-perfect alignment across displays.


4️⃣ Marking event days

Every event is expanded into all days between start and end:

for day in arrow.Arrow.range('day', start, end):
    days_with_events.append(day.day)

All unique days then receive a rounded border.


5️⃣ Event rendering

Upcoming events (up to 4 weeks in advance) are shown below the calendar:

  • Date is drawn left-aligned
  • Time (if not all-day) is drawn next to date
  • Title fills the remaining space
  • Multi-day events display a human-readable duration:

Example:

2 days β†’ "(in 2 days)"

Line wrapping is handled by the Canvas engine.


πŸ”— Parsing iCalendar Files

The module uses:

inkycal.utils.ical_parser.iCalendar

This parser:

  • Loads .ics URLs
  • Loads local .ics files
  • Sorts events by start date
  • Normalizes timezone-aware values
  • Detects all-day events via:
parser.all_day(event)

You can pass multiple calendar URLs or files.


πŸ“˜ Full Rendering Flow

Calendar.generate_image()
    |
    +--> Compute layout regions
    +--> Create Canvas
    +--> Draw month & weekdays
    +--> Build month grid
    +--> Highlight today
    +--> Retrieve + parse ICS events
    +--> Draw event-day borders
    +--> Draw upcoming events list
    +--> Return (black_img, colour_img)

πŸ”§ Tips for Better Calendar Results

βœ” Choose readable fonts

If using languages like Chinese, Japanese, Koreanβ€”ensure CJK fonts are installed.

βœ” Ensure ICS URLs support HTTPS

Many servers block plain HTTP.

βœ” Verify timezones

If events show at wrong times: - Confirm Raspberry Pi timezone via
sudo dpkg-reconfigure tzdata - Check ICS feed timezone fields

βœ” Reduce event clutter

Use filters in your calendar service if available.


πŸ§ͺ Troubleshooting

❌ Events are missing

Checklist:

  • Does ICS feed load in the browser?
  • Are there events in the next 4 weeks? (default range)
  • Is show_events enabled?

❌ Wrong date formatting

Your locale may not support certain month abbreviations.
Try a standard format:

D MMMM
MMM DD

❌ Today circle misaligned

This usually means:

  • Canvas font height was oversized
  • Day cell height too small
  • Incorrect DPI scaling on custom displays

Try lowering font size by 10–20%.


🧩 Extending the Calendar Module

You may want to:

  • Add holiday highlights
  • Add weather integration into each day cell
  • Display week numbers
  • Replace circle highlight with a rectangle or icon

All changes should be made in:

inkycal/modules/calendar.py

And rendered using:

Canvas.write(...)
Canvas.draw_icon(...)
Canvas utilities

πŸ“„ Summary

The Calendar module is a powerful, flexible, and highly customizable component.
It makes heavy use of the Canvas abstraction to guarantee:

  • Consistent rendering
  • Alignment across displays
  • Efficient pixel usage
  • Multi-language support

It remains one of the most mature and well-tested parts of Inkycal.

If you are creating your own module, studying this one is an excellent place to start.