codekasten/ical_aggregator/ical_aggregator.py
lars 76fc4d77cf ical aggregator:
* ignore source lines starting with "#"
 * add alternative parser for event dates given as strings
2009-10-10 23:22:56 +00:00

120 lines
3.2 KiB
Python
Executable file

#!/usr/bin/env python
#
# vevent keys: url, uid, summary, locations, category, description
import urllib
import vobject
import sys
import os
import drupal_submit
EVENT_KEYS = ["uid", "url", "location", "categories", "summary", "description", "dtstart" , "dtend", "dtstamp"]
UNIQUE_KEY = ["dtstart", "summary"]
def get_syntax():
return "Syntax: %s ICAL_SOURCES_FILE FINISHED_FILE AUTH_FILE" % (os.path.basename(sys.argv[0]))
def get_unique_id(event):
unique_values = []
for one_val in UNIQUE_KEY:
unique_values.append(unicode(event[one_val]))
return encode_safely(";".join(unique_values))
def encode_safely(text):
return text.encode("iso-8859-15", "replace")
def convert_event_to_dict(event):
result = {}
for key in EVENT_KEYS:
# convert lists to a string
value = event.getChildValue(key)
if isinstance(value, list):
value = " ,".join(value)
result[key] = value
return result
def fetch_ical(url):
result = []
try:
handle = urllib.urlopen(url)
content = handle.read()
handle.close()
except IOError, err_msg:
sys.stderr.write("Failed to parse iCal file (%s): %s\n" % (url, err_msg))
return []
events = vobject.readComponents(content)
for top_child in events:
for child in top_child.components():
result.append(convert_event_to_dict(child))
return result
def add_to_processed_list(fileout, event):
fileout.write(get_unique_id(event) + "\n")
def submit_event_to_drupal(auth_file, event):
body = "%(description)s\n\nOrt: %(location)s\n\nKategorie: %(categories)s" % event
result = drupal_submit.submit_drupal_node(auth_file, event["summary"], body, event["dtstart"], event["dtend"])
if result:
print "Added event: %s" % encode_safely(event["summary"])
else:
print "Failed to add event: %s" % encode_safely(event["summary"])
return result
if __name__ == "__main__":
if len(sys.argv) != 4:
sys.stderr.write(get_syntax() + "\n")
sys.exit(1)
ICAL_SOURCES_FILE = sys.argv[1]
FINISHED_FILE = sys.argv[2]
AUTH_FILE = sys.argv[3]
# read the file of iCal URLs to be sourced
try:
ical_file = file(ICAL_SOURCES_FILE)
ical_urls = ical_file.read().splitlines()
ical_file.close()
except IOError, err_msg:
sys.write("Failed to open iCal source URL file (%s): %s\n" % (ICAL_SOURCES_FILE, err_msg))
sys.exit(2)
finished_items = []
# read the file of processed events
if os.path.isfile(FINISHED_FILE):
try:
finished_file = file(FINISHED_FILE)
finished_items.extend(finished_file.read().splitlines())
finished_file.close()
except IOError, err_msg:
sys.write("Failed to open file for finished items (%s) for reading: %s\n" % (FINISHED_FILE, err_msg))
sys.exit(3)
# reopen the file for appending
try:
finished_file = file(FINISHED_FILE, "a")
except IOError, err_msg:
sys.write("Failed to open file for finished items (%s) for appending: %s\n" % (FINISHED_FILE, err_msg))
sys.exit(4)
icals = []
for ical_url in ical_urls:
# ignore lines starting with "#"
if not ical_url.startswith("#"):
icals.extend(fetch_ical(ical_url))
for event in icals:
if not get_unique_id(event) in finished_items:
# process new events
if submit_event_to_drupal(AUTH_FILE, event):
add_to_processed_list(finished_file, event)
finished_items.append(get_unique_id(event))
finished_file.close()