Last active
August 29, 2015 14:26
-
-
Save maracuja/b2025277f7e370c862ea to your computer and use it in GitHub Desktop.
Device Deletion and Synchronisation Code
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
''' | |
Runs when a device is deleted in the Skylark API. delete | |
''' | |
def sync_deletion(sender, instance, *args, **kwargs): | |
try: | |
if instance.removed: | |
delete_device(instance) | |
''' | |
when synching with ooyala we send a hash of the user id because that's | |
what we use on the front end. | |
''' | |
user = instance.customer.user | |
queued_sync_devices.delay(user) | |
except: | |
pass |
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
''' | |
Send a sync_devices call to the queue | |
''' | |
def queued_sync_devices(user): | |
sync_devices(user) | |
return True |
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
def sync_devices(user): | |
logging.info('-- calling sync_devices -----------------------------------') | |
""" | |
when synching with ooyala we send a hash of the user id because that's | |
what we use on the front end. | |
""" | |
Customer = swapper.load_model('box_office', 'Customer') | |
mDevice = get_model_class(label='ooyala', model='device') | |
mAccount = get_model_class(label='ooyala', model='account') | |
customer = Customer.objects.get(user__id=user.id) | |
user_hash = get_user_hash(customer) | |
account = get_default_account() | |
try: | |
api = OoyalaAPI(account.api_key, settings.OOYALA_SECRETS[account.slug], OOYALA_ENDPOINT) | |
devices = api.get('device_management/pcode/%s/account_id/%s/devices' % (account.pcode, user_hash,)) | |
except: | |
logging.info('failed to retrieve devices from ooyala') | |
return None | |
if devices and 'devices' in devices: | |
for device in devices['devices']: | |
try: | |
db_device = mDevice.objects.get(public_id=device['public_device_id']) | |
except: | |
db_device = mDevice() | |
db_device.public_id = device['public_device_id'] | |
db_device.user_agent = device['user_agent'] | |
if device['nickname']: | |
db_device.nickname = device['nickname'] | |
else: | |
db_device.nickname = '' | |
db_device.registered = datetime.strptime(device['registration_time'], '%Y-%m-%d %H:%M:%S +0000') | |
db_device.customer = customer | |
db_device.save() | |
else: | |
logging.info('no devices found for %s' % user_hash) | |
def delete_device(device): | |
logging.info('-- calling delete_device ----------------------------------------------------------------------') | |
try: | |
""" | |
when synching with ooyala we send a hash of the user id because that's | |
what we use on the front end. | |
""" | |
user_hash = get_user_hash(device.customer) | |
account = get_default_account() | |
api = OoyalaAPI(account.api_key, settings.OOYALA_SECRETS[account.slug], OOYALA_ENDPOINT) | |
api.delete('device_management/pcode/%s/account_id/%s/devices/%s' % (account.pcode, user_hash, device.public_id,)) | |
logging.info('deleted from ooyala: %s' % device) | |
except: | |
logging.info('not deleted from ooyala') |
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
import hashlib, base64, urllib, httplib, time, logging, json, sha | |
from datetime import datetime | |
from skylark.utils.utils import get_model_class, get_user_hash | |
from django.conf import settings | |
import swapper | |
HTTP_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'] | |
DEFAULT_EXPIRATION_WINDOW = 1800 | |
DEFAULT_ROUND_UP_TIME = 300 | |
API_VERSION = 'v2' | |
DEFAULT_BASE_URL = 'rl.ooyala.com' | |
DEFAULT_CACHE_BASE_URL = 'rl.ooyala.com' | |
OOYALA_ENDPOINT = 'rl.ooyala.com' | |
logging.basicConfig(format='',level=logging.INFO) | |
class OoyalaAPI(object): | |
def __init__(self, api_key, secret_key, base_url=DEFAULT_BASE_URL, | |
cache_base_url=DEFAULT_CACHE_BASE_URL, | |
expiration=DEFAULT_EXPIRATION_WINDOW): | |
"""OoyalaAPI Constructor | |
Type signature: | |
(str, str, str:DEFAULT_BASE_URL, int:DEFAULT_EXPIRATION_WINDOW) -> OoyalaAPI | |
Parameters: | |
api_key - The API key | |
secret_key - The secret key | |
base_url - the url's base | |
expiration - the expiration window, in seconds | |
Example: | |
api = OoyalaAPI("..", "..") | |
""" | |
self._secret_key = secret_key | |
self._api_key = api_key | |
self._base_url = base_url | |
self._cache_base_url = cache_base_url | |
self._expiration_window = expiration | |
self._response_headers = [()] | |
def send_request(self, http_method, relative_path, body=None, params={}): | |
"""Send a request. | |
Type signature: | |
(str, str, str:None, dict:{}) -> json str | None | |
Parameters: | |
http_method - the http method | |
relative_path - the url's relative path | |
body - the request's body | |
params - the query parameters | |
Example: | |
api = OoyalaAPI(secret_key, api_key) | |
response = api.send_request('GET', 'players/2kj390') | |
response = api.send_request('PATCH', 'players/2kj390', "{'name': 'my new player name'}") | |
""" | |
# create the url | |
if relative_path[:17] == 'device_management': | |
path = '/%s' % relative_path | |
else: | |
path = '/%s/%s' % (API_VERSION,relative_path,) | |
# Convert the body to JSON format | |
json_body = '' | |
if (body is not None): | |
json_body = json.dumps(body) if type(body) is not str else body | |
url = self.build_path_with_authentication_params(http_method, path, params, json_body) | |
if url is None: | |
return None | |
if relative_path[:17] == 'device_management': | |
base_url = self.base_url | |
else: | |
base_url = self.base_url if http_method != 'GET' else self.cache_base_url | |
connection = httplib.HTTPSConnection(base_url) | |
#hack needed when a PUT request has an empty body | |
headers = {} | |
if (body is None): | |
headers['Content-length'] = 0 | |
#Make the request | |
connection.request(http_method, url, json_body, headers) | |
#get the response | |
response = connection.getresponse() | |
# import pdb;pdb.set_trace() | |
data = response.read() | |
self._response_headers = response.getheaders() | |
connection.close() | |
if (response.status >= httplib.BAD_REQUEST): | |
return None | |
else: | |
if (len(data)==0): | |
data = "true" | |
return json.loads(data) | |
def get(self, path, query={}): | |
"""Send a GET request. | |
Type signature: | |
(str, srt:{}) -> json str | None | |
Parameters: | |
path - the url's path | |
query - the query parameters | |
Example: | |
api = Ooyala(...) | |
response = api.get('players/2kj390') | |
""" | |
return self.send_request('GET', path, None, query) | |
def put(self, path, body): | |
"""Send a PUT request. | |
Type signature: | |
(str, object) -> json str | None | |
Parameters: | |
path - the url's path | |
body - the request's body | |
Example: | |
api = Ooyala(...) | |
response = api.put('players/2kj390/metadata', {'skin' : 'branded'}) | |
""" | |
return self.send_request('PUT', path, body) | |
def post(self, path, body): | |
"""Send a POST request. | |
Type signature: | |
(str, object) -> json str | None | |
Parameters: | |
path - the url's path | |
body - the request's body | |
Example: | |
api = Ooyala(...) | |
response = api.post('players/', {'name' : 'sample player'}) | |
""" | |
return self.send_request('POST', path, body) | |
def patch(self, path, body): | |
"""Send a PATCH request. | |
Type signature: | |
(str, object) -> json str | None | |
Parameters: | |
path - the url's path | |
body - the request's body | |
Example: | |
api = Ooyala(...) | |
response = api.patch('players/2kj390', {'name' : 'renamed player'}) | |
""" | |
return self.send_request('PATCH', path, body) | |
def delete(self, path): | |
"""Send a DELETE request. | |
Type signature: | |
(str) -> json str | None | |
Key Parameters: | |
'path' - the url's path | |
Example: | |
api = Ooyala(...) | |
response = api.delete('players/2kj390') | |
""" | |
return self.send_request('DELETE', path) | |
def generate_signature(self, http_method, path, params, body=''): | |
"""Generates the signature for a request. | |
Type signature: | |
(str, str, dict, str:'') -> str | |
Parameters: | |
http_method - the http method | |
path - the url's path | |
body - the request's body (a JSON encoded string) | |
params - query parameters | |
""" | |
signature = str(self.secret_key) + http_method.upper() + path | |
for key, value in sorted(params.iteritems()): | |
signature += key + '=' + str(value) | |
# This is neccesary on python 2.7. if missing, | |
# signature+=body with raise an exception when body are bytes (image data) | |
signature = signature.encode('ascii') | |
signature += body | |
signature = base64.b64encode(hashlib.sha256(signature).digest())[0:43] | |
signature = urllib.quote_plus(signature) | |
return signature | |
def build_path(self, path, params): | |
"""Build the path for a request. | |
Type signature: | |
(str, dict) -> str | |
Parameters: | |
path - the url's path | |
params - the query parameters | |
""" | |
# a local function which check if item is a query param | |
f = lambda k: k == 'where' or k == 'orderby' or k == 'limit' or k == 'page_token' | |
url = path + '?' | |
url += "&".join(["%s=%s" % (key, urllib.quote_plus(str(value)) if f(key) else value) for key, value in params.items()]) | |
return url | |
def build_path_with_authentication_params(self, http_method, path, params, body): | |
"""Build the path for a Ooyala API request, including authentication parameters. | |
Type signature: | |
(str, str, str, dict, str) -> str | |
Parameters: | |
http_method - the http method | |
path - the url's path | |
params - the query parameters | |
body - the request's body | |
""" | |
if (http_method not in HTTP_METHODS) or (self.api_key is None) or (self.secret_key is None): | |
return None | |
authentication_params = dict(params) | |
#add the ooyala authentication params | |
authentication_params['api_key'] = str(self.api_key) | |
authentication_params['expires'] = str(self.expires) | |
authentication_params['signature'] = self.generate_signature(http_method, path, authentication_params, body) | |
return self.build_path(path, authentication_params) | |
@property | |
def response_headers(self): | |
"""Get the response's header from last request made. | |
Type signature: | |
() -> [(header,value)] | |
""" | |
return self._response_headers | |
def get_secret_key(self): | |
"""Secret Key getter. | |
Type signature: | |
() -> str | |
Example: | |
api = OoyalaAPI(...) | |
print 'the secret key is ', api.secret_key | |
""" | |
return self._secret_key | |
def set_secret_key(self, value): | |
"""Secret Key setter. | |
Type signature: | |
(str) -> None | |
Parameters: | |
value - the secret key to be set | |
Example: | |
api = OoyalaAPI(...) | |
api.secret_key = "83jja" | |
print 'the new secret key is ', api.secret_key | |
""" | |
self._secret_key = value | |
secret_key = property(get_secret_key, set_secret_key) | |
def get_api_key(self): | |
"""API Key getter. | |
Type signature: | |
() -> str | |
Example: | |
api = OoyalaAPI(...) | |
print 'the API key is ', api.api_key | |
""" | |
return self._api_key | |
def set_api_key(self, value): | |
"""API Key setter. | |
Type signature: | |
(str) -> None | |
Parameters: | |
value - the API key to be set | |
Example: | |
api = OoyalaAPI(...) | |
api.api_key = "332kka" | |
print 'the new API key is ', api.api_key | |
""" | |
self._api_key = value | |
api_key = property(get_api_key, set_api_key) | |
def get_base_url(self): | |
"""Base url getter. | |
Type signature: | |
() -> str | |
Example: | |
api = OoyalaAPI(...) | |
print 'the base url is ', api.base_url | |
""" | |
return self._base_url | |
def set_base_url(self, value): | |
"""Base url setter. | |
Type signature: | |
(str) -> None | |
Parameters: | |
value - the url's base to be set | |
Example: | |
api = OoyalaAPI(...) | |
api.base_url = "cache.api.ooyala.com" | |
print 'the new url's base is ', api.base_url | |
""" | |
self._base_url = value | |
base_url = property(get_base_url, set_base_url) | |
def get_cache_base_url(self): | |
"""Cache base url getter. | |
Type signature: | |
() -> str | |
Example: | |
api = OoyalaAPI(...) | |
print 'the cache base url is ', api.cache_base_url | |
""" | |
return self._cache_base_url | |
def set_cache_base_url(self, value): | |
"""Cache base url setter. | |
Type signature: | |
(str) -> None | |
Parameters: | |
value - the url's base to be set | |
Example: | |
api = OoyalaAPI(...) | |
api.base_url = "cache.api.ooyala.com" | |
print 'the new url's base is ', api.cache_base_url | |
""" | |
self._cache_base_url = value | |
cache_base_url = property(get_cache_base_url, set_cache_base_url) | |
def get_expiration_window(self): return self._expiration_window | |
def set_expiration_window(self, value): self._expiration_window = value | |
def del_expiration_window(self): del self._expiration_window | |
expiration_window = property(get_expiration_window, set_expiration_window, del_expiration_window) | |
@property | |
def expires(self): | |
"""Computes the expiration's time | |
Type signature: | |
() -> int | |
""" | |
now_plus_window = int(time.time()) + self.expiration_window | |
return now_plus_window + DEFAULT_ROUND_UP_TIME - (now_plus_window % DEFAULT_ROUND_UP_TIME) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment