diff --git a/caldav.py b/caldav.py
index 9553079..e209836 100644
--- a/caldav.py
+++ b/caldav.py
@@ -18,11 +18,11 @@
import band
import plan
import member
-
import datetime
import logging
# from pytz.gae import pytz
import pytz
+from safetaskqueue import safe_taskqueue_add, check_taskqueue_trust
def make_cal_header(the_title):
header = """BEGIN:VCALENDAR
@@ -235,52 +235,73 @@ def get(self, *args, **kwargs):
the_member_key = member.member_key_from_urlsafe(mk)
the_member = the_member_key.get()
+ the_member.last_calfetch = datetime.datetime.now()
+ the_member.put()
- calfeed = None
- if the_member.cal_feed_dirty is False:
- calfeed = get_calfeed_for_key("m",the_member.key)
+ calfeed = get_calfeed_for_key("m",the_member.key)
if calfeed is None:
- logging.info("member cal feed is dirty")
- the_member.cal_feed_dirty = False
- the_member.put()
-
- # construct the calendar feed, since it may have changed lately
-
- calfeed = u'{0}'.format(make_cal_header(the_member.name))
-
- the_bands = assoc.get_confirmed_bands_of_member(the_member)
-
- for a_band in the_bands:
- a_band_name = a_band.shortname if a_band.shortname else a_band.name
- all_gigs = gig.get_gigs_for_band_keys(a_band.key, show_past=True)
- for a_gig in all_gigs:
- if not a_gig.is_canceled and not a_gig.hide_from_calendar: # and not a_gig.is_archived:
- the_plan = plan.get_plan_for_member_key_for_gig_key(the_member_key, a_gig.key)
- if the_plan:
- # check member preferences
- # include gig if member wants to see all, or if gig is confirmed
- if a_gig.is_confirmed or \
- the_member.preferences.calendar_show_only_confirmed == False:
- # incude gig if member wants to see all, or if has registered
- # as maybe or definitely:
- if (the_plan.value > 0 and the_plan.value <= 3) or \
- (the_member.preferences.calendar_show_only_committed == False):
- if a_gig.is_confirmed:
- confstr = u'CONFIRMED!'
- else:
- confstr = u'(not confirmed)'
- calfeed = u'{0}{1}'.format(calfeed, \
- make_event(a_gig, a_band, \
- title_format=u'{0}:{{0}} {1}'.format(a_band_name, confstr)))
+ calfeed = u'{0}{1}'.format(make_cal_header(the_member.name), make_cal_footer())
- calfeed = u'{0}{1}'.format(calfeed, make_cal_footer())
- store_calfeed_for_key("m",the_member.key,calfeed)
self.response.write(calfeed)
- def post(self):
- print 'got post request'
+class UpdateCalfeeds(BaseHandler):
+
+ def get(self):
+ """ find members who are using their calfeeds and have dirty calfeeds """
+ member_keys = member.get_member_keys_to_update_calfeed()
+ logging.info("need to make calfeeds for {0} members".format(len(member_keys)))
+ for m in member_keys:
+ safe_taskqueue_add(
+ queue_name='calfeedqueue',
+ url='/update_member_calfeed',
+ params={'the_member':m.urlsafe()}
+ )
+
+class UpdateMemberCalfeed(webapp2.RequestHandler):
+ def post(self):
+ check_taskqueue_trust(self.request)
+ murl = self.request.get('the_member')
+ the_member = member.get_member_from_urlsafe_key(murl)
+ make_calfeed_for_member(the_member)
+
+
+def make_calfeed_for_member(the_member):
+ calfeed = None
+ logging.info("making cal feed for {0}".format(the_member.key.urlsafe()))
+ the_member.cal_feed_dirty = False
+ the_member.put()
+
+ # construct the calendar feed, since it may have changed lately
+ calfeed = u'{0}'.format(make_cal_header(the_member.name))
+ the_bands = assoc.get_confirmed_bands_of_member(the_member)
+
+ for a_band in the_bands:
+ a_band_name = a_band.shortname if a_band.shortname else a_band.name
+ all_gigs = gig.get_gigs_for_band_keys(a_band.key, show_past=True)
+ for a_gig in all_gigs:
+ if not a_gig.is_canceled and not a_gig.hide_from_calendar: # and not a_gig.is_archived:
+ the_plan = plan.get_plan_for_member_key_for_gig_key(the_member.key, a_gig.key)
+ if the_plan:
+ # check member preferences
+ # include gig if member wants to see all, or if gig is confirmed
+ if a_gig.is_confirmed or \
+ the_member.preferences.calendar_show_only_confirmed == False:
+ # incude gig if member wants to see all, or if has registered
+ # as maybe or definitely:
+ if (the_plan.value > 0 and the_plan.value <= 3) or \
+ (the_member.preferences.calendar_show_only_committed == False):
+ if a_gig.is_confirmed:
+ confstr = u'CONFIRMED!'
+ else:
+ confstr = u'(not confirmed)'
+ calfeed = u'{0}{1}'.format(calfeed, \
+ make_event(a_gig, a_band, \
+ title_format=u'{0}:{{0}} {1}'.format(a_band_name, confstr)))
+
+ calfeed = u'{0}{1}'.format(calfeed, make_cal_footer())
+ store_calfeed_for_key("m",the_member.key,calfeed)
def store_calfeed_for_key(prefix, the_key, the_feed):
diff --git a/cron.yaml b/cron.yaml
index f99759f..47ba6e5 100644
--- a/cron.yaml
+++ b/cron.yaml
@@ -11,3 +11,7 @@ cron:
- description: send reminders
url: /admin_send_reminders
schedule: every day 05:10
+- description: update cal feeds
+ url: /admin_generate_calfeeds
+ schedule: every 1 hours
+
diff --git a/goemail.py b/goemail.py
index f89fd3f..17c2928 100644
--- a/goemail.py
+++ b/goemail.py
@@ -4,7 +4,6 @@
from requestmodel import *
from google.appengine.api import mail
from google.appengine.api import users
-from google.appengine.api.taskqueue import taskqueue
import gig
import member
@@ -14,7 +13,7 @@
import pickle
import os
import stats
-import cryptoutil
+from safetaskqueue import safe_taskqueue_add, check_taskqueue_trust
from webapp2_extras import i18n
from webapp2_extras.i18n import gettext as _
@@ -146,7 +145,7 @@ def format_details(details, setlist, newline='\n'):
newline,
newline.join(setlist.splitlines()))
else:
- the_details_string = details
+ the_details_string = newline.join(details.splitlines())
return the_details_string
@@ -165,6 +164,7 @@ def format_body(body_format_str, newline='\n'):
else:
body = format_body(_('new_gig_email'))
html = format_body(_('new_gig_email_html'), newline='
')
+ print(html)
try:
ret= _send_admin_mail(the_email_address, u'{0} {1}'.format(title_string, the_gig.title), body, html=html, reply_to=reply_to)
@@ -181,7 +181,8 @@ def announce_new_gig(the_gig, the_gig_url, is_edit=False, is_reminder=False, cha
'change_string': change_string,
'the_members': the_members})
- _safe_taskqueue_add(
+ safe_taskqueue_add(
+ queue_name='emailqueue',
url='/announce_new_gig_handler',
params={'the_params': the_params
})
@@ -189,7 +190,7 @@ def announce_new_gig(the_gig, the_gig_url, is_edit=False, is_reminder=False, cha
class AnnounceNewGigHandler(webapp2.RequestHandler):
def post(self):
- _check_taskqueue_trust(self.request)
+ check_taskqueue_trust(self.request)
the_params = pickle.loads(self.request.get('the_params'))
@@ -231,7 +232,8 @@ def post(self):
'the_member_key': the_member_key
})
- _safe_taskqueue_add(
+ safe_taskqueue_add(
+ queue_name='emailqueue',
url='/send_new_gig_handler',
params={'the_shared_params': the_shared_params,
'the_member_params': the_member_params
@@ -247,7 +249,7 @@ def post(self):
class SendNewGigHandler(webapp2.RequestHandler):
def post(self):
- _check_taskqueue_trust(self.request)
+ check_taskqueue_trust(self.request)
the_shared_params = pickle.loads(self.request.get('the_shared_params'))
the_member_params = pickle.loads(self.request.get('the_member_params'))
@@ -373,7 +375,8 @@ def post(self):
address = self.request.get('address', None)
if address:
- _safe_taskqueue_add(
+ safe_taskqueue_add(
+ queue_name='emailqueue',
url='/send_test_email_handler',
params={'the_address':address}
)
@@ -383,7 +386,7 @@ class SendTestEmailHandler(webapp2.RequestHandler):
def post(self):
- _check_taskqueue_trust(self.request)
+ check_taskqueue_trust(self.request)
the_address = self.request.get('the_address', None)
if the_address:
_send_admin_mail(the_address, "testing email",
@@ -404,7 +407,8 @@ def post(self):
else:
raise ValueError('illegal member key to MemberTestEmail')
- _safe_taskqueue_add(
+ safe_taskqueue_add(
+ queue_name='emailqueue',
url='/member_test_email_handler',
params={'the_address':the_member.email_address}
)
@@ -412,7 +416,7 @@ def post(self):
class MemberTestEmailHandler(webapp2.RequestHandler):
def post(self):
- _check_taskqueue_trust(self.request)
+ check_taskqueue_trust(self.request)
the_address = self.request.get('the_address', None)
if the_address:
_send_admin_mail(the_address, "testing email",
@@ -422,13 +426,3 @@ def post(self):
logging.error('bad request to send member test email from {0}'.format(self.request.remote_addr))
self.response.write( 200 )
-
-def _safe_taskqueue_add(url, params):
- params['the_key'] = cryptoutil.encrypt_string("Trust Me")
- taskqueue.add(queue_name='emailqueue', url=url, params=params)
-
-def _check_taskqueue_trust(request):
- the_key = request.get('the_key','')
- plain_key = cryptoutil.decrypt_string(the_key).strip()
- if not plain_key == "Trust Me":
- raise RuntimeError('bad key to send email from {0}'.format(request.remote_addr))
\ No newline at end of file
diff --git a/main.py b/main.py
index fa9a7b1..2e5f0db 100644
--- a/main.py
+++ b/main.py
@@ -189,6 +189,8 @@
webapp2.Route('/cal/b/', caldav.BandRequestHandler),
webapp2.Route('/cal/m/', caldav.MemberRequestHandler),
webapp2.Route('/cal/p/', caldav.PublicBandGigRequestHandler),
+ webapp2.Route('/admin_generate_calfeeds', caldav.UpdateCalfeeds),
+ webapp2.Route('/update_member_calfeed', caldav.UpdateMemberCalfeed),
webapp2.Route('/calhelp', caldav.HelpHandler),
webapp2.Route('/announce_new_gig_handler', goemail.AnnounceNewGigHandler),
webapp2.Route('/send_new_gig_handler', goemail.SendNewGigHandler),
diff --git a/member.py b/member.py
index 1658ea1..12008e8 100644
--- a/member.py
+++ b/member.py
@@ -315,9 +315,8 @@ def forget_member_from_key(the_member_key):
the_member_key.delete()
def get_member_from_urlsafe_key(urlsafe):
- """take a urlsafe key and cause an ancestor query to happen, to assure previous writes are committed"""
- untrusted_member=ndb.Key(urlsafe=urlsafe).get()
- return get_member_from_nickname(untrusted_member.nickname)
+ return ndb.Key(urlsafe=urlsafe).get()
+
def get_member(the_member_key):
@@ -469,6 +468,14 @@ def make_member_cal_dirty(the_member_key):
the_member.cal_feed_dirty = True
the_member.put()
+def get_member_keys_to_update_calfeed():
+ args=[
+ Member.cal_feed_dirty == True,
+ Member.last_calfetch != None
+ ]
+ member_query = Member.lquery(*args)
+ members = member_query.fetch(keys_only=True)
+ return members
def rest_member_info(the_member, include_id=True):
obj = { k:getattr(the_member,k) for k in ['display_name'] }
diff --git a/queue.yaml b/queue.yaml
index c6cc9d2..114f1f4 100644
--- a/queue.yaml
+++ b/queue.yaml
@@ -9,4 +9,9 @@ queue:
max_concurrent_requests: 1
retry_parameters:
task_retry_limit: 0
-
+- name: calfeedqueue
+ rate: 1/m
+ bucket_size: 10
+ max_concurrent_requests: 1
+ retry_parameters:
+ task_retry_limit: 0
\ No newline at end of file
diff --git a/templates/calview.html b/templates/calview.html
index ce96f72..faa2592 100644
--- a/templates/calview.html
+++ b/templates/calview.html
@@ -48,7 +48,7 @@
},
},
eventAfterAllRender: calCallback,
- {% if m and y %}
+ {% if defaultDate %}
defaultDate: moment( [ {{ y }}, {{ m }} ] ),
{% endif %}
})