Skip to content

Commit

Permalink
Add iCal event feed (#64)
Browse files Browse the repository at this point in the history
* add start of ical support

* Remove ical files and add to gitignore

* Add requirements.txt for netlify

* Change build script for netlify

* Change build preview command to generate ical files

* Use python3.8 compatiable toml library for netlify

* Add events feed links to site

* fix make_event_ical

* Add calendar widget

* Update URI scheme

* Update add to ical link

* Add webcals to uri scheme

* take out the s

* Change to http for ical

* Add missing slash

* Add Google Calendar link

* Clean up widget

* Refactor

* url encode google calendar feed

* Update events.html

* Remove link from individial events

* Update mobile styles for calendar holder
  • Loading branch information
davidnuon authored Oct 12, 2024
1 parent 2834d05 commit ce630aa
Show file tree
Hide file tree
Showing 12 changed files with 129 additions and 17 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
public
result
result
*.ical
3 changes: 3 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,11 @@
zola
alejandra
python311
python311Packages.toml
python311Packages.pip
python311Packages.click
python311Packages.jsonschema
python311Packages.icalendar
act
];
};
Expand Down
4 changes: 2 additions & 2 deletions netlify.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# to have a `base` variable but you do need the `publish` and `command` variables.
base = "/"
publish = "public"
command = "zola build"
command = "zola build && python scripts/make_event_ical.py --output public/events/ content/events/20*.md"

[build.environment]
# Set the version name that you want to use and Netlify will automatically use it.
Expand All @@ -15,4 +15,4 @@ ZOLA_VERSION = "0.13.0"
# `$DEPLOY_PRIME_URL`.

[context.deploy-preview]
command = "zola build --base-url $DEPLOY_PRIME_URL"
command = "zola build --base-url $DEPLOY_PRIME_URL && python scripts/make_event_ical.py --output public/events/ content/events/20*.md"
11 changes: 11 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
attrs==23.1.0
click==8.1.7
icalendar==5.0.10
jsonschema==4.19.0
jsonschema-specifications==2023.7.1
python-dateutil==2.8.2
pytz==2023.3.post1
referencing==0.30.2
rpds-py==0.10.3
six==1.16.0
toml==0.10.2
15 changes: 15 additions & 0 deletions sass/css/components/ui-calendar-holder.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.add-to-calendar {
padding: 1em 0;
display: flex;
gap: 1em;

.button {
box-shadow: rgba(0, 0, 0, 0.2) 0px 1px 2px 0px;
}
}

@media screen and (max-width: 700px) {
.add-to-calendar {
flex-direction: column;
}
}
8 changes: 8 additions & 0 deletions sass/css/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
@import "components/ui-specialhero.scss";
@import "components/ui-frontpage-event-card.scss";
@import "components/ui-frontpage-hero-cta.scss";
@import "components/ui-calendar-holder.scss";
@import "pages/events.scss";

body, html {
Expand Down Expand Up @@ -44,4 +45,11 @@ p, ul, a, span, div {
}

footer {
}

@media screen and (max-width: 700px) {
.child-page {
box-sizing: border-box;
padding: 1em;
}
}
Binary file added scripts/__pycache__/make_event_ical.cpython-311.pyc
Binary file not shown.
63 changes: 63 additions & 0 deletions scripts/make_event_ical.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/usr/bin/env python
import icalendar
from pathlib import Path

import toml
import click

import pytz
from datetime import datetime

@click.command()
@click.argument('posts', nargs=-1)
@click.option('--output', help='Output for iCal files')
def validate_data(posts, output):
all_events = icalendar.Calendar()

for post in posts:
if '_index.md' in post:
continue

with open(post, 'r') as f:
data_content = f.read().strip()

separator = '+++'
front_matter = data_content.split(separator)[1].strip()
data = toml.loads(front_matter)

# Parse the date and times
event_date = data["extra"]["event"]["date"]
start_time_str = data["extra"]["event"]["start_time"]
stop_time_str = data["extra"]["event"]["stop_time"]

# Create datetime objects with timezone information (Assuming PST)
timezone = pytz.timezone("America/Los_Angeles")
start_datetime = timezone.localize(datetime.strptime(f"{event_date} {start_time_str}", "%Y-%m-%d %H:%M"))
stop_datetime = timezone.localize(datetime.strptime(f"{event_date} {stop_time_str}", "%Y-%m-%d %H:%M"))

# Create the calendar and event objects
cal = icalendar.Calendar()
event = icalendar.Event()

event.add("summary", data["title"])
event.add("description", data["description"])
event.add("dtstart", start_datetime)
event.add("dtend", stop_datetime)
event.add("location", f"{data['extra']['venue']['name']}, {data['extra']['venue']['address_street']}, "
f"{data['extra']['venue']['address_city']} {data['extra']['venue']['address_zip']}")
event.add("organizer", data["extra"]["organizer"])

# Add the event to the calendar
cal.add_component(event)
all_events.add_component(event)

output_path = Path(f'{output}/{event_date}/event.ics')
with open(output_path, 'wb') as f:
f.write(cal.to_ical())

with Path(f'{output}/calendar.ics').open('wb') as f:
f.write(all_events.to_ical())


if __name__ == '__main__':
validate_data()
2 changes: 1 addition & 1 deletion templates/child.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{% endblock %}

{% block body %}
<div class="container">
<div class="child-page container">
{% block content %}
{% endblock %}
</div>
Expand Down
1 change: 0 additions & 1 deletion templates/event.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
<h1 class="title is-1 my-4">
{{ page.title }}
</h1>

<div class="columns event-details">
<div class="column">
<div class="content">
Expand Down
11 changes: 10 additions & 1 deletion templates/events.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,16 @@
{% block content %}

<h1 class="title is-1 mb-3">Events</h1>

<div class="add-to-calendar">
{% set ical_feed_url = config.base_url ~ '/events/calendar.ics' %}
{% set ical_feed_url_google = ical_feed_url | replace(from='https', to='http') %}
<a href="{{ ical_feed_url }}" class="button">
📅 Download ICS Feed
</a>
<a href="https://calendar.google.com/calendar/r?cid={{ ical_feed_url_google | safe }}" class="button">
📅 Add to Google Calendar
</a>
</div>
<div class="columns">
<div class="column is-two-thirds">
<div class="is-multiline event-listing">
Expand Down
25 changes: 14 additions & 11 deletions templates/partials/events.rsvp-card.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,22 @@ <h2 class="card-header-title">Event Details</h2>
<time>
{{
date_macros::date_full(
year=date_parts[0] | int,
month=date_parts[1] | int,
day=date_parts[2] | int)
}}
<br>
{% if 'start_time' in page.extra.event %}
year=date_parts[0] | int,
month=date_parts[1] | int,
day=date_parts[2] | int)
}}
<br>
{% if 'start_time' in page.extra.event %}
{{ page.extra.event['start_time'] }}
{% endif %}
{% if 'stop_time' in page.extra.event %}
{% endif %}
{% if 'stop_time' in page.extra.event %}
- {{ page.extra.event['stop_time'] }}
{% endif %}
</time>
</div>
{% endif %}

</time>


</div>
</div>
</div>
<div class="card-content">
Expand Down

0 comments on commit ce630aa

Please sign in to comment.