Obtain subscription info from Store.

This was in Pillar, and is now moved to Blender Cloud. It's used to obtain
the subscription expiration date from Blender Store.
This commit is contained in:
Sybren A. Stüvel 2017-11-30 15:45:40 +01:00
parent d5d189de8c
commit 532bf60041
4 changed files with 80 additions and 3 deletions

View File

@ -38,7 +38,10 @@ class CloudExtension(PillarExtension):
# Just so that it registers the management commands.
from . import cli
return {}
return {
'EXTERNAL_SUBSCRIPTIONS_MANAGEMENT_SERVER': 'https://store.blender.org/api/',
'EXTERNAL_SUBSCRIPTIONS_TIMEOUT_SECS': 10,
}
def eve_settings(self):
"""Returns extensions to the Eve settings.

View File

@ -340,6 +340,8 @@ def emails():
def billing():
"""View the subscription status of a user
"""
from . import store
if current_user.has_role('protected'):
return abort(404) # TODO: make this 403, handle template properly
api = system_util.pillar_api()
@ -350,7 +352,7 @@ def billing():
group = Group.find(group_id, api=api)
groups.append(group.name)
store_user = pillar.api.blender_cloud.subscription.fetch_subscription_info(user.email)
store_user = store.fetch_subscription_info(user.email)
return render_template(
'users/settings/billing.html',

72
cloud/store.py Normal file
View File

@ -0,0 +1,72 @@
"""Blender Store interface."""
import logging
import typing
from pillar import current_app
log = logging.getLogger(__name__)
def fetch_subscription_info(email: str) -> typing.Optional[dict]:
"""Returns the user info dict from the external subscriptions management server.
:returns: the store user info, or None if the user can't be found or there
was an error communicating. A dict like this is returned:
{
"shop_id": 700,
"cloud_access": 1,
"paid_balance": 314.75,
"balance_currency": "EUR",
"start_date": "2014-08-25 17:05:46",
"expiration_date": "2016-08-24 13:38:45",
"subscription_status": "wc-active",
"expiration_date_approximate": true
}
"""
from requests.adapters import HTTPAdapter
import requests.exceptions
external_subscriptions_server = current_app.config['EXTERNAL_SUBSCRIPTIONS_MANAGEMENT_SERVER']
if log.isEnabledFor(logging.DEBUG):
import urllib.parse
log_email = urllib.parse.quote(email)
log.debug('Connecting to store at %s?blenderid=%s',
external_subscriptions_server, log_email)
# Retry a few times when contacting the store.
s = requests.Session()
s.mount(external_subscriptions_server, HTTPAdapter(max_retries=5))
try:
r = s.get(external_subscriptions_server,
params={'blenderid': email},
verify=current_app.config['TLS_CERT_FILE'],
timeout=current_app.config.get('EXTERNAL_SUBSCRIPTIONS_TIMEOUT_SECS', 10))
except requests.exceptions.ConnectionError as ex:
log.error('Error connecting to %s: %s', external_subscriptions_server, ex)
return None
except requests.exceptions.Timeout as ex:
log.error('Timeout communicating with %s: %s', external_subscriptions_server, ex)
return None
except requests.exceptions.RequestException as ex:
log.error('Some error communicating with %s: %s', external_subscriptions_server, ex)
return None
if r.status_code != 200:
log.warning("Error communicating with %s, code=%i, unable to check "
"subscription status of user %s",
external_subscriptions_server, r.status_code, email)
return None
store_user = r.json()
if log.isEnabledFor(logging.DEBUG):
import json
log.debug('Received JSON from store API: %s',
json.dumps(store_user, sort_keys=False, indent=4))
return store_user

View File

@ -15,7 +15,7 @@ style(type='text/css').
.settings-content
| {% if store_user['cloud_access'] %}
| {% if current_user.has_role('subscriber') %}
h3.subscription-active
i.pi-check
| Your subscription is active