Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100755 618 lines (564 sloc) 29.144 kb
8414350 @billsaysthis multiline for details and notes fields
billsaysthis authored
1 import cgi
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
2 from google.appengine.ext import webapp, db
3 from google.appengine.ext.webapp import util, template
47a7f7a @progrium basic form validation, added end time, start of notifications, some fixe...
progrium authored
4 from google.appengine.api import urlfetch, memcache, users, mail
5
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
6 from django.utils import simplejson
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
7 from django.template.defaultfilters import slugify
841fefb added meaningful descriptions to ical events.
Stig Hackvan authored
8 from icalendar import Calendar, Event as CalendarEvent
b4ea292 Handler to bug pending events
Brian Klug authored
9 import logging, urllib, os
7bdb866 Let all members staff events.
Brian Klug authored
10 from pprint import pprint
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
11 from datetime import datetime, timedelta
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
12
2ad290e @billsaysthis add logging model and obscure list view
billsaysthis authored
13 from models import Event, Feedback, HDLog, ROOM_OPTIONS, PENDING_LIFETIME
c97598b @dustball Room Conflict Detection
dustball authored
14 from utils import username, human_username, set_cookie, local_today, is_phone_valid, UserRights, dojo
81a81e1 @progrium adding errors for form validation, full notifications, and minor edits t...
progrium authored
15 from notices import *
7742592 @progrium start of maintaining form state on errors
progrium authored
16
9f06c39 @casey Added RSS for upcoming events.
casey authored
17 import PyRSS2Gen
841fefb added meaningful descriptions to ical events.
Stig Hackvan authored
18 import re
7787223 restored an inscrutible but necessary pytz tzinfo quirk to the start/end...
Stig Hackvan authored
19 import pytz
f434ff5 @dustball Send e-mails to a better place on dev
dustball authored
20
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
21 webapp.template.register_template_library('templatefilters')
22
9f06c39 @casey Added RSS for upcoming events.
casey authored
23 def event_path(event):
24 return '/event/%s-%s' % (event.key().id(), slugify(event.name))
25
219203b @dustball Cache better
dustball authored
26 class DomainCacheCron(webapp.RequestHandler):
5459516 @billsaysthis [#40] add not approved status and list view
billsaysthis authored
27 def post(self):
219203b @dustball Cache better
dustball authored
28 noop = dojo('/groups/events',force=True)
29
30
f49797a @dustball Reminders 2.0
dustball authored
31 class ReminderCron(webapp.RequestHandler):
5459516 @billsaysthis [#40] add not approved status and list view
billsaysthis authored
32 def post(self):
f49797a @dustball Reminders 2.0
dustball authored
33 self.response.out.write("REMINDERS")
34 today = local_today()
35 # remind everyone 3 days in advance they need to show up
36 events = Event.all() \
37 .filter('status IN', ['approved']) \
38 .filter('reminded =', False) \
39 .filter('start_time <', today + timedelta(days=3))
5459516 @billsaysthis [#40] add not approved status and list view
billsaysthis authored
40 for event in events:
f49797a @dustball Reminders 2.0
dustball authored
41 self.response.out.write(event.name)
42 # only mail them if they created the event 2+ days ago
43 if event.created < today - timedelta(days=2):
44 schedule_reminder_email(event)
45 event.reminded = True
46 event.put()
47
48
e2b9558 @btubbs Fixes issue 4. Changed to jqueryUI datepicker. Replaced jquery
btubbs authored
49 class ExpireCron(webapp.RequestHandler):
47a7f7a @progrium basic form validation, added end time, start of notifications, some fixe...
progrium authored
50 def post(self):
51 # Expire events marked to expire today
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
52 today = local_today()
47a7f7a @progrium basic form validation, added end time, start of notifications, some fixe...
progrium authored
53 events = Event.all() \
54 .filter('status IN', ['pending', 'understaffed']) \
55 .filter('expired >=', today) \
56 .filter('expired <', today + timedelta(days=1))
57 for event in events:
58 event.expire()
59 notify_owner_expired(event)
5459516 @billsaysthis [#40] add not approved status and list view
billsaysthis authored
60
f1997e4 @christopherb Made misc style fixes
christopherb authored
61
47a7f7a @progrium basic form validation, added end time, start of notifications, some fixe...
progrium authored
62 class ExpireReminderCron(webapp.RequestHandler):
63 def post(self):
64 # Find events expiring in 10 days to warn owner
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
65 ten_days = local_today() + timedelta(days=10)
47a7f7a @progrium basic form validation, added end time, start of notifications, some fixe...
progrium authored
66 events = Event.all() \
67 .filter('status IN', ['pending', 'understaffed']) \
68 .filter('expired >=', ten_days) \
69 .filter('expired <', ten_days + timedelta(days=1))
70 for event in events:
71 notify_owner_expiring(event)
72
841fefb added meaningful descriptions to ical events.
Stig Hackvan authored
73 class ExportHandler(webapp.RequestHandler):
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
74 def get(self, format):
9c331d0 @progrium refactoring the export handler a bit
progrium authored
75 content_type, body = getattr(self, 'export_%s' % format)()
76 self.response.headers['content-type'] = content_type
77 self.response.out.write(body)
5459516 @billsaysthis [#40] add not approved status and list view
billsaysthis authored
78
9c331d0 @progrium refactoring the export handler a bit
progrium authored
79 def export_json(self):
20a578c @dustball Reasonable limits
dustball authored
80 events = Event.get_recent_past_and_future()
9c331d0 @progrium refactoring the export handler a bit
progrium authored
81 for k in self.request.GET:
82 if self.request.GET[k] and k in ['member']:
83 value = users.User(urllib.unquote(self.request.GET[k]))
84 else:
85 value = urllib.unquote(self.request.GET[k])
86 events = events.filter('%s =' % k, value)
87 events = map(lambda x: x.to_dict(summarize=True), events)
88 return 'application/json', simplejson.dumps(events)
5459516 @billsaysthis [#40] add not approved status and list view
billsaysthis authored
89
9c331d0 @progrium refactoring the export handler a bit
progrium authored
90 def export_ics(self):
20a578c @dustball Reasonable limits
dustball authored
91 events = Event.get_recent_past_and_future()
841fefb added meaningful descriptions to ical events.
Stig Hackvan authored
92 url_base = 'http://' + self.request.headers.get('host', 'events.hackerdojo.com')
9c331d0 @progrium refactoring the export handler a bit
progrium authored
93 cal = Calendar()
94 for event in events:
95 iev = CalendarEvent()
96 iev.add('summary', event.name if event.status == 'approved' else event.name + ' (%s)' % event.status.upper())
97 # make verbose description with empty fields where information is missing
98 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' % (
5459516 @billsaysthis [#40] add not approved status and list view
billsaysthis authored
99 event.status,
100 event.owner(),
101 event.type,
102 event.estimated_size,
103 event.url,
104 event.fee,
105 event.contact_name,
106 event.contact_phone,
107 event.roomlist(),
108 event.details,
9c331d0 @progrium refactoring the export handler a bit
progrium authored
109 event.notes)
110 # then delete the empty fields with a regex
111 ev_desc = re.sub(re.compile(r'^__.*?:[ ,]*$\n*',re.M),'',ev_desc)
112 ev_desc = re.sub(re.compile(r'^__',re.M),'',ev_desc)
113 ev_url = url_base + event_path(event)
114 iev.add('description', ev_desc + '\n--\n' + ev_url)
115 iev.add('url', ev_url)
116 if event.start_time:
117 iev.add('dtstart', event.start_time.replace(tzinfo=pytz.timezone('US/Pacific')))
118 if event.end_time:
119 iev.add('dtend', event.end_time.replace(tzinfo=pytz.timezone('US/Pacific')))
120 cal.add_component(iev)
121 return 'text/calendar', cal.as_string()
85d17af @dustball "Large Events" page and iCal feed
dustball authored
122
123 def export_large_ics(self):
20a578c @dustball Reasonable limits
dustball authored
124 events = Event.get_recent_past_and_future()
85d17af @dustball "Large Events" page and iCal feed
dustball authored
125 url_base = 'http://' + self.request.headers.get('host', 'events.hackerdojo.com')
126 cal = Calendar()
127 for event in events:
128 iev = CalendarEvent()
129 iev.add('summary', event.name + ' (%s)' % event.estimated_size)
130 # make verbose description with empty fields where information is missing
131 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' % (
5459516 @billsaysthis [#40] add not approved status and list view
billsaysthis authored
132 event.status,
133 event.owner(),
134 event.type,
135 event.estimated_size,
136 event.url,
137 event.fee,
138 event.contact_name,
139 event.contact_phone,
140 event.roomlist(),
141 event.details,
85d17af @dustball "Large Events" page and iCal feed
dustball authored
142 event.notes)
143 # then delete the empty fields with a regex
144 ev_desc = re.sub(re.compile(r'^__.*?:[ ,]*$\n*',re.M),'',ev_desc)
145 ev_desc = re.sub(re.compile(r'^__',re.M),'',ev_desc)
146 ev_url = url_base + event_path(event)
147 iev.add('description', ev_desc + '\n--\n' + ev_url)
148 iev.add('url', ev_url)
149 if event.start_time:
150 iev.add('dtstart', event.start_time.replace(tzinfo=pytz.timezone('US/Pacific')))
151 if event.end_time:
152 iev.add('dtend', event.end_time.replace(tzinfo=pytz.timezone('US/Pacific')))
153 cal.add_component(iev)
154 return 'text/calendar', cal.as_string()
5459516 @billsaysthis [#40] add not approved status and list view
billsaysthis authored
155
9c331d0 @progrium refactoring the export handler a bit
progrium authored
156 def export_rss(self):
157 url_base = 'http://' + self.request.headers.get('host', 'events.hackerdojo.com')
20a578c @dustball Reasonable limits
dustball authored
158 events = Event.get_recent_past_and_future()
9c331d0 @progrium refactoring the export handler a bit
progrium authored
159 rss = PyRSS2Gen.RSS2(
160 title = "Hacker Dojo Events Feed",
161 link = url_base,
162 description = "Upcoming events at the Hacker Dojo in Mountain View, CA",
163 lastBuildDate = datetime.now(),
164 items = [PyRSS2Gen.RSSItem(
15786c3 @mikeharris100 Include event date on RSS feed (Fixes #39)
mikeharris100 authored
165 title = "%s @ %s: %s" % (
166 event.start_time.strftime("%A, %B %d"),
167 event.start_time.strftime("%I:%M%p").lstrip("0"),
168 event.name),
9c331d0 @progrium refactoring the export handler a bit
progrium authored
169 link = url_base + event_path(event),
170 description = event.details,
171 guid = url_base + event_path(event),
172 pubDate = event.updated,
173 ) for event in events]
174 )
175 return 'application/xml', rss.to_xml()
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
176
f1997e4 @christopherb Made misc style fixes
christopherb authored
177
ca8c7f2 @dustball Let edit events and refactor error handling
dustball authored
178 class EditHandler(webapp.RequestHandler):
179 def get(self, id):
180 event = Event.get_by_id(int(id))
181 user = users.get_current_user()
736390e @dustball Bug fixes & UI
dustball authored
182 show_all_nav = user
ca8c7f2 @dustball Let edit events and refactor error handling
dustball authored
183 access_rights = UserRights(user, event)
184 if access_rights.can_edit:
5459516 @billsaysthis [#40] add not approved status and list view
billsaysthis authored
185 logout_url = users.create_logout_url('/')
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
186 rooms = ROOM_OPTIONS
187 hours = [1,2,3,4,5,6,7,8,9,10,11,12]
188 self.response.out.write(template.render('templates/edit.html', locals()))
ca8c7f2 @dustball Let edit events and refactor error handling
dustball authored
189 else:
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
190 self.response.out.write("Access denied")
ca8c7f2 @dustball Let edit events and refactor error handling
dustball authored
191
192 def post(self, id):
193 event = Event.get_by_id(int(id))
194 user = users.get_current_user()
195 access_rights = UserRights(user, event)
196 if access_rights.can_edit:
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
197 try:
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
198 start_time = datetime.strptime('%s %s:%s %s' % (
c6a3cce @mikeharris100 (For #12) Added basic ability to add/edit/view end *date* of an event
mikeharris100 authored
199 self.request.get('start_date'),
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
200 self.request.get('start_time_hour'),
201 self.request.get('start_time_minute'),
202 self.request.get('start_time_ampm')), '%m/%d/%Y %I:%M %p')
203 end_time = datetime.strptime('%s %s:%s %s' % (
c6a3cce @mikeharris100 (For #12) Added basic ability to add/edit/view end *date* of an event
mikeharris100 authored
204 self.request.get('end_date'),
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
205 self.request.get('end_time_hour'),
206 self.request.get('end_time_minute'),
207 self.request.get('end_time_ampm')), '%m/%d/%Y %I:%M %p')
20c252d @dustball Fix key/index bug
dustball authored
208 conflicts = Event.check_conflict(start_time,end_time,self.request.get_all('rooms'), int(id))
c97598b @dustball Room Conflict Detection
dustball authored
209 if conflicts:
81f76e6 @dustball Better error message for deck/savannah conflicts
dustball authored
210 if "Deck" in self.request.get_all('rooms') or "Savanna" in self.request.get_all('rooms'):
211 raise ValueError('Room conflict detected <small>(Note: Deck &amp; Savanna share the same area, two events cannot take place at the same time in these rooms.)</small>')
212 else:
213 raise ValueError('Room conflict detected')
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
214 if not self.request.get('estimated_size').isdigit():
215 raise ValueError('Estimated number of people must be a number')
216 if not int(self.request.get('estimated_size')) > 0:
217 raise ValueError('Estimated number of people must be greater then zero')
c2c3fbb @dustball Enforce 49 limit partially
dustball authored
218 if int(self.request.get('estimated_size')) > 47:
219 raise ValueError('Hacker Dojo temporarily is under order of the City of Mountain View to not allow assemblies larger than 49 persons. Sorry, your event exceeds this size. <p>NOTE: Lying about the event size to get around this restriction will result in membership ban plus possible legal action. We will be fined $1500 for each violation, which will be passed on to the event host.')
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
220 if ( self.request.get( 'contact_phone' ) and not is_phone_valid( self.request.get( 'contact_phone' ) ) ):
221 raise ValueError( 'Phone number does not appear to be valid' )
222 else:
b193624 much nicer event edit logs
jonathan authored
223 log_desc = "Event edited<br />"
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
224 previous_object = Event.get_by_id(int(id))
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
225 event.name = self.request.get('name')
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
226 if (previous_object.name != event.name):
a4f9ae7 changed my mind about the italics
jonathan authored
227 log_desc = log_desc + "<strong>Title:</strong> " + previous_object.name + " to " + event.name + "<br />"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
228 event.start_time = start_time
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
229 if (previous_object.start_time != event.start_time):
a4f9ae7 changed my mind about the italics
jonathan authored
230 log_desc = log_desc + "<strong>Start time:</strong> " + str(previous_object.start_time) + " to " + str(event.start_time) + "<br />"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
231 event.end_time = end_time
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
232 if (previous_object.end_time != event.end_time):
a4f9ae7 changed my mind about the italics
jonathan authored
233 log_desc = log_desc + "<strong>End time:</strong> " + str(previous_object.end_time) + " to " + str(event.end_time) + "<br />"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
234 event.estimated_size = cgi.escape(self.request.get('estimated_size'))
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
235 if (previous_object.estimated_size != event.estimated_size):
a4f9ae7 changed my mind about the italics
jonathan authored
236 log_desc = log_desc + "<strong>Est. size:</strong> " + previous_object.estimated_size + " to " + event.estimated_size + "<br />"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
237 event.contact_name = cgi.escape(self.request.get('contact_name'))
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
238 if (previous_object.contact_name != event.contact_name):
a4f9ae7 changed my mind about the italics
jonathan authored
239 log_desc = log_desc + "<strong>Contact:</strong> " + previous_object.contact_name + " to " + event.contact_name + "<br />"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
240 event.contact_phone = cgi.escape(self.request.get('contact_phone'))
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
241 if (previous_object.contact_phone != event.contact_phone):
a4f9ae7 changed my mind about the italics
jonathan authored
242 log_desc = log_desc + "<strong>Contact phone:</strong> " + previous_object.contact_phone + " to " + event.contact_phone + "<br />"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
243 event.details = cgi.escape(self.request.get('details'))
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
244 if (previous_object.details != event.details):
a4f9ae7 changed my mind about the italics
jonathan authored
245 log_desc = log_desc + "<strong>Details:</strong> " + previous_object.details + " to " + event.details + "<br />"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
246 event.url = cgi.escape(self.request.get('url'))
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
247 if (previous_object.url != event.url):
a4f9ae7 changed my mind about the italics
jonathan authored
248 log_desc = log_desc + "<strong>Url:</strong> " + previous_object.url + " to " + event.url + "<br />"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
249 event.fee = cgi.escape(self.request.get('fee'))
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
250 if (previous_object.fee != event.fee):
a4f9ae7 changed my mind about the italics
jonathan authored
251 log_desc = log_desc + "<strong>Fee:</strong> " + previous_object.fee + " to " + event.fee + "<br />"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
252 event.notes = cgi.escape(self.request.get('notes'))
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
253 if (previous_object.notes != event.notes):
a4f9ae7 changed my mind about the italics
jonathan authored
254 log_desc = log_desc + "<strong>Notes:</strong> " + previous_object.notes + " to " + event.notes + "<br />"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
255 event.rooms = self.request.get_all('rooms')
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
256 if (previous_object.rooms != event.rooms):
6199d1a issue 11 print this page for your record
jonathan authored
257 log_desc = log_desc + "<strong>Rooms changed</strong><br />"
f35ea58 patches requested to log
jonathan authored
258 log_desc = log_desc + "<strong>Old room:</strong> " + previous_object.roomlist() + "<br />"
259 log_desc = log_desc + "<strong>New room:</strong> " + event.roomlist() + "<br />"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
260 event.put()
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
261 log = HDLog(event=event,description=log_desc)
2ad290e @billsaysthis add logging model and obscure list view
billsaysthis authored
262 log.put()
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
263 self.redirect(event_path(event))
2ad290e @billsaysthis add logging model and obscure list view
billsaysthis authored
264 except ValueError, e:
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
265 error = str(e)
266 self.response.out.write(template.render('templates/error.html', locals()))
ca8c7f2 @dustball Let edit events and refactor error handling
dustball authored
267 else:
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
268 self.response.out.write("Access denied")
ca8c7f2 @dustball Let edit events and refactor error handling
dustball authored
269
270
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
271 class EventHandler(webapp.RequestHandler):
272 def get(self, id):
5459516 @billsaysthis [#40] add not approved status and list view
billsaysthis authored
273
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
274 event = Event.get_by_id(int(id))
2e08a66 @progrium cleaning things up and adding json representations for jon
progrium authored
275 if self.request.path.endswith('json'):
276 self.response.headers['content-type'] = 'application/json'
277 self.response.out.write(simplejson.dumps(event.to_dict()))
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
278 else:
2e08a66 @progrium cleaning things up and adding json representations for jon
progrium authored
279 user = users.get_current_user()
280 if user:
766e87c @christopherb Added UserRights class.
christopherb authored
281 access_rights = UserRights(user, event)
2e08a66 @progrium cleaning things up and adding json representations for jon
progrium authored
282 logout_url = users.create_logout_url('/')
5459516 @billsaysthis [#40] add not approved status and list view
billsaysthis authored
283
2e08a66 @progrium cleaning things up and adding json representations for jon
progrium authored
284 else:
285 login_url = users.create_login_url('/')
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
286 event.details = db.Text(event.details.replace('\n','<br/>'))
736390e @dustball Bug fixes & UI
dustball authored
287 show_all_nav = user
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
288 event.notes = db.Text(event.notes.replace('\n','<br/>'))
2e08a66 @progrium cleaning things up and adding json representations for jon
progrium authored
289 self.response.out.write(template.render('templates/event.html', locals()))
e2b9558 @btubbs Fixes issue 4. Changed to jqueryUI datepicker. Replaced jquery
btubbs authored
290
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
291 def post(self, id):
292 event = Event.get_by_id(int(id))
293 user = users.get_current_user()
766e87c @christopherb Added UserRights class.
christopherb authored
294 access_rights = UserRights(user, event)
295
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
296 state = self.request.get('state')
297 if state:
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
298 desc = ''
766e87c @christopherb Added UserRights class.
christopherb authored
299 if state.lower() == 'approve' and access_rights.can_approve:
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
300 event.approve()
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
301 desc = 'Approved event'
5459516 @billsaysthis [#40] add not approved status and list view
billsaysthis authored
302 if state.lower() == 'notapproved' and access_rights.can_not_approve:
303 event.not_approved()
304 desc = 'Event marked not approved'
5ef05d9 @dustball RSVP system
dustball authored
305 if state.lower() == 'rsvp' and user:
306 event.rsvp()
134bb40 @dustball New RSVP e-mail and fix issue #35
dustball authored
307 notify_owner_rsvp(event,user)
b84b533 @dustball Fix one more staff logic bomb
dustball authored
308 if state.lower() == 'staff' and access_rights.can_staff:
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
309 event.add_staff(user)
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
310 desc = 'Added self as staff'
766e87c @christopherb Added UserRights class.
christopherb authored
311 if state.lower() == 'unstaff' and access_rights.can_unstaff:
72849c2 @billsaysthis added unstaff event, including email notification if event becomes under...
billsaysthis authored
312 event.remove_staff(user)
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
313 desc = 'Removed self as staff'
f8ffd89 @billsaysthis refactor lists to use singe event partial, adds contact email link in he...
billsaysthis authored
314 if state.lower() == 'onhold' and access_rights.can_cancel:
315 event.on_hold()
316 desc = 'Put event on hold'
766e87c @christopherb Added UserRights class.
christopherb authored
317 if state.lower() == 'cancel' and access_rights.can_cancel:
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
318 event.cancel()
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
319 desc = 'Cancelled event'
766e87c @christopherb Added UserRights class.
christopherb authored
320 if state.lower() == 'delete' and access_rights.is_admin:
a67ac50 @mdhancher Add a simple admin-only event delete and undelete.
mdhancher authored
321 event.delete()
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
322 desc = 'Deleted event'
766e87c @christopherb Added UserRights class.
christopherb authored
323 if state.lower() == 'undelete' and access_rights.is_admin:
a67ac50 @mdhancher Add a simple admin-only event delete and undelete.
mdhancher authored
324 event.undelete()
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
325 desc = 'Undeleted event'
766e87c @christopherb Added UserRights class.
christopherb authored
326 if state.lower() == 'expire' and access_rights.is_admin:
47a7f7a @progrium basic form validation, added end time, start of notifications, some fixe...
progrium authored
327 event.expire()
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
328 desc = 'Expired event'
134bb40 @dustball New RSVP e-mail and fix issue #35
dustball authored
329 if event.status == 'approved' and state.lower() == 'approve':
47a7f7a @progrium basic form validation, added end time, start of notifications, some fixe...
progrium authored
330 notify_owner_approved(event)
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
331 if desc != '':
332 log = HDLog(event=event,description=desc)
333 log.put()
9f06c39 @casey Added RSS for upcoming events.
casey authored
334 self.redirect(event_path(event))
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
335
f1997e4 @christopherb Made misc style fixes
christopherb authored
336
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
337 class ApprovedHandler(webapp.RequestHandler):
338 def get(self):
339 user = users.get_current_user()
340 if user:
341 logout_url = users.create_logout_url('/')
342 else:
343 login_url = users.create_login_url('/')
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
344 today = local_today()
736390e @dustball Bug fixes & UI
dustball authored
345 show_all_nav = user
411c89f @mikeharris100 (For #12) Show every day of multiple day events
mikeharris100 authored
346 events = Event.get_approved_list_with_multiday()
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
347 tomorrow = today + timedelta(days=1)
d63161a Add widget mode
Brian Klug authored
348 whichbase = 'base.html'
349 if self.request.get('base'):
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
350 whichbase = self.request.get('base') + '.html'
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
351 self.response.out.write(template.render('templates/approved.html', locals()))
352
f1997e4 @christopherb Made misc style fixes
christopherb authored
353
a82b43e @billsaysthis add myevents, pastevents code, refined list display on event page
billsaysthis authored
354 class MyEventsHandler(webapp.RequestHandler):
355 @util.login_required
356 def get(self):
357 user = users.get_current_user()
358 if user:
359 logout_url = users.create_logout_url('/')
360 else:
361 login_url = users.create_login_url('/')
362 events = Event.all().filter('member = ', user).order('start_time')
736390e @dustball Bug fixes & UI
dustball authored
363 show_all_nav = user
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
364 today = local_today()
a82b43e @billsaysthis add myevents, pastevents code, refined list display on event page
billsaysthis authored
365 tomorrow = today + timedelta(days=1)
366 self.response.out.write(template.render('templates/myevents.html', locals()))
367
f1997e4 @christopherb Made misc style fixes
christopherb authored
368
a82b43e @billsaysthis add myevents, pastevents code, refined list display on event page
billsaysthis authored
369 class PastHandler(webapp.RequestHandler):
370 def get(self):
371 user = users.get_current_user()
372 if user:
373 logout_url = users.create_logout_url('/')
374 else:
375 login_url = users.create_login_url('/')
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
376 today = local_today()
736390e @dustball Bug fixes & UI
dustball authored
377 show_all_nav = user
d75579f @progrium minor updates here and there to bills contributions.
progrium authored
378 events = Event.all().filter('start_time < ', today).order('-start_time')
a82b43e @billsaysthis add myevents, pastevents code, refined list display on event page
billsaysthis authored
379 self.response.out.write(template.render('templates/past.html', locals()))
380
f1997e4 @christopherb Made misc style fixes
christopherb authored
381
5459516 @billsaysthis [#40] add not approved status and list view
billsaysthis authored
382 class NotApprovedHandler(webapp.RequestHandler):
383 def get(self):
384 user = users.get_current_user()
385 if user:
386 logout_url = users.create_logout_url('/')
387 else:
388 login_url = users.create_login_url('/')
389 today = local_today()
390 show_all_nav = user
391 events = Event.get_recent_not_approved_list()
392 self.response.out.write(template.render('templates/not_approved.html', locals()))
393
394
b4ea292 Handler to bug pending events
Brian Klug authored
395 class CronBugOwnersHandler(webapp.RequestHandler):
396 def get(self):
397 events = Event.get_pending_list()
398 for e in events:
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
399 bug_owner_pending(e)
400
401
402 class AllFutureHandler(webapp.RequestHandler):
403 def get(self):
404 user = users.get_current_user()
405 if user:
406 logout_url = users.create_logout_url('/')
407 else:
408 login_url = users.create_login_url('/')
736390e @dustball Bug fixes & UI
dustball authored
409 show_all_nav = user
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
410 events = Event.get_all_future_list()
411 today = local_today()
412 tomorrow = today + timedelta(days=1)
413 self.response.out.write(template.render('templates/all_future.html', locals()))
b4ea292 Handler to bug pending events
Brian Klug authored
414
85d17af @dustball "Large Events" page and iCal feed
dustball authored
415 class LargeHandler(webapp.RequestHandler):
416 def get(self):
417 user = users.get_current_user()
418 if user:
419 logout_url = users.create_logout_url('/')
420 else:
421 login_url = users.create_login_url('/')
422 show_all_nav = user
423 events = Event.get_large_list()
424 today = local_today()
425 tomorrow = today + timedelta(days=1)
426 self.response.out.write(template.render('templates/large.html', locals()))
427
f1997e4 @christopherb Made misc style fixes
christopherb authored
428
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
429 class PendingHandler(webapp.RequestHandler):
430 def get(self):
431 user = users.get_current_user()
432 if user:
433 logout_url = users.create_logout_url('/')
434 else:
435 login_url = users.create_login_url('/')
47a7f7a @progrium basic form validation, added end time, start of notifications, some fixe...
progrium authored
436 events = Event.get_pending_list()
736390e @dustball Bug fixes & UI
dustball authored
437 show_all_nav = user
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
438 today = local_today()
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
439 tomorrow = today + timedelta(days=1)
440 self.response.out.write(template.render('templates/pending.html', locals()))
441
f1997e4 @christopherb Made misc style fixes
christopherb authored
442
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
443 class NewHandler(webapp.RequestHandler):
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
444 @util.login_required
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
445 def get(self):
446 user = users.get_current_user()
4d85afa @dustball Remove staffing requirement and make members more responsible
dustball authored
447 human = human_username(user)
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
448 if user:
449 logout_url = users.create_logout_url('/')
450 else:
451 login_url = users.create_login_url('/')
452 rooms = ROOM_OPTIONS
cb7a9d1 pull in the rules live and memcache them for 1 day on new and confirm ac...
jonathan authored
453 rules = memcache.get("rules")
454 if(rules is None):
f434ff5 @dustball Send e-mails to a better place on dev
dustball authored
455 try:
456 rules = urlfetch.fetch("http://wiki.hackerdojo.com/api_v2/op/GetPage/page/Event+Policies/_type/html", "GET").content
457 memcache.add("rules", rules, 86400)
458 except Exception, e:
459 rules = "Error fetching rules. Please report this error to internal-dev@hackerdojo.com."
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
460 self.response.out.write(template.render('templates/new.html', locals()))
e2b9558 @btubbs Fixes issue 4. Changed to jqueryUI datepicker. Replaced jquery
btubbs authored
461
f1997e4 @christopherb Made misc style fixes
christopherb authored
462
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
463 def post(self):
464 user = users.get_current_user()
7742592 @progrium start of maintaining form state on errors
progrium authored
465 try:
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
466 start_time = datetime.strptime('%s %s:%s %s' % (
c6a3cce @mikeharris100 (For #12) Added basic ability to add/edit/view end *date* of an event
mikeharris100 authored
467 self.request.get('start_date'),
7742592 @progrium start of maintaining form state on errors
progrium authored
468 self.request.get('start_time_hour'),
469 self.request.get('start_time_minute'),
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
470 self.request.get('start_time_ampm')), '%m/%d/%Y %I:%M %p')
471 end_time = datetime.strptime('%s %s:%s %s' % (
c6a3cce @mikeharris100 (For #12) Added basic ability to add/edit/view end *date* of an event
mikeharris100 authored
472 self.request.get('end_date'),
7742592 @progrium start of maintaining form state on errors
progrium authored
473 self.request.get('end_time_hour'),
474 self.request.get('end_time_minute'),
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
475 self.request.get('end_time_ampm')), '%m/%d/%Y %I:%M %p')
c97598b @dustball Room Conflict Detection
dustball authored
476 conflicts = Event.check_conflict(start_time,end_time,self.request.get_all('rooms'))
477 if conflicts:
81f76e6 @dustball Better error message for deck/savannah conflicts
dustball authored
478 if "Deck" in self.request.get_all('rooms') or "Savanna" in self.request.get_all('rooms'):
479 raise ValueError('Room conflict detected <small>(Note: Deck &amp; Savanna share the same area, two events cannot take place at the same time in these rooms.)</small>')
480 else:
481 raise ValueError('Room conflict detected')
8615877 Fix validation for event size
Brian Klug authored
482 if not self.request.get('estimated_size').isdigit():
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
483 raise ValueError('Estimated number of people must be a number')
8615877 Fix validation for event size
Brian Klug authored
484 if not int(self.request.get('estimated_size')) > 0:
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
485 raise ValueError('Estimated number of people must be greater then zero')
c2c3fbb @dustball Enforce 49 limit partially
dustball authored
486 if int(self.request.get('estimated_size')) > 47:
487 raise ValueError('Hacker Dojo temporarily is under order of the City of Mountain View to not allow assemblies larger than 49 persons. Sorry, your event exceeds this size. <p>NOTE: Lying about the event size to get around this restriction will result in membership ban plus possible legal action. We will be fined $1500 for each violation, which will be passed on to the event host.')
7742592 @progrium start of maintaining form state on errors
progrium authored
488 if (end_time-start_time).days < 0:
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
489 raise ValueError('End time must be after start time')
a244c65 @dustball Bug fixes
dustball authored
490 if ( self.request.get( 'contact_phone' ) and not is_phone_valid( self.request.get( 'contact_phone' ) ) ):
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
491 raise ValueError( 'Phone number does not appear to be valid' )
7742592 @progrium start of maintaining form state on errors
progrium authored
492 else:
493 event = Event(
ca3c6dd Escaped additional fields that could be used for XSS
Christopher Biettchert authored
494 name = cgi.escape(self.request.get('name')),
7742592 @progrium start of maintaining form state on errors
progrium authored
495 start_time = start_time,
496 end_time = end_time,
ca3c6dd Escaped additional fields that could be used for XSS
Christopher Biettchert authored
497 type = cgi.escape(self.request.get('type')),
498 estimated_size = cgi.escape(self.request.get('estimated_size')),
499 contact_name = cgi.escape(self.request.get('contact_name')),
500 contact_phone = cgi.escape(self.request.get('contact_phone')),
8414350 @billsaysthis multiline for details and notes fields
billsaysthis authored
501 details = cgi.escape(self.request.get('details')),
ca3c6dd Escaped additional fields that could be used for XSS
Christopher Biettchert authored
502 url = cgi.escape(self.request.get('url')),
503 fee = cgi.escape(self.request.get('fee')),
8414350 @billsaysthis multiline for details and notes fields
billsaysthis authored
504 notes = cgi.escape(self.request.get('notes')),
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
505 rooms = self.request.get_all('rooms'),
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
506 expired = local_today() + timedelta(days=PENDING_LIFETIME), # Set expected expiration date
7742592 @progrium start of maintaining form state on errors
progrium authored
507 )
508 event.put()
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
509 log = HDLog(event=event,description="Created new event")
510 log.put()
7742592 @progrium start of maintaining form state on errors
progrium authored
511 notify_owner_confirmation(event)
512 notify_new_event(event)
81a81e1 @progrium adding errors for form validation, full notifications, and minor edits t...
progrium authored
513 set_cookie(self.response.headers, 'formvalues', None)
87868cf issue 11 add a confirmation page
jonathan authored
514 #self.redirect('/event/%s-%s' % (event.key().id(), slugify(event.name)))
515 self.redirect('/confirm/%s-%s' % (event.key().id(), slugify(event.name)))
5459516 @billsaysthis [#40] add not approved status and list view
billsaysthis authored
516
81a81e1 @progrium adding errors for form validation, full notifications, and minor edits t...
progrium authored
517 except Exception, e:
518 message = str(e)
519 if 'match format' in message:
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
520 message = 'Date is required.'
81a81e1 @progrium adding errors for form validation, full notifications, and minor edits t...
progrium authored
521 if message.startswith('Property'):
522 message = message[9:].replace('_', ' ').capitalize()
ca8c7f2 @dustball Let edit events and refactor error handling
dustball authored
523 # This is NOT a reliable way to handle erorrs
524 #set_cookie(self.response.headers, 'formerror', message)
525 #set_cookie(self.response.headers, 'formvalues', dict(self.request.POST))
526 #self.redirect('/new')
527 error = message
528 self.response.out.write(template.render('templates/error.html', locals()))
87868cf issue 11 add a confirmation page
jonathan authored
529
530 class ConfirmationHandler(webapp.RequestHandler):
531 def get(self, id):
532 event = Event.get_by_id(int(id))
cb7a9d1 pull in the rules live and memcache them for 1 day on new and confirm ac...
jonathan authored
533 rules = memcache.get("rules")
534 if(rules is None):
f434ff5 @dustball Send e-mails to a better place on dev
dustball authored
535 try:
536 rules = urlfetch.fetch("http://wiki.hackerdojo.com/api_v2/op/GetPage/page/Event+Policies/_type/html", "GET").content
537 memcache.add("rules", rules, 86400)
538 except Exception, e:
539 rules = "Error fetching rules. Please report this error to internal-dev@hackerdojo.com."
b47158d Issue 36 Need to use deffered mail sends everywhere
Abraham Erki authored
540 user = users.get_current_user()
541 logout_url = users.create_logout_url('/')
87868cf issue 11 add a confirmation page
jonathan authored
542 self.response.out.write(template.render('templates/confirmation.html', locals()))
543
2ad290e @billsaysthis add logging model and obscure list view
billsaysthis authored
544 class LogsHandler(webapp.RequestHandler):
545 @util.login_required
546 def get(self):
547 user = users.get_current_user()
548 logs = HDLog.get_logs_list()
549 if user:
550 logout_url = users.create_logout_url('/')
551 else:
552 login_url = users.create_login_url('/')
736390e @dustball Bug fixes & UI
dustball authored
553 show_all_nav = user
2ad290e @billsaysthis add logging model and obscure list view
billsaysthis authored
554 self.response.out.write(template.render('templates/logs.html', locals()))
555
d2c3dc7 @billsaysthis moved app-specific js to separate file
billsaysthis authored
556 class FeedbackHandler(webapp.RequestHandler):
557 @util.login_required
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
558 def get(self, id):
d2c3dc7 @billsaysthis moved app-specific js to separate file
billsaysthis authored
559 user = users.get_current_user()
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
560 event = Event.get_by_id(int(id))
d2c3dc7 @billsaysthis moved app-specific js to separate file
billsaysthis authored
561 if user:
562 logout_url = users.create_logout_url('/')
563 else:
564 login_url = users.create_login_url('/')
565 self.response.out.write(template.render('templates/feedback.html', locals()))
566
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
567 def post(self, id):
d2c3dc7 @billsaysthis moved app-specific js to separate file
billsaysthis authored
568 user = users.get_current_user()
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
569 event = Event.get_by_id(int(id))
8c52522 @billsaysthis small tweak to how feedbacks displayed in event page
billsaysthis authored
570 try:
571 if self.request.get('rating'):
572 feedback = Feedback(
573 event = event,
574 rating = int(self.request.get('rating')),
ca3c6dd Escaped additional fields that could be used for XSS
Christopher Biettchert authored
575 comment = cgi.escape(self.request.get('comment')))
8c52522 @billsaysthis small tweak to how feedbacks displayed in event page
billsaysthis authored
576 feedback.put()
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
577 log = HDLog(event=event,description="Posted feedback")
578 log.put()
8c52522 @billsaysthis small tweak to how feedbacks displayed in event page
billsaysthis authored
579 self.redirect('/event/%s-%s' % (event.key().id(), slugify(event.name)))
580 else:
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
581 raise ValueError('Please select a rating')
8c52522 @billsaysthis small tweak to how feedbacks displayed in event page
billsaysthis authored
582 except Exception:
583 set_cookie(self.response.headers, 'formvalues', dict(self.request.POST))
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
584 self.redirect('/feedback/new/' + id)
d2c3dc7 @billsaysthis moved app-specific js to separate file
billsaysthis authored
585
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
586 def main():
587 application = webapp.WSGIApplication([
588 ('/', ApprovedHandler),
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
589 ('/all_future', AllFutureHandler),
85d17af @dustball "Large Events" page and iCal feed
dustball authored
590 ('/large', LargeHandler),
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
591 ('/pending', PendingHandler),
841fefb added meaningful descriptions to ical events.
Stig Hackvan authored
592 ('/past', PastHandler),
b4ea292 Handler to bug pending events
Brian Klug authored
593 ('/cronbugowners', CronBugOwnersHandler),
a82b43e @billsaysthis add myevents, pastevents code, refined list display on event page
billsaysthis authored
594 ('/myevents', MyEventsHandler),
5459516 @billsaysthis [#40] add not approved status and list view
billsaysthis authored
595 ('/not_approved', NotApprovedHandler),
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
596 ('/new', NewHandler),
87868cf issue 11 add a confirmation page
jonathan authored
597 ('/confirm/(\d+).*', ConfirmationHandler),
ca8c7f2 @dustball Let edit events and refactor error handling
dustball authored
598 ('/edit/(\d+).*', EditHandler),
841fefb added meaningful descriptions to ical events.
Stig Hackvan authored
599 # single event views
47a7f7a @progrium basic form validation, added end time, start of notifications, some fixe...
progrium authored
600 ('/event/(\d+).*', EventHandler),
2e08a66 @progrium cleaning things up and adding json representations for jon
progrium authored
601 ('/event/(\d+)\.json', EventHandler),
841fefb added meaningful descriptions to ical events.
Stig Hackvan authored
602 # various export methods -- events.{json,rss,ics}
603 ('/events\.(.+)', ExportHandler),
604 #
605 # CRON tasks
47a7f7a @progrium basic form validation, added end time, start of notifications, some fixe...
progrium authored
606 ('/expire', ExpireCron),
34d98f0 @billsaysthis moved feedback stuff to separate py file, small tweak to email notificat...
billsaysthis authored
607 ('/expiring', ExpireReminderCron),
5459516 @billsaysthis [#40] add not approved status and list view
billsaysthis authored
608 ('/domaincache', DomainCacheCron),
f49797a @dustball Reminders 2.0
dustball authored
609 ('/reminder', ReminderCron),
841fefb added meaningful descriptions to ical events.
Stig Hackvan authored
610 #
2ad290e @billsaysthis add logging model and obscure list view
billsaysthis authored
611 ('/logs', LogsHandler),
d2c3dc7 @billsaysthis moved app-specific js to separate file
billsaysthis authored
612 ('/feedback/new/(\d+).*', FeedbackHandler) ],debug=True)
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
613 util.run_wsgi_app(application)
614
f1997e4 @christopherb Made misc style fixes
christopherb authored
615
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
616 if __name__ == '__main__':
617 main()
Something went wrong with that request. Please try again.