Permalink
Browse files

added meaningful descriptions to ical events.

url in ical events points back to events.hackerdojo.com

renamed EventsHandler to ExportHandler (because it's the function that generates rss/ical/json exported versions of the calendar)
moved some ical generating code from models.py to main.py (where it's handy when rss exports want to catch up with ical exports)
cleaned up formatting of templates/list_event.html
added link to events.json in approved.html

added dev_appserver.datastore from my /tmp directory...  let's have some decent test data, okay?
  • Loading branch information...
Stig Hackvan stig hackvan
Stig Hackvan authored and stig hackvan committed Jan 21, 2011
1 parent 86757a1 commit 841fefb91731da2f86ee3f8e711665581b920838
Showing with 56 additions and 29 deletions.
  1. +44 −13 main.py
  2. +0 −14 models.py
  3. +1 −1 templates/approved.html
  4. +11 −1 templates/list_event.html
View
57 main.py
@@ -5,7 +5,7 @@
from django.utils import simplejson
from django.template.defaultfilters import slugify
-from icalendar import Calendar
+from icalendar import Calendar, Event as CalendarEvent
import logging, urllib, os
from pprint import pprint
from datetime import datetime, timedelta
@@ -15,6 +15,7 @@
from notices import *
import PyRSS2Gen
+import re
webapp.template.register_template_library('templatefilters')
@@ -69,19 +70,45 @@ def post(self):
notify_owner_expiring(event)
-class EventsHandler(webapp.RequestHandler):
+class ExportHandler(webapp.RequestHandler):
def get(self, format):
events = Event.all().filter('status IN', ['approved', 'canceled']).order('start_time')
- if format == 'ics':
- cal = Calendar()
- for event in events:
- cal.add_component(event.to_ical())
- self.response.headers['content-type'] = 'text/calendar'
- self.response.out.write(cal.as_string())
- elif format == 'json':
+ url_base = 'http://' + self.request.headers.get('host', 'events.hackerdojo.com')
+ if format == 'json':
self.response.headers['content-type'] = 'application/json'
events = map(lambda x: x.to_dict(summarize=True), Event.get_approved_list())
self.response.out.write(simplejson.dumps(events))
+ elif format == 'ics':
+ cal = Calendar()
+ #tzinfo=pytz.timezone('US/Pacific') # FIXME -- ummm, what's up with doing all this start/end_time.replace(tzinfo) nonsense?
+ for event in events:
+ iev = CalendarEvent()
+ iev.add('summary', event.name if event.status == 'approved' else event.name + ' (%s)' % event.status.upper())
+ # make verbose description with empty fields where information is missing
+ ev_desc = '__Status: %s\n__Member: %s\n__Type: %s\n__Estimated size: %s\n__Info URL: %s\n__Fee: %s\n__Contact: %s, %s\n__Rooms: %s\n\n__Details: %s\n\n__Notes: %s' % (
+ event.status,
+ event.owner(),
+ event.type,
+ event.estimated_size,
+ event.url,
+ event.fee,
+ event.contact_name,
+ event.contact_phone,
+ event.roomlist(),
+ event.details,
+ event.notes)
+ # then delete the empty fields with a regex
+ ev_desc = re.sub(re.compile(r'^__.*?:[ ,]*$\n*',re.M),'',ev_desc)
+ ev_desc = re.sub(re.compile(r'^__',re.M),'',ev_desc)
+ iev.add('description', ev_desc)
+ iev.add('url', url_base + event_path(event))
+ if event.start_time:
+ iev.add('dtstart', event.start_time)
+ if event.end_time:
+ iev.add('dtend', event.end_time)
+ cal.add_component(iev)
+ self.response.headers['content-type'] = 'text/calendar'
+ self.response.out.write(cal.as_string())
elif format =='rss':
url_base = 'http://' + self.request.headers.get('host', 'events.hackerdojo.com')
rss = PyRSS2Gen.RSS2(
@@ -95,9 +122,8 @@ def get(self, format):
description = event.details,
guid = url_base + event_path(event),
pubDate = event.updated,
- ) for event in events]
+ ) for event in events]
)
-
self.response.headers['content-type'] = 'application/xml'
self.response.out.write(rss.to_xml())
@@ -436,20 +462,25 @@ def post(self, id):
def main():
application = webapp.WSGIApplication([
('/', ApprovedHandler),
- ('/events\.(.+)', EventsHandler),
('/all_future', AllFutureHandler),
- ('/past', PastHandler),
('/pending', PendingHandler),
+ ('/past', PastHandler),
('/cronbugowners', CronBugOwnersHandler),
('/myevents', MyEventsHandler),
('/new', NewHandler),
('/edit/(\d+).*', EditHandler),
+ # single event views
('/event/(\d+).*', EventHandler),
('/event/(\d+)\.json', EventHandler),
+ # various export methods -- events.{json,rss,ics}
+ ('/events\.(.+)', ExportHandler),
+ #
+ # CRON tasks
('/expire', ExpireCron),
('/expiring', ExpireReminderCron),
('/domaincache', DomainCacheCron),
('/reminder', ReminderCron),
+ #
('/check_conflict', CheckConflict),
('/logs', LogsHandler),
('/feedback/new/(\d+).*', FeedbackHandler) ],debug=True)
View
@@ -1,7 +1,6 @@
from google.appengine.ext import db
from google.appengine.api import urlfetch, memcache, users, mail
from datetime import datetime, timedelta
-from icalendar import Calendar, Event as CalendarEvent
from utils import human_username, local_today, to_sentence_list
import logging
import pytz
@@ -179,19 +178,6 @@ def remove_staff(self, user):
self.put()
logging.info('%s staffed %s' % (user.nickname, self.name))
- def to_ical(self):
- event = CalendarEvent()
- event.add('summary', self.name if self.status == 'approved' else self.name + ' (%s)' % self.status.upper())
- if self.details:
- event.add('description', self.details)
- if self.url:
- event.add('url', self.url)
- if self.start_time:
- event.add('dtstart', self.start_time.replace(tzinfo=pytz.timezone('US/Pacific')))
- if self.end_time:
- event.add('dtend', self.end_time.replace(tzinfo=pytz.timezone('US/Pacific')))
- return event
-
def to_dict(self, summarize=False):
d = dict()
if summarize:
View
@@ -18,7 +18,7 @@ <h4>{% ifequal events.grouper today.date %}<span style="text-decoration:underlin
<p><a href="/past" style="font-size: smaller;">&larr; Past Events</a></p>
<div style="font-size: x-small; float: right; color: gray;">{{ today }}</div>
- <p style="font-size: x-small;">Alternative formats: <a href="/events.ics">iCal</a> | <a href="/events.rss">RSS</a> | JSON</p>
+ <p style="font-size: x-small;">Alternative formats: <a href="/events.ics">iCal</a> | <a href="/events.rss">RSS</a> | <a href="/events.json">JSON</a></p>
</div>
View
@@ -1 +1,11 @@
-<tr><td width="75">{{event.start_time|date:"g:iA"|lower}}</td><td><a {% if event.is_canceled %}style="text-decoration: line-through;"{% endif %} href="/event/{{event.key.id}}-{{event.name|slugify}}">{{event.name}}</a> {% ifnotequal event.status "approved" %}<span style="color: white; font-size: x-small; padding: 2px; background: gray">{{event.status}}</span>{% endifnotequal %}{% if event.is_past %}(<a href="/feedback/new/{{event.key.id}}">Give your feedback</a>){% endif %}<div style="font-size:80%">Hosted by <a href="mailto:{{event.member.email}}">{{event.owner}}</a> {% if event.roomlist %}in {{event.roomlist}}{% endif %}</div></td></tr>
+<tr>
+ <td width="75">{{event.start_time|date:"g:iA"|lower}}</td>
+ <td>
+ <a {% if event.is_canceled %}style="text-decoration: line-through;"{% endif %} href="/event/{{event.key.id}}-{{event.name|slugify}}">
+ {{event.name}}
+ </a>
+ {% ifnotequal event.status "approved" %}<span style="color: white; font-size: x-small; padding: 2px; background: gray">{{event.status}}</span>{% endifnotequal %}
+ {% if event.is_past %}(<a href="/feedback/new/{{event.key.id}}">Give your feedback</a>){% endif %}
+ <div style="font-size:80%">Hosted by <a href="mailto:{{event.member.email}}">{{event.owner}}</a>
+ {% if event.roomlist %}in {{event.roomlist}}{% endif %}</div></td>
+</tr>

0 comments on commit 841fefb

Please sign in to comment.