#!/bin/python3
#lumbung.space calendar feed generator
#© 2021 roel roscam abbing gplv3 etc
from ics import Calendar
import requests
import jinja2
import os
import shutil
from slugify import slugify
from natural import date
from event_feed_config import calendar_url , output_dir
import arrow
cal = Calendar ( requests . get ( calendar_url ) . text )
env = jinja2 . Environment (
loader = jinja2 . FileSystemLoader ( os . path . curdir )
)
if not os . path . exists ( output_dir ) :
os . mkdir ( output_dir )
template = env . get_template ( ' event_template.md ' )
existing_posts = os . listdir ( output_dir )
def create_metadata ( event ) :
#construct a formatted dict of event metadata for in a post
event_metadata = {
' name ' : event . name ,
' created ' : event . created . format ( ) ,
' description ' : event . description ,
' localized_begin ' : ' ' . join ( localize_time ( event . begin ) ) , #non-breaking space characters to defeat markdown
' begin ' : event . begin . format ( ) ,
' end ' : event . end . format ( ) ,
' duration ' : date . compress ( event . duration ) ,
' location ' : event . location ,
' uid ' : event . uid
}
return event_metadata
def localize_time ( date ) :
# Dates need to be displayed for the various TZs
# takes arrow objects
# 3 PM Kassel, Germany, 4 PM Ramallah/Jerusalem, Palestina (QoF),
# 8 AM Bogota, Colombia (MaMa), 8 PM Jakarta, Indonesia (Gudskul),
# 1 PM (+1day) Wellington, New Zealand (Fafswag), 9 AM Havana, Cuba (Instar).
tzs = [
( ' Kassel ' , ' Europe/Berlin ' ) ,
( ' Bamako ' , ' Europe/London ' ) ,
( ' Palestine ' , ' Asia/Jerusalem ' ) ,
( ' Bogota ' , ' America/Bogota ' ) ,
( ' Jakarta ' , ' Asia/Jakarta ' ) ,
( ' Makassar ' , ' Asia/Makassar ' ) ,
( ' Wellington ' , ' Pacific/Auckland ' )
]
localized_begins = [ ]
for location , tz in tzs :
localized_begins . append ( #javascript formatting because of string creation from hell
' __ {} __ {} ' . format (
str ( location ) ,
str ( date . to ( tz ) . format ( " YYYY-MM-DD __HH:mm__ " ) )
)
)
return localized_begins
def create_event_post ( post_dir , event ) :
event_metadata = create_metadata ( event )
if not os . path . exists ( post_dir ) :
os . mkdir ( post_dir )
with open ( os . path . join ( post_dir , ' index.md ' ) , ' w ' ) as f :
post = template . render ( event = event_metadata )
f . write ( post )
print ( ' created post for ' , event . name , ' ( {} ) ' . format ( event . uid ) )
with open ( os . path . join ( post_dir , ' .timestamp ' ) , ' w ' ) as f :
f . write ( event_metadata [ ' created ' ] )
def update_event_post ( post_dir , event ) :
if os . path . exists ( post_dir ) :
old_timestamp = open ( os . path . join ( post_dir , ' .timestamp ' ) ) . read ( )
if event . created > arrow . get ( old_timestamp ) :
print ( ' Updating ' , event . name , ' ( {} ) ' . format ( event . uid ) )
create_event_post ( post_dir , event )
else :
print ( ' Event current: ' , event . name , ' ( {} ) ' . format ( event . uid ) )
for event in list ( cal . events ) :
post_dir = os . path . join ( output_dir , event . uid )
if event . uid not in existing_posts :
#if there is an event we dont already have, make it
create_event_post ( post_dir , event )
elif event . uid in existing_posts :
#if we already have it, update
update_event_post ( post_dir , event )
existing_posts . remove ( event . uid ) # create list of posts which have not been returned by the calendar
for post in existing_posts :
#remove events not returned by the calendar (deletion)
print ( ' deleted ' , post )
shutil . rmtree ( os . path . join ( output_dir , post ) )