0

This is a continuation of this question

What follows is an abbreviated version of the original code. I tried to include the most relevant parts and left out the part of the script used by a cron job which updates the Datastore with values.

Then, in the sendFollowUp() handler, a second cron job queries the Datastore for these values, then uses a push task queue to send these values as parameters which are ultimately used in a REST API call to another service that sends people(entities) in the Datastore an email.

What I can't figure out is how to follow-up a get request with a post request in the same handler without submitting a post request through a form. This needs to happen within the sendFollowUp handler. Most of the examples I have found include submitting a form. However, I don't want to do that. I just want it to work automatically with the cron job and task queue.

import webapp2
import datetime
from google.appengine.ext import db
from google.appengine.api import users
from google.appengine.api import taskqueue
import jinja2
import os

jinja_environment = jinja2.Environment(loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))

class emailJobs(db.Model):
    """ Models an a list of email jobs for each user """
    triggerid = db.StringProperty()  #Trig id
    recipientid_po = db.StringProperty() # id
    recipientlang = db.StringProperty()  #Language
    fu_email_sent = db.DateTimeProperty() 
    fuperiod = db.IntegerProperty() # (0 - 13)
    fu1 = db.DateTimeProperty() 
    fu2 = db.DateTimeProperty()

    @classmethod
    def update_fusent(cls, key_name, senddate):
        """ Class method that updates fu messages sent in the GAE Datastore """
        emailsjobs = cls.get_by_key_name(key_name)
        if emailsjobs is None:
            emailsjobs = cls(key_name=key_name)
        emailsjobs.fu_email_sent = senddate
        emailsjobs.put()

def timeStampFM(now):
    d = now.date()
    year = d.year
    month = d.month
    day = d.day
    t = now.time()
    hour = t.hour
    minute = t.minute + 5
    second = t.second
    today_datetime = datetime.datetime(year, month, day, hour, minute, second)
    return today_datetime


class MainPage(webapp2.RequestHandler):
    """ Main admin login page """
    def get(self):
        if users.get_current_user():
            url = users.create_logout_url(self.request.uri)
            url_linktext = 'Logout'
            urla = '/'
            url_admin = ""
            if users.is_current_user_admin():
                url = users.create_logout_url(self.request.uri)
                urla = "_ah/admin/"
                url_admin = 'Go to admin pages'
                url_linktext = 'Logout'

        else:
            url = users.create_login_url(self.request.uri)
            url_linktext = 'Login'

        template_values = {
            'url': url,
            'url_linktext': url_linktext,
            'url_admin': url_admin,
            'urla': urla,
            }

        template = jinja_environment.get_template('index.html')
        self.response.out.write(template.render(template_values))


class sendFollowUp(webapp2.RequestHandler):
    """ Queries Datastore for fu dates that match today's date, then adds them to a task queue """
    def get(self):

        now = datetime.datetime.now()
        now_dt = now.date() #today's date to compare with fu dates

        q = emailJobs.all()
        q.filter('fuperiod >', 0)
        q.filter('fuperiod <', 99)

        for part in q:
            guid = str(part.recipientid_po)
            lang = str(part.recipientlang)
            trigid = str(part.triggerid)

            if part.fuperiod == 1:
                fu1rawdt = part.fu1
                fu1dt = fu1rawdt.date()
                if fu1dt == now_dt:
                    follow_up = '1'

            if part.fuperiod == 2: # the values go up to 12 in the original code
                fu2rawdt = part.fu2
                fu2dt = fu2rawdt.date()
                if fu2dt == now_dt:
                    follow_up = '2'

        if follow_up != None:
            taskqueue.add(queue_name='emailworker', url='/emailworker', params={'guid': guid,
                                                                            'fu': follow_up,
                                                                            'lang': lang,
                                                                            'trigid': trigid,
                                                                            })
        self.redirect('/emailworker')


class pushQueue(webapp2.RequestHandler):
    """ Sends fu emails, updates the Datastore with datetime sent """

    def store_emails(self, trigid, senddate):
        db.run_in_transaction(emailJobs.update_fusent, trigid, senddate)

    def get(self):
        fu_messages = {'1': 'MS_x01', 
                       '2': 'MS_x02',
                       # the values go up to 12 in the original code
                       }
        langs = {'EN': 'English subject',
                 'ES': 'Spanish subject',
                 }

        fu = str(self.request.get('fu'))
        messageid = fu_messages[fu]

        lang = str(self.request.get('lang'))
        subject = langs[lang]

        now = datetime.datetime.now()
        senddate = timeStampFM(now)

        guid = str(self.request.get('guid'))
        trigid = str(self.request.get('trigid'))

        data = {}
        data['Subject'] = subject
        data['MessageID'] = messageid
        data['SendDate'] = senddate
        data['RecipientID'] = guid
        # Here I do something with data = {}

        self.store_emails(trigid, senddate)

    app = webapp2.WSGIApplication([('/', MainPage),
                       ('/cron/sendfu', sendFollowUp),
                       ('/emailworker', pushQueue)],
                       debug=True)
Community
  • 1
  • 1
655321
  • 411
  • 4
  • 26
  • I do not understand why you like to use a kind of internal post. Why not call a method or function. – voscausa Mar 06 '13 at 09:43

1 Answers1

0

I'm not sure I really understand your question, but can't you just create a POST request with the requests module?

Post Requests

>>> payload = {'key1': 'value1', 'key2': 'value2'}
>>> r = requests.post("http://httpbin.org/post", data=payload)

Also for easy task use have you seen the deferred library?

The deferred library lets you bypass all the work of setting up dedicated task handlers and serializing and deserializing your parameters by exposing a simple function, deferred.defer(). To call a function later, simply pass the function and its arguments to deferred.defer

Link

Paul Collingwood
  • 9,053
  • 3
  • 23
  • 36
  • Hi. Thanks! I think deferred sounds like the way to go but I don't quite understand how to integrate it with my current code. – 655321 Mar 06 '13 at 19:25