diff --git a/cloud/__init__.py b/cloud/__init__.py new file mode 100644 index 0000000..c7e3015 --- /dev/null +++ b/cloud/__init__.py @@ -0,0 +1,71 @@ +import logging + +import flask +from werkzeug.local import LocalProxy +from pillar.extension import PillarExtension + +EXTENSION_NAME = 'cloud' + + +class CloudExtension(PillarExtension): + def __init__(self): + self._log = logging.getLogger('%s.CloudExtension' % __name__) + + @property + def name(self): + return EXTENSION_NAME + + def flask_config(self): + """Returns extension-specific defaults for the Flask configuration. + + Use this to set sensible default values for configuration settings + introduced by the extension. + + :rtype: dict + """ + + # Just so that it registers the management commands. + from . import cli + + return {} + + def eve_settings(self): + """Returns extensions to the Eve settings. + + Currently only the DOMAIN key is used to insert new resources into + Eve's configuration. + + :rtype: dict + """ + + return {} + + def blueprints(self): + """Returns the list of top-level blueprints for the extension. + + These blueprints will be mounted at the url prefix given to + app.load_extension(). + + :rtype: list of flask.Blueprint objects. + """ + from . import routes + return [routes.blueprint] + + @property + def template_path(self): + import os.path + return os.path.join(os.path.dirname(__file__), 'templates') + + @property + def static_path(self): + import os.path + return os.path.join(os.path.dirname(__file__), 'static') + + +def _get_current_cloud(): + """Returns the Cloud extension of the current application.""" + return flask.current_app.pillar_extensions[EXTENSION_NAME] + + +current_cloud = LocalProxy(_get_current_cloud) +"""Cloud extension of the current app.""" diff --git a/cloud/cli.py b/cloud/cli.py new file mode 100755 index 0000000..67dcbb8 --- /dev/null +++ b/cloud/cli.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python + +import logging +from flask import current_app +from flask_script import Manager + +from pillar.cli import manager + +log = logging.getLogger(__name__) + +manager_cloud = Manager( + current_app, usage="Blender Cloud scripts") + + +@manager_cloud.command +def reconcile_subscribers(): + """For every user, check their subscription status with the store.""" + from pillar.auth.subscriptions import fetch_user + + users_coll = current_app.data.driver.db['users'] + unsubscribed_users = [] + for user in users_coll.find({'roles': 'subscriber'}): + print('Processing %s' % user['email']) + print(' Checking subscription') + user_store = fetch_user(user['email']) + if user_store['cloud_access'] == 0: + print(' Removing subscriber role') + users_coll.update( + {'_id': user['_id']}, + {'$pull': {'roles': 'subscriber'}}) + unsubscribed_users.append(user['email']) + + if not unsubscribed_users: + return + + print('The following users have been unsubscribed') + for user in unsubscribed_users: + print(user) + +manager.add_command("cloud", manager_cloud) diff --git a/cloud/routes.py b/cloud/routes.py new file mode 100644 index 0000000..3d84c8f --- /dev/null +++ b/cloud/routes.py @@ -0,0 +1,11 @@ +import logging + +from flask import Blueprint, render_template + +blueprint = Blueprint('cloud', __name__) +log = logging.getLogger(__name__) + + +@blueprint.route('/about') +def about(): + return render_template('about.html') diff --git a/cloud/templates/about.html b/cloud/templates/about.html new file mode 100644 index 0000000..9c16876 --- /dev/null +++ b/cloud/templates/about.html @@ -0,0 +1,252 @@ +{% extends 'layout.html' %} +{% block page_title %}Welcome{% endblock %} +{% block body %} +