-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added access control decorator for cross-origin AJAX requests, added …
…FFTF leaderboard hooks to log complete calls (optional and wont affect anything if not passed in)
- Loading branch information
1 parent
87db5ac
commit c208f25
Showing
6 changed files
with
156 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
from datetime import timedelta | ||
from flask import make_response, request, current_app | ||
from functools import update_wrapper | ||
|
||
|
||
def crossdomain(origin=None, methods=None, headers=None, | ||
max_age=21600, attach_to_all=True, | ||
automatic_options=True): | ||
if methods is not None: | ||
methods = ', '.join(sorted(x.upper() for x in methods)) | ||
if headers is not None and not isinstance(headers, basestring): | ||
headers = ', '.join(x.upper() for x in headers) | ||
if not isinstance(origin, basestring): | ||
origin = ', '.join(origin) | ||
if isinstance(max_age, timedelta): | ||
max_age = max_age.total_seconds() | ||
|
||
def get_methods(): | ||
if methods is not None: | ||
return methods | ||
|
||
options_resp = current_app.make_default_options_response() | ||
return options_resp.headers['allow'] | ||
|
||
def decorator(f): | ||
def wrapped_function(*args, **kwargs): | ||
if automatic_options and request.method == 'OPTIONS': | ||
resp = current_app.make_default_options_response() | ||
else: | ||
resp = make_response(f(*args, **kwargs)) | ||
if not attach_to_all and request.method != 'OPTIONS': | ||
return resp | ||
|
||
h = resp.headers | ||
|
||
h['Access-Control-Allow-Origin'] = origin | ||
h['Access-Control-Allow-Methods'] = get_methods() | ||
h['Access-Control-Max-Age'] = str(max_age) | ||
if headers is not None: | ||
h['Access-Control-Allow-Headers'] = headers | ||
return resp | ||
|
||
f.provide_automatic_options = False | ||
return update_wrapper(wrapped_function, f) | ||
return decorator |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import json | ||
import grequests | ||
|
||
class FFTFLeaderboard(): | ||
|
||
debug_mode = False | ||
pool_size = 1 | ||
|
||
def __init__(self, debug_mode, pool_size): | ||
|
||
self.debug_mode = debug_mode | ||
|
||
def log_call(self, params, campaign, request): | ||
|
||
if params['fftfCampaign'] == None or params['fftfReferer'] == None: | ||
return | ||
|
||
i = int(request.values.get('call_index')) | ||
|
||
kwds = { | ||
'campaign_id': campaign['id'], | ||
'member_id': params['repIds'][i], | ||
'zipcode': params['zipcode'], | ||
'phone_number': params['userPhone'], | ||
'call_id': request.values.get('CallSid', None), | ||
'status': request.values.get('DialCallStatus', 'unknown'), | ||
'duration': request.values.get('DialCallDuration', 0) | ||
} | ||
data = json.dumps(kwds) | ||
|
||
self.post_to_leaderboard( | ||
params['fftfCampaign'], | ||
'call', | ||
data, | ||
params['fftfReferer'], | ||
params['fftfSession']) | ||
|
||
def log_complete(self, params, campaign, request): | ||
|
||
if params['fftfCampaign'] == None or params['fftfReferer'] == None: | ||
return | ||
|
||
self.post_to_leaderboard( | ||
params['fftfCampaign'], | ||
'calls_complete', | ||
'yay', | ||
params['fftfReferer'], | ||
params['fftfSession']) | ||
|
||
def post_to_leaderboard(self, fftf_campaign, stat, data, host, session): | ||
|
||
debug_mode = self.debug_mode | ||
|
||
def finished(res, **kwargs): | ||
if debug_mode: | ||
print "FFTF Leaderboard call complete: %s" % res | ||
|
||
data = { | ||
'campaign': fftf_campaign, | ||
'stat': stat, | ||
'data': data, | ||
'host': host, | ||
'session': session | ||
} | ||
|
||
if self.debug_mode: | ||
print "FFTF Leaderboard sending: %s" % data | ||
|
||
url = 'https://leaderboard.fightforthefuture.org/log' | ||
req = grequests.post(url, data=data, hooks=dict(response=finished)) | ||
job = grequests.send(req, grequests.Pool(self.pool_size)) | ||
|
||
return |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters