Пример #1
0
        def decorated(*args, **kwargs):

            print request.values

            if 'CallSid' not in request.values:
                return abort(401, 'Request must be a signed Twilio request.')

            if validate and False:

                validator = RequestValidator(settings.TWILIO_AUTH_TOKEN)
                sig_header = request.headers.get('X-Twilio-Signature', '')

                if request.method == 'POST':
                    vparams = request.form
                    vurl = request.url
                else:
                    vparams = {}
                    vurl = request.url

                # validator params are called URL, POST vars, and signature
                if not validator.validate(vurl, vparams, sig_header):
                    return abort(401, 'Request signature could not be validated')

            # load the call from Mongo or create if one does not exist
            g.call = load_call(request.values['CallSid'], request.values)

            g.zipcode = read_context('zipcode', None)
            g.legislator = read_context('legislator', None)

            twilio_response = func(*args, **kwargs)

            return Response(str(twilio_response), mimetype='application/xml')
Пример #2
0
def subscribe_to_bill_updates():

    r = twiml.Response()

    bill_id = read_context('bill_id')
    if not bill_id:
        r.redirect(url_for('.bills'))
        return r

    bill = data.get_bill_by_id(bill_id)
    if not bill:
        r.say("No bill was found matching %s" % bill_id)
        r.redirect(url_for('.bills'))
        return r

    if 'from' in g.call:

        params = {
            'phone': g.call['from'],
            'interest_type': 'item',
            'item_type': 'bill',
            'item_id': bill_id,
            'source': 'call_on_congress',
        }

        if data.subscribe_to_bill_updates(**params):
            r.say('You have been subscribed. A confirmation message has been sent to %s.' % " ".join(g.call['from'][1:]))
        else:
            r.say('Sorry, there was an error subscribing you.')

    else:
        r.say('Sorry, we were unable to identify your phone number.')

    r.redirect(url_for('.bills'))
    return str(r)
Пример #3
0
def load_member_for(bioguide):
    for legislator in read_context('legislators', []):
        if legislator['bioguide_id'] == bioguide:
            write_context('legislator', legislator)
            return legislator
    legislator = data.legislator_by_bioguide(bioguide)
    write_context('legislator', legislator)
    return legislator
Пример #4
0
def member_bio():
    """Biography for a specific member of congress"""

    r = twiml.Response()
    bioguide = g.request_params['bioguide_id']
    legislator = read_context('legislator', load_member_for(bioguide))
    with r.gather(numDigits=1, timeout=1, action=url_for('.member_bio', bioguide_id=bioguide)) as rg:
        rg.say(data.legislator_bio(legislator) or 'There is no biography available for this legislator.')

    return next_action(r, default=url_for('.member', bioguide_id=bioguide))
Пример #5
0
def call_member():
    """Calls the DC office of a member of congress"""

    r = twiml.Response()
    bioguide = g.request_params['bioguide_id']
    legislator = read_context('legislator', load_member_for(bioguide))
    r.say("Connecting you to %s at %s" % (legislator['fullname'], legislator['phone']))
    with r.dial() as rd:
        rd.number(legislator['phone'])

    return r
Пример #6
0
def member_donors():
    """Top campaign donors for a member of congress"""

    r = twiml.Response()
    bioguide = g.request_params['bioguide_id']
    legislator = read_context('legislator', load_member_for(bioguide))
    contribs = data.top_contributors(legislator)
    script = " ".join("%(name)s contributed $%(total_amount)s.\n" % c for c in contribs)
    with r.gather(numDigits=1, timeout=1, action=url_for('.member_donors', bioguide_id=bioguide)) as rg:
        rg.say(script)

    return next_action(r, default=url_for('.member'))
Пример #7
0
def member_votes():
    """Recent votes by a member of congress"""

    r = twiml.Response()
    bioguide = g.request_params['bioguide_id']
    legislator = read_context('legislator', load_member_for(bioguide))
    votes = data.recent_votes(legislator)
    script = " ".join("On %(question)s. Voted %(voted)s. . The vote %(result)s.\t" % v for v in votes)
    with r.gather(numDigits=1, timeout=1, action=url_for('.member_votes', bioguide_id=bioguide)) as rg:
        rg.say("Recent votes for %s. %s" % (legislator['fullname'], script))

    return next_action(r, default=url_for('.member', bioguide_id=bioguide))
Пример #8
0
def member():
    """Menu for a specific member of congress"""

    r = twiml.Response()

    bioguide = g.request_params['bioguide_id']
    legislator = read_context('legislator', load_member_for(bioguide))
    if 'Digits' in g.request_params.keys():
        return handle_selection(r, menu='member', selection=g.request_params['Digits'], params={'bioguide_id': bioguide})

    r.say(MENU['member']['name'] % legislator['fullname'])
    with r.gather(numDigits=1, timeout=settings.INPUT_TIMEOUT, action=url_for('.member', bioguide_id=bioguide)) as rg:
        rg.say("""Press 1 to hear a short biography.
                  Press 2 for a list of top campaign donors.
                  Press 3 for recent votes in congress.
                  Press 4 to call this representative's Capitol Hill office.""")
        rg.say("""To return to the previous menu, press 9.""")

    r.redirect(url_for('.member', bioguide_id=bioguide))
    return r
Пример #9
0
def select_bill():
    """Meta-route for handling multiple bills returned from search"""

    r = twiml.Response()
    query = {}
    bills = read_context('bills')
    if 'Digits' in g.request_params.keys() and bills:
        if g.request_params['Digits'] == '0':
            flush_context('bills')
            r.redirect(url_for('.search_bills'))
        try:
            sel = int(g.request_params['Digits'])
            bill = bills[sel - 1]
            query.update(bill_id=bill['bill_id'])
            r.redirect(url_for('.bill', **query))
            return r
        except:
            r.say("No bill matched your selection.")

    r.redirect(url_for('.search_bills', **query))
    return r
Пример #10
0
def bioguide_selection():
    """Ensures a Bioguide ID is present in request params before proceeding with call flow.
       This is not stored in the context, only passed in params. Logic as follows:
        - If a get param is sent, return.
        - If a list of possible legislators is stored in context, and a choice was passed,
            append the choice's Bioguide ID to params and return.
        - If no list of legislators is present in context, prompt for zipcode and load legislators,
            then prompt for a selection.
    """
    r = twiml.Response()

    # Handle twimlet-style params
    if 'bioguide_id' in g.request_params.keys():
        digits = g.request_params.get('Digits')
        if digits == '9':
            if re.search(r'member\/[\w\d\/]+', request.path):
                r.redirect(url_for('.member', bioguide_id=g.request_params['bioguide_id']))
            else:
                del g.request_params['bioguide_id']
                r.redirect(url_for('.member'))
            return r
        elif digits == '0':
            r.redirect(url_for('.index'))
            return r
        return True

    # If Digits = 0, we're entering a new zip or going back
    if g.request_params.get('Digits') == '0':
        if len(read_context('legislators', [])):
            flush_context('zipcode')
            flush_context('legislators')
            r.redirect(url_for('.member'))
            return r
        else:
            r.redirect(url_for('.index'))
            return r

    # Make sure there's a legislators list in the call context.
    # If not, short-circuit to zip collection and repost to get legislator list
    # before prompting for a selection.
    legislators = read_context('legislators', [])
    if 'Digits' in g.request_params.keys() and len(legislators):
        if len(legislators) < 8 and g.request_params['Digits'] == '9':
            r.redirect(url_for('.index'))
            return r
        sel = int(g.request_params['Digits'])
        del g.request_params['Digits']
        try:
            legislator = read_context('legislators')[sel - 1]
            g.request_params['bioguide_id'] = legislator['bioguide_id']

            return True
        except:
            del g.request_params['Digits']
            r.say('%d is not a valid selection, please try again.' % sel)

    # If we don't have a bioguide, or legislators, or a zip selection,
    # skip this and get a zip code first.
    if not len(legislators) and not get_zip() and not 'Digits' in g.request_params.keys():
        return zipcode_selection()

    # If we do have a zip code selection, store it before trying to get legislators.
    if not len(legislators) and not get_zip():
        zipcode_selection()

    # If we have a zip and no legislators, load them.
    if not len(legislators):
        load_members_for(get_zip())
        legislators = read_context('legislators', [])

    # If there are legislators, prompt for a choice. If still nothing, fail and get a new zip.
    if len(legislators):
        with r.gather(numDigits=1, timeout=settings.INPUT_TIMEOUT) as rg:
            if len(legislators) > 3:
                rg.say("""Since your zip code covers more than one congressional district,
                          you will be provided with a list of all possible legislators that
                          may represent you. Please select from the following names:""")
            else:
                rg.say("""We identified your representatives in Congress.""")
                rg.say("""Please select from the following:""")
            options = [(l['fullname'], l['bioguide_id']) for l in legislators]
            script = " ".join("Press %i for %s." % (index + 1, o[0]) for index, o in enumerate(options))
            script += " Press 0 to enter a new zip code."
            if len(legislators) < 8:
                script += " Press 9 to return to the previous menu."
            rg.say(script)
    else:
        r.say("We were unable to locate any representatives for")
        r.say("%s." % get_zip())
        flush_context('zipcode')
        try:
            del g.request_params['Digits']
        except:
            pass

    r.redirect(request.path)
    return r