Skip to content
Browse files

Reminders 2.0

  • Loading branch information...
1 parent 4d85afa commit f49797ae42d8dd6a01073bc2dbf649934f9aecc3 @dustball dustball committed Sep 9, 2010
Showing with 98 additions and 94 deletions.
  1. +4 −3 app.yaml
  2. +4 −1 cron.yaml
  3. +6 −0 index.yaml
  4. +20 −6 main.py
  5. +1 −0 models.py
  6. +56 −80 notices.py
  7. +3 −0 queue.yaml
  8. +3 −3 templates/event.html
  9. +1 −1 templates/new.html
View
7 app.yaml
@@ -27,8 +27,9 @@ handlers:
- url: /test.*
login: admin
script: gaeunit.py
+- url: /_ah/queue/deferred
+ script: $PYTHON_LIB/google/appengine/ext/deferred/handler.py
+ login: admin
- url: .*
- script: main.py
-
-
+ script: main.py
View
5 cron.yaml
@@ -4,4 +4,7 @@ cron:
schedule: every 24 hours
- description: reminder of expiring events in 10 days
url: /expiring
- schedule: every 24 hours
+ schedule: every 24 hours
+- description: remind people about their event
+ url: /reminder
+ schedule: every 1 minute
View
6 index.yaml
@@ -17,6 +17,12 @@ indexes:
- kind: Event
properties:
+ - name: reminded
+ - name: status
+ - name: start_time
+
+- kind: Event
+ properties:
- name: status
- name: expired
View
26 main.py
@@ -14,6 +14,24 @@
from utils import username, human_username, set_cookie, local_today, is_phone_valid, UserRights
from notices import *
+class ReminderCron(webapp.RequestHandler):
+ def post(self):
+ self.response.out.write("REMINDERS")
+ today = local_today()
+ # remind everyone 3 days in advance they need to show up
+ events = Event.all() \
+ .filter('status IN', ['approved']) \
+ .filter('reminded =', False) \
+ .filter('start_time <', today + timedelta(days=3))
+ for event in events:
+ self.response.out.write(event.name)
+ # only mail them if they created the event 2+ days ago
+ if event.created < today - timedelta(days=2):
+ schedule_reminder_email(event)
+ event.reminded = True
+ event.put()
+
+
class ExpireCron(webapp.RequestHandler):
def post(self):
# Expire events marked to expire today
@@ -25,7 +43,7 @@ def post(self):
for event in events:
event.expire()
notify_owner_expired(event)
-
+
class ExpireReminderCron(webapp.RequestHandler):
def post(self):
@@ -85,9 +103,6 @@ def post(self, id):
event.add_staff(user)
if state.lower() == 'unstaff' and access_rights.can_unstaff:
event.remove_staff(user)
- # send notification is state changed to understaffed
- if event.status == 'understaffed':
- notify_unapproved_unstaff_event(event)
if state.lower() == 'cancel' and access_rights.can_cancel:
event.cancel()
if state.lower() == 'delete' and access_rights.is_admin:
@@ -215,8 +230,6 @@ def post(self):
)
event.put()
notify_owner_confirmation(event)
- if not event.is_staffed():
- notify_staff_needed(event)
notify_new_event(event)
set_cookie(self.response.headers, 'formvalues', None)
self.redirect('/event/%s-%s' % (event.key().id(), slugify(event.name)))
@@ -272,6 +285,7 @@ def main():
('/event/(\d+)\.json', EventHandler),
('/expire', ExpireCron),
('/expiring', ExpireReminderCron),
+ ('/reminder', ReminderCron),
('/feedback/new/(\d+).*', FeedbackHandler) ],debug=True)
util.run_wsgi_app(application)
View
1 models.py
@@ -35,6 +35,7 @@ class Event(db.Model):
notes = db.TextProperty()
type = db.StringProperty(required=True)
estimated_size = db.StringProperty(required=True)
+ reminded = db.BooleanProperty(default=False)
contact_name = db.StringProperty(required=True)
contact_phone = db.StringProperty(required=True)
View
136 notices.py
@@ -1,5 +1,7 @@
from google.appengine.api import mail
from django.template.defaultfilters import slugify
+from google.appengine.ext import deferred
+import random
import os
FROM_ADDRESS = 'Dojo Events <no-reply@hackerdojo-events.appspotmail.com>'
@@ -20,109 +22,78 @@ def bug_owner_pending(e):
e.key().id(),
slugify(e.name),)
- if e.staff_needed()>0:
- body += """
-Alert! You still need to get %i more member(s) to staff your event.
-Please get some other Dojo members to go to
-http://%s/event/%s-%s and click the 'Staff' button.
-""" % (
- e.staff_needed(),
- os.environ.get('HTTP_HOST'),
- e.key().id(),
- slugify(e.name),)
-
if not e.is_approved():
body += """
Alert! The events team has not approved your event yet.
Please e-mail them at events@hackerdojo.com to see whats up.
"""
body += """
-Your event is NOT scheduled. Please remedy the above issues to get your event official.
-"""
- print body
- print "*" * 80
-
- mail.send_mail(sender=FROM_ADDRESS, to=e.member.email(),
+Cheers,
+Hacker Dojo Events Team
+events@hackerdojo.com
+"""
+
+ deferred.defer(mail.send_mail, sender=FROM_ADDRESS, to=e.member.email(),
subject="[Pending Event] Your event is still pending: " + e.name,
- body=body)
-
-def notify_owner_confirmation(event):
- mail.send_mail(sender=FROM_ADDRESS, to=event.member.email(),
- subject="[New Event] Submitted but **not yet approved**",
- body="""This is a confirmation that your event:
+ body=body, _queue="emailthrottle")
-%s
-on %s
+def schedule_reminder_email(e):
+ body = """
-has been submitted to be approved. If staff is needed for your event, they
-will be notified of your request. You will be notified as soon as it's
-approved and on the calendar. Here is a link to the event page:
+*REMINDER*
-http://events.hackerdojo.com/event/%s-%s
+Event: %s
+Owner: %s
+Date: %s
+URL: http://%s/event/%s-%s
+""" % (
+ e.name,
+ str(e.owner()),
+ e.start_time.strftime('%A, %B %d'),
+ os.environ.get('HTTP_HOST'),
+ e.key().id(),
+ slugify(e.name),)
+ body += """
-Again, your event is NOT YET APPROVED and not on the calendar.""" % (
- event.name,
- event.start_time.strftime('%A, %B %d'),
- event.key().id(),
- slugify(event.name),))
+Hello! Friendly reminder that your event is scheduled to happen at Hacker Dojo.
+ * The person named above must be physically present
+ * If the event has been cancelled, resecheduled or moved, you must login and cancel the event on our system
-def notify_staff_needed(event):
- mail.send_mail(sender=FROM_ADDRESS, to=STAFF_ADDRESS,
- subject='[Event Staffing] %s on %s' % (event.name, event.start_time.strftime('%a %b %d')),
- body="""Hello staff!
+Cheers,
+Hacker Dojo Events Team
+events@hackerdojo.com
-Fellow member %s is sponsoring a ~%s person event:
+"""
+
+ deferred.defer(mail.send_mail, sender=FROM_ADDRESS, to=e.member.email(),
+ subject="[Event Reminder] " + e.name,
+ body=body, _queue="emailthrottle")
+
+def notify_owner_confirmation(event):
+ mail.send_mail(sender=FROM_ADDRESS, to=event.member.email(),
+ subject="[New Event] Submitted but **not yet approved**",
+ body="""This is a confirmation that your event:
%s
-at %s to %s on %s
-
-At %s people expected, %s staff members need to opt in to support this event.
+on %s
-Without your help, this event won't happen. If you can staff this event, click
-the Staff button once logged in on this page:
+has been submitted to be approved. You will be notified as soon as it's
+approved and on the calendar. Here is a link to the event page:
http://events.hackerdojo.com/event/%s-%s
-""" % (
- event.member.email(),
- event.estimated_size,
- event.name,
- event.start_time.strftime('%I:%M%p'),
- event.end_time.strftime('%I:%M%p'),
- event.start_time.strftime('%A, %B %d'),
- event.estimated_size,
- event.staff_needed(),
- event.key().id(),
- slugify(event.name),))
-
-
-def notify_unapproved_unstaff_event(event):
- mail.send_mail(sender=FROM_ADDRESS, to=STAFF_ADDRESS,
- subject="[Event Unapproved, Needs Staffing] %s on %s" % (event.name, event.start_time.strftime('%a %b %d')),
- body="""Hello staff!
-Unfortunately a staffer can no longer support %s's ~%s person event.
+Again, your event is NOT YET APPROVED and not on the calendar.
-Event Name: %s
-at %s to %s on %s
+Cheers,
+Hacker Dojo Events Team
+events@hackerdojo.com
-At %s people expected, %s staff members need to opt in to support this event.
-
-Without your help, this event won't happen. If you can staff this event, click
-the Staff button once logged in on this page:
-
-http://events.hackerdojo.com/event/%s-%s
""" % (
- event.member.email(),
- event.estimated_size,
- event.name,
- event.start_time.strftime('%I:%M%p'),
- event.end_time.strftime('%I:%M%p'),
+ event.name,
event.start_time.strftime('%A, %B %d'),
- event.estimated_size,
- event.staff_needed(),
event.key().id(),
slugify(event.name),))
@@ -156,16 +127,21 @@ def notify_owner_approved(event):
subject="[Event Approved] %s" % event.name,
body="""Your event is approved and on the calendar!
-Please notify the event organizer if that is not you. You still need to be
-present at the event! And remember your duties as a Hacker Dojo event sponsor.
+Friendly Reminder: You must be present at the event and make sure Dojo policies are followed.
+
+Note: If you cancel or reschedule the event, please log in to our system and cancel the event!
http://events.hackerdojo.com/event/%s-%s
+
+Cheers,
+Hacker Dojo Events Team
+events@hackerdojo.com
+
""" % (event.key().id(), slugify(event.name)))
def notify_owner_expiring(event):
pass
-
def notify_owner_expired(event):
pass
View
3 queue.yaml
@@ -0,0 +1,3 @@
+queue:
+- name: emailthrottle
+ rate: 5/m
View
6 templates/event.html
@@ -15,8 +15,8 @@
{% if access_rights.can_approve %}<input type="submit" name="state" value="Approve" />{% endif %}
{% if access_rights.can_cancel and not event.is_canceled %}<input type="submit" name="state" value="Cancel" />{% endif %}
{% if access_rights.is_admin %}<input type="submit" name="state" value="Delete" />{% endif %}
- {% if access_rights.can_staff %}<input type="submit" name="state" value="Staff" />{% endif %}
- {% if access_rights.can_unstaff %}<input type="submit" name="state" value="Unstaff" />{% endif %}
+ <!--{% if access_rights.can_staff %}<input type="submit" name="state" value="Staff" />{% endif %}
+ {% if access_rights.can_unstaff %}<input type="submit" name="state" value="Unstaff" />{% endif %}-->
{% endif %}
</form>
</p>{% endif %}
@@ -39,7 +39,7 @@
<div class='b-block'><div class='b-label'>URL:</div><div class='b-data'><a href='{{event.url}}'>{{event.url}}</a></div></div>
<div class='b-block'><div class='b-label'>Fee:</div><div class='b-data'>{{event.fee}}</div></div>
<div class='b-block'><div class='b-label'>Rooms:</div><div class='b-data'>{{event.roomlist}}</div></div>
- <div class='b-block'><div class='b-label'>Staff:</div><div class='b-data'>{{event.stafflist}}</div></div>
+ <!--<div class='b-block'><div class='b-label'>Staff:</div><div class='b-data'>{{event.stafflist}}</div></div>-->
<div class='thin-border'></div>
<div class='b-block'><div class='b-label'>Details:</div><div class='b-data'>{{event.details}}</div></div>
<br />
View
2 templates/new.html
@@ -45,7 +45,7 @@ <h3 style="margin-top: 0px;">Member Terms as Event Host:</h3>
<li><strong>Schedule</strong>
<div>Dojo resources are allocated on a first come, first serve basis. Avoid scheduling major events on the same day. Otherwise, expect an Events Coordinator to suggest an alternate time or room.</div></li>
<li><strong>Presence</strong>
- <div>{{human}} must be phsyically physically for the event. You need to be there to ensure the event runs smoothly and the rules are enforced. If the event is cancelled, you are responsible for cancelling the event on this system.<p>If you are submitting this application on behalf of someone else, you will still be held responsible.</div></li>
+ <div>{{human}} must be physically for the event. You need to be there to ensure the event runs smoothly and the rules are enforced. If the event is cancelled, you are responsible for cancelling the event on this system.<p>If you are submitting this application on behalf of someone else, you will still be held responsible.</div></li>
<li><strong>Approval</strong>
<div>The event must be approved by Event Coordinators. We reserve the right to refuse approval of events that are not considered in the spirit of Hacker Dojo.</div></li>
<li><strong>Setup</strong>

0 comments on commit f49797a

Please sign in to comment.
Something went wrong with that request. Please try again.