Skip to content

Instantly share code, notes, and snippets.

@juliomistral
Created March 30, 2012 17:25
Show Gist options
  • Save juliomistral/2253128 to your computer and use it in GitHub Desktop.
Save juliomistral/2253128 to your computer and use it in GitHub Desktop.
import requests
import simplejson
from datetime import datetime
from isodate import parse_duration
from django.core.cache import cache
from django.conf import settings
from yola.services import ProductService
SUBSCRIPTION_TYPES_FOR = {
'40000101' : 'silver',
'40000035' : 'silver',
}
GRACE_PERIOD_FOR = {
'silver' : 'P7D',
}
BILLING_PERIOD_FOR = {
'silver' : 'P0D',
}
import logging
log = logging.getLogger(__name__)
def _get_product_definition(sku):
"""
Retrieve the product definition for the provided SKU. Some magic will occur to determine what project
it's running in to choose the correct method of product retrieval (remote API vs. model retrieval).
"""
cache_key = 'michango.subscription.product.%s' % sku
product_def = cache.get(cache_key)
if product_def is not None:
return product_def
response = ProductService().get_last_available_product(sku=sku)
log.debug(response)
if response['http_code'] == 200:
product_def = response['response']
else:
raise ValueError('No product was found for the provided sku: %s' % sku)
cache.set(cache_key, product_def)
return product_def
class SubscriptionManager(object):
def __init__(self, user, endpoint_url=None):
self.user = user
if endpoint_url is None:
self.endpoint_url = settings.MICHANGO_URL
else:
self.endpoint_url = endpoint_url
def get_all_subscriptions(self):
subscriptions_url = '%s/user/%s/subscriptions' % (self.endpoint_url, self.user.id)
response = requests.get(subscriptions_url)
log.debug(response)
if response.status_code != 200:
raise Exception('Error occurred contacting subscription end-point: %s' % response.status_code)
raw_subs = simplejson.loads(response.content)
return Subscription.from_list(raw_subs)
def add_subscription(self, sku, expiry_date=None):
"""
Takes the provided subscription product and adds it to the user's subscription set. The client
can override the expiry date (i.e., a pro rata purchase), otherwise the expiry date will be
today + the product's term.
"""
product_def = _get_product_definition(sku)
product_meta = product_def['product_meta']
if 'term' not in product_meta:
raise Exception('Provided sku was not for a subscription product. No term in product meta.')
term = product_meta['term']
today = datetime.today().replace(tzinfo=None)
if expiry_date is None:
term_duration = parse_duration(term)
expiry_date = today + term_duration
data = {
'user_id' : self.user.id,
'status' : 'active',
'term' : term,
'sku' : sku,
'type' : SUBSCRIPTION_TYPES_FOR[sku],
'start_date' : today,
'expiry_date' : expiry_date,
'deprovision_date' : self._calculate_deprovision_date(expiry_date, SUBSCRIPTION_TYPES_FOR[sku]),
'billing_date' : self._calculate_billing_date(expiry_date, SUBSCRIPTION_TYPES_FOR[sku]),
}
log.debug('Posting to subscription end-point with data: %s' % data)
subscriptions_url = '%s/user/%s/subscriptions/' % (self.endpoint_url, self.user.id)
headers = {'Accepts': 'application/json'}
response = requests.post(subscriptions_url, data=data, headers=headers)
log.debug('Response from posting new subscription: %s' % response)
if response.status_code != 200:
raise Exception('Error occurred contacting subscription end-point: %s' % response.status_code)
def _calculate_deprovision_date(self, expiry_date, type):
grace_period_duration = parse_duration(GRACE_PERIOD_FOR[type])
return expiry_date + grace_period_duration
def _calculate_billing_date(self, expiry_date, type):
billing_date_duration = parse_duration(BILLING_PERIOD_FOR[type])
return expiry_date - billing_date_duration
class Subscription(object):
def __init__(self, **kwargs):
for key, value in kwargs.iteritems():
setattr(self, key, value)
@classmethod
def from_list(cls, raw_data_list):
subs = []
for item in raw_data_list:
subs.append(Subscription(**item))
return subs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment