Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add iCal event feed #64

Merged
merged 22 commits into from
Oct 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading