Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100755 517 lines (470 sloc) 23.221 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 f…
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 edit…
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/…
Stig Hackvan authored
19 import pytz
9f06c39 @casey Added RSS for upcoming events.
casey 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):
27 def post(self):
28 noop = dojo('/groups/events',force=True)
29
30
f49797a @dustball Reminders 2.0
dustball authored
31 class ReminderCron(webapp.RequestHandler):
32 def post(self):
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))
40 for event in events:
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 f…
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 f…
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)
f49797a @dustball Reminders 2.0
dustball authored
60
f1997e4 @christopherb Made misc style fixes
christopherb authored
61
47a7f7a @progrium basic form validation, added end time, start of notifications, some f…
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 f…
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)
78
79 def export_json(self):
80 events = Event.get_approved_list()
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)
89
90 def export_ics(self):
9f06c39 @casey Added RSS for upcoming events.
casey authored
91 events = Event.all().filter('status IN', ['approved', 'canceled']).order('start_time')
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' % (
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,
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()
122
123 def export_rss(self):
124 url_base = 'http://' + self.request.headers.get('host', 'events.hackerdojo.com')
125 events = Event.all().filter('status IN', ['approved', 'canceled']).order('start_time')
126 rss = PyRSS2Gen.RSS2(
127 title = "Hacker Dojo Events Feed",
128 link = url_base,
129 description = "Upcoming events at the Hacker Dojo in Mountain View, CA",
130 lastBuildDate = datetime.now(),
131 items = [PyRSS2Gen.RSSItem(
132 title = event.name,
133 link = url_base + event_path(event),
134 description = event.details,
135 guid = url_base + event_path(event),
136 pubDate = event.updated,
137 ) for event in events]
138 )
139 return 'application/xml', rss.to_xml()
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
140
f1997e4 @christopherb Made misc style fixes
christopherb authored
141
ca8c7f2 @dustball Let edit events and refactor error handling
dustball authored
142 class EditHandler(webapp.RequestHandler):
143 def get(self, id):
144 event = Event.get_by_id(int(id))
145 user = users.get_current_user()
736390e @dustball Bug fixes & UI
dustball authored
146 show_all_nav = user
ca8c7f2 @dustball Let edit events and refactor error handling
dustball authored
147 access_rights = UserRights(user, event)
148 if access_rights.can_edit:
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
149 logout_url = users.create_logout_url('/')
150 rooms = ROOM_OPTIONS
151 hours = [1,2,3,4,5,6,7,8,9,10,11,12]
152 self.response.out.write(template.render('templates/edit.html', locals()))
ca8c7f2 @dustball Let edit events and refactor error handling
dustball authored
153 else:
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
154 self.response.out.write("Access denied")
ca8c7f2 @dustball Let edit events and refactor error handling
dustball authored
155
156 def post(self, id):
157 event = Event.get_by_id(int(id))
158 user = users.get_current_user()
159 access_rights = UserRights(user, event)
160 if access_rights.can_edit:
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
161 try:
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fi…
jonathan authored
162 start_time = datetime.strptime('%s %s:%s %s' % (
163 self.request.get('date'),
164 self.request.get('start_time_hour'),
165 self.request.get('start_time_minute'),
166 self.request.get('start_time_ampm')), '%m/%d/%Y %I:%M %p')
167 end_time = datetime.strptime('%s %s:%s %s' % (
168 self.request.get('date'),
169 self.request.get('end_time_hour'),
170 self.request.get('end_time_minute'),
171 self.request.get('end_time_ampm')), '%m/%d/%Y %I:%M %p')
20c252d @dustball Fix key/index bug
dustball authored
172 conflicts = Event.check_conflict(start_time,end_time,self.request.get_all('rooms'), int(id))
c97598b @dustball Room Conflict Detection
dustball authored
173 if conflicts:
174 raise ValueError('Room conflict detected')
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
175 if not self.request.get('estimated_size').isdigit():
176 raise ValueError('Estimated number of people must be a number')
177 if not int(self.request.get('estimated_size')) > 0:
178 raise ValueError('Estimated number of people must be greater then zero')
179 if ( self.request.get( 'contact_phone' ) and not is_phone_valid( self.request.get( 'contact_phone' ) ) ):
180 raise ValueError( 'Phone number does not appear to be valid' )
181 else:
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fi…
jonathan authored
182 log_desc = "Event edited\n"
183 previous_object = Event.get_by_id(int(id))
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
184 event.name = self.request.get('name')
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fi…
jonathan authored
185 if (previous_object.name != event.name):
186 log_desc = log_desc + "Title: " + previous_object.name + " to " + event.name + "\n"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
187 event.start_time = start_time
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fi…
jonathan authored
188 if (previous_object.start_time != event.start_time):
189 log_desc = log_desc + "Start time: " + str(previous_object.start_time) + " to " + str(event.start_time) + "\n"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
190 event.end_time = end_time
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fi…
jonathan authored
191 if (previous_object.end_time != event.end_time):
192 log_desc = log_desc + "End time: " + str(previous_object.end_time) + " to " + str(event.end_time) + "\n"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
193 event.estimated_size = cgi.escape(self.request.get('estimated_size'))
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fi…
jonathan authored
194 if (previous_object.estimated_size != event.estimated_size):
195 log_desc = log_desc + "Est. size: " + previous_object.estimated_size + " to " + event.estimated_size + "\n"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
196 event.contact_name = cgi.escape(self.request.get('contact_name'))
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fi…
jonathan authored
197 if (previous_object.contact_name != event.contact_name):
198 log_desc = log_desc + "Contact: " + previous_object.contact_name + " to " + event.contact_name + "\n"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
199 event.contact_phone = cgi.escape(self.request.get('contact_phone'))
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fi…
jonathan authored
200 if (previous_object.contact_phone != event.contact_phone):
201 log_desc = log_desc + "Contact phone: " + previous_object.contact_phone + " to " + event.contact_phone + "\n"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
202 event.details = cgi.escape(self.request.get('details'))
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fi…
jonathan authored
203 if (previous_object.details != event.details):
204 log_desc = log_desc + "Details: " + previous_object.details + " to " + event.details + "\n"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
205 event.url = cgi.escape(self.request.get('url'))
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fi…
jonathan authored
206 if (previous_object.url != event.url):
207 log_desc = log_desc + "Url: " + previous_object.url + " to " + event.url + "\n"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
208 event.fee = cgi.escape(self.request.get('fee'))
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fi…
jonathan authored
209 if (previous_object.fee != event.fee):
210 log_desc = log_desc + "Fee: " + previous_object.fee + " to " + event.fee + "\n"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
211 event.notes = cgi.escape(self.request.get('notes'))
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fi…
jonathan authored
212 if (previous_object.notes != event.notes):
213 log_desc = log_desc + "Notes: " + previous_object.notes + " to " + event.notes + "\n"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
214 event.rooms = self.request.get_all('rooms')
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fi…
jonathan authored
215 if (previous_object.rooms != event.rooms):
216 log_desc = log_desc + "Rooms changed" + "\n"
217 log_desc = log_desc + "Old room " + "\n"
218 for room in previous_object.rooms:
219 log_desc = log_desc + room + ' '
220 log_desc = log_desc + "New room(s) " + "\n"
221 for room in event.rooms:
222 log_desc = log_desc + room + ' '
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
223 event.put()
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fi…
jonathan authored
224 log = HDLog(event=event,description=log_desc)
2ad290e @billsaysthis add logging model and obscure list view
billsaysthis authored
225 log.put()
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
226 self.redirect(event_path(event))
2ad290e @billsaysthis add logging model and obscure list view
billsaysthis authored
227 except ValueError, e:
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
228 error = str(e)
229 self.response.out.write(template.render('templates/error.html', locals()))
ca8c7f2 @dustball Let edit events and refactor error handling
dustball authored
230 else:
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
231 self.response.out.write("Access denied")
ca8c7f2 @dustball Let edit events and refactor error handling
dustball authored
232
233
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
234 class EventHandler(webapp.RequestHandler):
235 def get(self, id):
236 event = Event.get_by_id(int(id))
2e08a66 @progrium cleaning things up and adding json representations for jon
progrium authored
237 if self.request.path.endswith('json'):
238 self.response.headers['content-type'] = 'application/json'
239 self.response.out.write(simplejson.dumps(event.to_dict()))
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
240 else:
2e08a66 @progrium cleaning things up and adding json representations for jon
progrium authored
241 user = users.get_current_user()
242 if user:
766e87c @christopherb Added UserRights class.
christopherb authored
243 access_rights = UserRights(user, event)
2e08a66 @progrium cleaning things up and adding json representations for jon
progrium authored
244 logout_url = users.create_logout_url('/')
766e87c @christopherb Added UserRights class.
christopherb authored
245
2e08a66 @progrium cleaning things up and adding json representations for jon
progrium authored
246 else:
247 login_url = users.create_login_url('/')
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on singl…
christopherb authored
248 event.details = db.Text(event.details.replace('\n','<br/>'))
736390e @dustball Bug fixes & UI
dustball authored
249 show_all_nav = user
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on singl…
christopherb authored
250 event.notes = db.Text(event.notes.replace('\n','<br/>'))
2e08a66 @progrium cleaning things up and adding json representations for jon
progrium authored
251 self.response.out.write(template.render('templates/event.html', locals()))
e2b9558 @btubbs Fixes issue 4. Changed to jqueryUI datepicker. Replaced jquery
btubbs authored
252
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
253 def post(self, id):
254 event = Event.get_by_id(int(id))
255 user = users.get_current_user()
766e87c @christopherb Added UserRights class.
christopherb authored
256 access_rights = UserRights(user, event)
257
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
258 state = self.request.get('state')
259 if state:
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
260 desc = ''
766e87c @christopherb Added UserRights class.
christopherb authored
261 if state.lower() == 'approve' and access_rights.can_approve:
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
262 event.approve()
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
263 desc = 'Approved event'
b84b533 @dustball Fix one more staff logic bomb
dustball authored
264 if state.lower() == 'staff' and access_rights.can_staff:
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
265 event.add_staff(user)
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
266 desc = 'Added self as staff'
766e87c @christopherb Added UserRights class.
christopherb authored
267 if state.lower() == 'unstaff' and access_rights.can_unstaff:
72849c2 @billsaysthis added unstaff event, including email notification if event becomes un…
billsaysthis authored
268 event.remove_staff(user)
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
269 desc = 'Removed self as staff'
f8ffd89 @billsaysthis refactor lists to use singe event partial, adds contact email link in…
billsaysthis authored
270 if state.lower() == 'onhold' and access_rights.can_cancel:
271 event.on_hold()
272 desc = 'Put event on hold'
766e87c @christopherb Added UserRights class.
christopherb authored
273 if state.lower() == 'cancel' and access_rights.can_cancel:
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
274 event.cancel()
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
275 desc = 'Cancelled event'
766e87c @christopherb Added UserRights class.
christopherb authored
276 if state.lower() == 'delete' and access_rights.is_admin:
a67ac50 @mdhancher Add a simple admin-only event delete and undelete.
mdhancher authored
277 event.delete()
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
278 desc = 'Deleted event'
766e87c @christopherb Added UserRights class.
christopherb authored
279 if state.lower() == 'undelete' and access_rights.is_admin:
a67ac50 @mdhancher Add a simple admin-only event delete and undelete.
mdhancher authored
280 event.undelete()
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
281 desc = 'Undeleted event'
766e87c @christopherb Added UserRights class.
christopherb authored
282 if state.lower() == 'expire' and access_rights.is_admin:
47a7f7a @progrium basic form validation, added end time, start of notifications, some f…
progrium authored
283 event.expire()
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
284 desc = 'Expired event'
47a7f7a @progrium basic form validation, added end time, start of notifications, some f…
progrium authored
285 if event.status == 'approved':
286 notify_owner_approved(event)
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
287 if desc != '':
288 log = HDLog(event=event,description=desc)
289 log.put()
9f06c39 @casey Added RSS for upcoming events.
casey authored
290 self.redirect(event_path(event))
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
291
f1997e4 @christopherb Made misc style fixes
christopherb authored
292
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
293 class ApprovedHandler(webapp.RequestHandler):
294 def get(self):
295 user = users.get_current_user()
296 if user:
297 logout_url = users.create_logout_url('/')
298 else:
299 login_url = users.create_login_url('/')
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
300 today = local_today()
736390e @dustball Bug fixes & UI
dustball authored
301 show_all_nav = user
47a7f7a @progrium basic form validation, added end time, start of notifications, some f…
progrium authored
302 events = Event.get_approved_list()
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
303 tomorrow = today + timedelta(days=1)
d63161a Add widget mode
Brian Klug authored
304 whichbase = 'base.html'
305 if self.request.get('base'):
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on singl…
christopherb authored
306 whichbase = self.request.get('base') + '.html'
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
307 self.response.out.write(template.render('templates/approved.html', locals()))
308
f1997e4 @christopherb Made misc style fixes
christopherb authored
309
a82b43e @billsaysthis add myevents, pastevents code, refined list display on event page
billsaysthis authored
310 class MyEventsHandler(webapp.RequestHandler):
311 @util.login_required
312 def get(self):
313 user = users.get_current_user()
314 if user:
315 logout_url = users.create_logout_url('/')
316 else:
317 login_url = users.create_login_url('/')
318 events = Event.all().filter('member = ', user).order('start_time')
736390e @dustball Bug fixes & UI
dustball authored
319 show_all_nav = user
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
320 today = local_today()
a82b43e @billsaysthis add myevents, pastevents code, refined list display on event page
billsaysthis authored
321 tomorrow = today + timedelta(days=1)
322 self.response.out.write(template.render('templates/myevents.html', locals()))
323
f1997e4 @christopherb Made misc style fixes
christopherb authored
324
a82b43e @billsaysthis add myevents, pastevents code, refined list display on event page
billsaysthis authored
325 class PastHandler(webapp.RequestHandler):
326 def get(self):
327 user = users.get_current_user()
328 if user:
329 logout_url = users.create_logout_url('/')
330 else:
331 login_url = users.create_login_url('/')
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
332 today = local_today()
736390e @dustball Bug fixes & UI
dustball authored
333 show_all_nav = user
d75579f @progrium minor updates here and there to bills contributions.
progrium authored
334 events = Event.all().filter('start_time < ', today).order('-start_time')
a82b43e @billsaysthis add myevents, pastevents code, refined list display on event page
billsaysthis authored
335 self.response.out.write(template.render('templates/past.html', locals()))
336
f1997e4 @christopherb Made misc style fixes
christopherb authored
337
b4ea292 Handler to bug pending events
Brian Klug authored
338 class CronBugOwnersHandler(webapp.RequestHandler):
339 def get(self):
340 events = Event.get_pending_list()
341 for e in events:
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
342 bug_owner_pending(e)
343
344
345 class AllFutureHandler(webapp.RequestHandler):
346 def get(self):
347 user = users.get_current_user()
348 if user:
349 logout_url = users.create_logout_url('/')
350 else:
351 login_url = users.create_login_url('/')
736390e @dustball Bug fixes & UI
dustball authored
352 show_all_nav = user
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
353 events = Event.get_all_future_list()
354 today = local_today()
355 tomorrow = today + timedelta(days=1)
356 self.response.out.write(template.render('templates/all_future.html', locals()))
b4ea292 Handler to bug pending events
Brian Klug authored
357
f1997e4 @christopherb Made misc style fixes
christopherb authored
358
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
359 class PendingHandler(webapp.RequestHandler):
360 def get(self):
361 user = users.get_current_user()
362 if user:
363 logout_url = users.create_logout_url('/')
364 else:
365 login_url = users.create_login_url('/')
47a7f7a @progrium basic form validation, added end time, start of notifications, some f…
progrium authored
366 events = Event.get_pending_list()
736390e @dustball Bug fixes & UI
dustball authored
367 show_all_nav = user
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
368 today = local_today()
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
369 tomorrow = today + timedelta(days=1)
370 self.response.out.write(template.render('templates/pending.html', locals()))
371
f1997e4 @christopherb Made misc style fixes
christopherb authored
372
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
373 class NewHandler(webapp.RequestHandler):
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
374 @util.login_required
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
375 def get(self):
376 user = users.get_current_user()
4d85afa @dustball Remove staffing requirement and make members more responsible
dustball authored
377 human = human_username(user)
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
378 if user:
379 logout_url = users.create_logout_url('/')
380 else:
381 login_url = users.create_login_url('/')
382 rooms = ROOM_OPTIONS
383 self.response.out.write(template.render('templates/new.html', locals()))
e2b9558 @btubbs Fixes issue 4. Changed to jqueryUI datepicker. Replaced jquery
btubbs authored
384
f1997e4 @christopherb Made misc style fixes
christopherb authored
385
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
386 def post(self):
387 user = users.get_current_user()
7742592 @progrium start of maintaining form state on errors
progrium authored
388 try:
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on singl…
christopherb authored
389 start_time = datetime.strptime('%s %s:%s %s' % (
7742592 @progrium start of maintaining form state on errors
progrium authored
390 self.request.get('date'),
391 self.request.get('start_time_hour'),
392 self.request.get('start_time_minute'),
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on singl…
christopherb authored
393 self.request.get('start_time_ampm')), '%m/%d/%Y %I:%M %p')
394 end_time = datetime.strptime('%s %s:%s %s' % (
7742592 @progrium start of maintaining form state on errors
progrium authored
395 self.request.get('date'),
396 self.request.get('end_time_hour'),
397 self.request.get('end_time_minute'),
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on singl…
christopherb authored
398 self.request.get('end_time_ampm')), '%m/%d/%Y %I:%M %p')
c97598b @dustball Room Conflict Detection
dustball authored
399 conflicts = Event.check_conflict(start_time,end_time,self.request.get_all('rooms'))
400 if conflicts:
401 raise ValueError('Room conflict detected')
8615877 Fix validation for event size
Brian Klug authored
402 if not self.request.get('estimated_size').isdigit():
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on singl…
christopherb authored
403 raise ValueError('Estimated number of people must be a number')
8615877 Fix validation for event size
Brian Klug authored
404 if not int(self.request.get('estimated_size')) > 0:
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on singl…
christopherb authored
405 raise ValueError('Estimated number of people must be greater then zero')
7742592 @progrium start of maintaining form state on errors
progrium authored
406 if (end_time-start_time).days < 0:
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on singl…
christopherb authored
407 raise ValueError('End time must be after start time')
a244c65 @dustball Bug fixes
dustball authored
408 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 singl…
christopherb authored
409 raise ValueError( 'Phone number does not appear to be valid' )
7742592 @progrium start of maintaining form state on errors
progrium authored
410 else:
411 event = Event(
ca3c6dd Escaped additional fields that could be used for XSS
Christopher Biettchert authored
412 name = cgi.escape(self.request.get('name')),
7742592 @progrium start of maintaining form state on errors
progrium authored
413 start_time = start_time,
414 end_time = end_time,
ca3c6dd Escaped additional fields that could be used for XSS
Christopher Biettchert authored
415 type = cgi.escape(self.request.get('type')),
416 estimated_size = cgi.escape(self.request.get('estimated_size')),
417 contact_name = cgi.escape(self.request.get('contact_name')),
418 contact_phone = cgi.escape(self.request.get('contact_phone')),
8414350 @billsaysthis multiline for details and notes fields
billsaysthis authored
419 details = cgi.escape(self.request.get('details')),
ca3c6dd Escaped additional fields that could be used for XSS
Christopher Biettchert authored
420 url = cgi.escape(self.request.get('url')),
421 fee = cgi.escape(self.request.get('fee')),
8414350 @billsaysthis multiline for details and notes fields
billsaysthis authored
422 notes = cgi.escape(self.request.get('notes')),
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on singl…
christopherb authored
423 rooms = self.request.get_all('rooms'),
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
424 expired = local_today() + timedelta(days=PENDING_LIFETIME), # Set expected expiration date
7742592 @progrium start of maintaining form state on errors
progrium authored
425 )
426 event.put()
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
427 log = HDLog(event=event,description="Created new event")
428 log.put()
7742592 @progrium start of maintaining form state on errors
progrium authored
429 notify_owner_confirmation(event)
430 notify_new_event(event)
81a81e1 @progrium adding errors for form validation, full notifications, and minor edit…
progrium authored
431 set_cookie(self.response.headers, 'formvalues', None)
7742592 @progrium start of maintaining form state on errors
progrium authored
432 self.redirect('/event/%s-%s' % (event.key().id(), slugify(event.name)))
81a81e1 @progrium adding errors for form validation, full notifications, and minor edit…
progrium authored
433 except Exception, e:
434 message = str(e)
435 if 'match format' in message:
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on singl…
christopherb authored
436 message = 'Date is required.'
81a81e1 @progrium adding errors for form validation, full notifications, and minor edit…
progrium authored
437 if message.startswith('Property'):
438 message = message[9:].replace('_', ' ').capitalize()
ca8c7f2 @dustball Let edit events and refactor error handling
dustball authored
439 # This is NOT a reliable way to handle erorrs
440 #set_cookie(self.response.headers, 'formerror', message)
441 #set_cookie(self.response.headers, 'formvalues', dict(self.request.POST))
442 #self.redirect('/new')
443 error = message
444 self.response.out.write(template.render('templates/error.html', locals()))
445
2ad290e @billsaysthis add logging model and obscure list view
billsaysthis authored
446 class LogsHandler(webapp.RequestHandler):
447 @util.login_required
448 def get(self):
449 user = users.get_current_user()
450 logs = HDLog.get_logs_list()
451 if user:
452 logout_url = users.create_logout_url('/')
453 else:
454 login_url = users.create_login_url('/')
736390e @dustball Bug fixes & UI
dustball authored
455 show_all_nav = user
2ad290e @billsaysthis add logging model and obscure list view
billsaysthis authored
456 self.response.out.write(template.render('templates/logs.html', locals()))
457
d2c3dc7 @billsaysthis moved app-specific js to separate file
billsaysthis authored
458 class FeedbackHandler(webapp.RequestHandler):
459 @util.login_required
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on singl…
christopherb authored
460 def get(self, id):
d2c3dc7 @billsaysthis moved app-specific js to separate file
billsaysthis authored
461 user = users.get_current_user()
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on singl…
christopherb authored
462 event = Event.get_by_id(int(id))
d2c3dc7 @billsaysthis moved app-specific js to separate file
billsaysthis authored
463 if user:
464 logout_url = users.create_logout_url('/')
465 else:
466 login_url = users.create_login_url('/')
467 self.response.out.write(template.render('templates/feedback.html', locals()))
468
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on singl…
christopherb authored
469 def post(self, id):
d2c3dc7 @billsaysthis moved app-specific js to separate file
billsaysthis authored
470 user = users.get_current_user()
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on singl…
christopherb authored
471 event = Event.get_by_id(int(id))
8c52522 @billsaysthis small tweak to how feedbacks displayed in event page
billsaysthis authored
472 try:
473 if self.request.get('rating'):
474 feedback = Feedback(
475 event = event,
476 rating = int(self.request.get('rating')),
ca3c6dd Escaped additional fields that could be used for XSS
Christopher Biettchert authored
477 comment = cgi.escape(self.request.get('comment')))
8c52522 @billsaysthis small tweak to how feedbacks displayed in event page
billsaysthis authored
478 feedback.put()
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
479 log = HDLog(event=event,description="Posted feedback")
480 log.put()
8c52522 @billsaysthis small tweak to how feedbacks displayed in event page
billsaysthis authored
481 self.redirect('/event/%s-%s' % (event.key().id(), slugify(event.name)))
482 else:
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on singl…
christopherb authored
483 raise ValueError('Please select a rating')
8c52522 @billsaysthis small tweak to how feedbacks displayed in event page
billsaysthis authored
484 except Exception:
485 set_cookie(self.response.headers, 'formvalues', dict(self.request.POST))
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on singl…
christopherb authored
486 self.redirect('/feedback/new/' + id)
d2c3dc7 @billsaysthis moved app-specific js to separate file
billsaysthis authored
487
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
488 def main():
489 application = webapp.WSGIApplication([
490 ('/', ApprovedHandler),
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
491 ('/all_future', AllFutureHandler),
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
492 ('/pending', PendingHandler),
841fefb added meaningful descriptions to ical events.
Stig Hackvan authored
493 ('/past', PastHandler),
b4ea292 Handler to bug pending events
Brian Klug authored
494 ('/cronbugowners', CronBugOwnersHandler),
a82b43e @billsaysthis add myevents, pastevents code, refined list display on event page
billsaysthis authored
495 ('/myevents', MyEventsHandler),
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
496 ('/new', NewHandler),
ca8c7f2 @dustball Let edit events and refactor error handling
dustball authored
497 ('/edit/(\d+).*', EditHandler),
841fefb added meaningful descriptions to ical events.
Stig Hackvan authored
498 # single event views
47a7f7a @progrium basic form validation, added end time, start of notifications, some f…
progrium authored
499 ('/event/(\d+).*', EventHandler),
2e08a66 @progrium cleaning things up and adding json representations for jon
progrium authored
500 ('/event/(\d+)\.json', EventHandler),
841fefb added meaningful descriptions to ical events.
Stig Hackvan authored
501 # various export methods -- events.{json,rss,ics}
502 ('/events\.(.+)', ExportHandler),
503 #
504 # CRON tasks
47a7f7a @progrium basic form validation, added end time, start of notifications, some f…
progrium authored
505 ('/expire', ExpireCron),
34d98f0 @billsaysthis moved feedback stuff to separate py file, small tweak to email notifi…
billsaysthis authored
506 ('/expiring', ExpireReminderCron),
219203b @dustball Cache better
dustball authored
507 ('/domaincache', DomainCacheCron),
f49797a @dustball Reminders 2.0
dustball authored
508 ('/reminder', ReminderCron),
841fefb added meaningful descriptions to ical events.
Stig Hackvan authored
509 #
2ad290e @billsaysthis add logging model and obscure list view
billsaysthis authored
510 ('/logs', LogsHandler),
d2c3dc7 @billsaysthis moved app-specific js to separate file
billsaysthis authored
511 ('/feedback/new/(\d+).*', FeedbackHandler) ],debug=True)
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
512 util.run_wsgi_app(application)
513
f1997e4 @christopherb Made misc style fixes
christopherb authored
514
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
515 if __name__ == '__main__':
516 main()
Something went wrong with that request. Please try again.