|
|
|
@ -10,11 +10,12 @@
|
|
|
|
|
The store must be prefixed with an authentication module, because customers must be signed in before making a purchase.
|
|
|
|
|
"""
|
|
|
|
|
from __future__ import division
|
|
|
|
|
from flask import Flask, request, session, render_template,Response
|
|
|
|
|
from flask import Flask, request, session, render_template
|
|
|
|
|
from flask_session import Session
|
|
|
|
|
from flask_cors import CORS
|
|
|
|
|
# import Domain
|
|
|
|
|
# from User import User
|
|
|
|
|
# from couchdbkit import Server, Document
|
|
|
|
|
from flask_pymongo import PyMongo
|
|
|
|
|
from flask_mongo_sessions import MongoDBSessionInterface
|
|
|
|
|
|
|
|
|
|
import stripe
|
|
|
|
|
import json
|
|
|
|
|
# from StringIO import StringIO
|
|
|
|
@ -25,6 +26,9 @@ from transport import factory
|
|
|
|
|
# from store import Store
|
|
|
|
|
import store
|
|
|
|
|
from datetime import datetime
|
|
|
|
|
import numpy as np
|
|
|
|
|
import requests
|
|
|
|
|
|
|
|
|
|
# from utils.transport import Couchdb, CouchdbReader
|
|
|
|
|
PORT = 8100 if 'port' not in PARAMS else int(PARAMS['port']) ;
|
|
|
|
|
path = PARAMS['path'] #os.environ['CONFIG']
|
|
|
|
@ -41,9 +45,8 @@ stripe.api_key = stripe_keys['secret_key'].strip()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app = Flask(__name__)
|
|
|
|
|
# CORS(app)
|
|
|
|
|
# COUCHDB = Server(uri=CONFIG['couchdb']['uri']) ;
|
|
|
|
|
# SYS_STORE = CONFIG['couchdb']
|
|
|
|
|
CORS(app)
|
|
|
|
|
|
|
|
|
|
SYS_STORE = CONFIG['store']
|
|
|
|
|
@app.route("/")
|
|
|
|
|
def index():
|
|
|
|
@ -66,18 +69,67 @@ def get_plans_json(id):
|
|
|
|
|
# Log this shit or not
|
|
|
|
|
pass
|
|
|
|
|
return "[]",HEADER
|
|
|
|
|
|
|
|
|
|
@app.route("/store",methods=['POST','PUT'])
|
|
|
|
|
def to_session():
|
|
|
|
|
"""
|
|
|
|
|
This function will store/persist session variables for reuse
|
|
|
|
|
"""
|
|
|
|
|
info = request.json
|
|
|
|
|
if info :
|
|
|
|
|
for key in info :
|
|
|
|
|
session[key] = info[key]
|
|
|
|
|
return "{}"
|
|
|
|
|
@app.route("/signup",methods=['GET','POST'])
|
|
|
|
|
def get_stripe():
|
|
|
|
|
def signup():
|
|
|
|
|
"""
|
|
|
|
|
This function will signup a user to a plan or upgrade them if necessary
|
|
|
|
|
The assumption here is one product - one plan
|
|
|
|
|
:request.form stripeToken (optional)
|
|
|
|
|
"""
|
|
|
|
|
if request.method == 'GET' :
|
|
|
|
|
if 'auth' not in session :
|
|
|
|
|
return "0",403
|
|
|
|
|
_object = {"data-key":CONFIG['stripe']['pub'].strip()}
|
|
|
|
|
return json.dumps(_object)
|
|
|
|
|
return json.dumps(_object),{"Content-Type":"application/json"}
|
|
|
|
|
else:
|
|
|
|
|
print (request.args)
|
|
|
|
|
return 1
|
|
|
|
|
#
|
|
|
|
|
# We are receiving a call from stripe framework and we need create a charge for this
|
|
|
|
|
# @NOTE: https://stripe.com/docs/payments/accept-a-payment-charges#web-create-charge
|
|
|
|
|
token = request.form['stripeToken'] if 'stripeToken' in request.form else None
|
|
|
|
|
email = session['auth']['user']['uid']
|
|
|
|
|
plan_id = session['plan']['id']
|
|
|
|
|
id = session['product']['name']
|
|
|
|
|
mystore = store.factory.instance(name=id,email=email)
|
|
|
|
|
user = mystore.user
|
|
|
|
|
plans = user.plan.info()
|
|
|
|
|
plans = [plans] if isinstance(plans,dict) else plans
|
|
|
|
|
|
|
|
|
|
has_plan = [1 for item in plans if item['id'] == plan_id]
|
|
|
|
|
if np.sum(has_plan) == 0 and len(plans) == 0:
|
|
|
|
|
|
|
|
|
|
mystore.subscribe(id=plan_id,email=email)
|
|
|
|
|
elif np.sum(has_plan)==0 and len(plans) > 0:
|
|
|
|
|
#
|
|
|
|
|
# We should upgrade/downgrade the current plan
|
|
|
|
|
#
|
|
|
|
|
mystore.plan.upgrade(plan_id,email)
|
|
|
|
|
uri = session['product']['metadata']['uri'] if 'uri' in session['product']['metadata'] else '#status'
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
|
# @NOTE:
|
|
|
|
|
# This function assumes one product one plan, operations outside of this scope will require a new function
|
|
|
|
|
return """
|
|
|
|
|
<script>
|
|
|
|
|
window.location = ':uri'
|
|
|
|
|
</script>
|
|
|
|
|
""".replace(":uri",uri)
|
|
|
|
|
|
|
|
|
|
@app.route("/ui/signup/<id>",methods=['GET','PUT'])
|
|
|
|
|
def signup(id):
|
|
|
|
|
def signup_form(id):
|
|
|
|
|
"""
|
|
|
|
|
This function loads the signup form with cloud-view authentication support
|
|
|
|
|
This allows us to know who is signing up or upgrading their plan
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
mystore = store.factory.instance(name=id)
|
|
|
|
@ -92,6 +144,10 @@ def signup(id):
|
|
|
|
|
return render_template("signup.html",**args)
|
|
|
|
|
@app.route("/ui/<id>")
|
|
|
|
|
def get_plans_ui(id):
|
|
|
|
|
"""
|
|
|
|
|
This function loads the form for signup and information about the various plans for a given product.
|
|
|
|
|
:id name of the products
|
|
|
|
|
"""
|
|
|
|
|
mystore = store.factory.instance(name=id)
|
|
|
|
|
#
|
|
|
|
|
# sort plans by
|
|
|
|
@ -102,7 +158,28 @@ def get_plans_ui(id):
|
|
|
|
|
args['theme'] = 'theme-clouds'
|
|
|
|
|
# print (mystore.product.keys())
|
|
|
|
|
session['cloud-view'] = CONFIG['cloud-view']
|
|
|
|
|
session['product'] = mystore.product
|
|
|
|
|
return render_template('plans.html',**args)
|
|
|
|
|
@app.route("/goto/<id>",methods=['POST','GET'])
|
|
|
|
|
def redirect(id ) :
|
|
|
|
|
"""
|
|
|
|
|
This function will redirect to a given product page given a payload. The payload is intended to set the a session
|
|
|
|
|
:info
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
mystore = store.factory.instance(name=id)
|
|
|
|
|
args = {"context":CONTEXT,"product":mystore.product}
|
|
|
|
|
HEADER = {"Location":mystore.product['metadata']['uri']}
|
|
|
|
|
info = request.json
|
|
|
|
|
if info :
|
|
|
|
|
session['auth'] = info['auth']
|
|
|
|
|
session['plan'] = info['plan']
|
|
|
|
|
session['product'] = mystore.product
|
|
|
|
|
return "1",HEADER
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
|
|
return "0",403
|
|
|
|
|
pass
|
|
|
|
|
@app.route("/init/<product>",methods=['POST'])
|
|
|
|
|
def init(product):
|
|
|
|
|
"""
|
|
|
|
@ -116,34 +193,7 @@ def init(product):
|
|
|
|
|
#
|
|
|
|
|
uid = request.headers['uid']
|
|
|
|
|
plan_id = request.headers['pid'] if 'pid' in request.headers else None
|
|
|
|
|
#
|
|
|
|
|
# We should just pull the factory method and get a storage handler to handle the logs
|
|
|
|
|
#
|
|
|
|
|
# store = dict(CONFIG['couchdb'])
|
|
|
|
|
# store['dbname'] = product
|
|
|
|
|
# user = User(stripe=stripe,store=store,product=product)
|
|
|
|
|
# user.subscribe(uid,plan_id)
|
|
|
|
|
|
|
|
|
|
# sub = None
|
|
|
|
|
# if 'auid' in request.headers :
|
|
|
|
|
# auid = request.headers['auid']
|
|
|
|
|
# user.update(emails=auid)
|
|
|
|
|
# user.post()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# store = dict(CONFIG['couchdb'],**{})
|
|
|
|
|
# store['dbname'] = product
|
|
|
|
|
# store['uid'] = 'logs'
|
|
|
|
|
|
|
|
|
|
# sub = user.get(uid,'subscriptions')
|
|
|
|
|
# features = {}
|
|
|
|
|
# for id in sub :
|
|
|
|
|
# if sub[id]['active'] is True :
|
|
|
|
|
# features[id] = sub[id]
|
|
|
|
|
|
|
|
|
|
# user.refresh(uid)
|
|
|
|
|
# session['key'] = user.user_key
|
|
|
|
|
# session['uid'] = uid
|
|
|
|
|
|
|
|
|
|
mystore = store.factory.instance(name=product,email=uid)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -154,53 +204,55 @@ def init(product):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
features = user.plan.info()['metadata']['features'] if 'features' in user.plan.info()['metadata'] else {}
|
|
|
|
|
print (features)
|
|
|
|
|
return json.dumps(features),200
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/subscribe/<product>',methods=['POST'])
|
|
|
|
|
def subscribe(product):
|
|
|
|
|
"""
|
|
|
|
|
This function subscribes a user to a given service for an application
|
|
|
|
|
This function guarantees not to duplicate subscriptions
|
|
|
|
|
@resource name name of the application {cloud-music}
|
|
|
|
|
@header key service/plan
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
|
# The name is the full name of the service
|
|
|
|
|
#@TODO: Log that uid, has initiated use of product
|
|
|
|
|
#
|
|
|
|
|
resp = "0"
|
|
|
|
|
user = User(stripe=stripe,store=CONFIG['couchdb'],product=product)
|
|
|
|
|
if 'stripeToken' in request.form :
|
|
|
|
|
stripeToken = request.form['stripeToken']
|
|
|
|
|
uid = request.form['stripeEmail']
|
|
|
|
|
tokenType = request.form['stripeTokenType']
|
|
|
|
|
amount = request.form['amount']
|
|
|
|
|
pid = request.form['plan']
|
|
|
|
|
return json.dumps(features),200
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
pid = request.headers['pid'] if 'pid' in request.headers else None
|
|
|
|
|
uid = request.headers['uid']
|
|
|
|
|
stripeToken = None
|
|
|
|
|
user.subscribe(uid,pid,stripeToken)
|
|
|
|
|
if 'auid' in request.headers :
|
|
|
|
|
|
|
|
|
|
if request.headers['auid'].startswith('[') or request.headers['auid'].startswith("{") :
|
|
|
|
|
auid = json.loads(request.headers['auid'])
|
|
|
|
|
else:
|
|
|
|
|
auid = [request.headers['auid']]
|
|
|
|
|
user.update(emails=auid)
|
|
|
|
|
user.refresh(uid)
|
|
|
|
|
|
|
|
|
|
reader = CouchdbReader(uri=SYS_STORE['uri'],dbname=product,uid=uid,create=False)
|
|
|
|
|
plans = reader.view('users/active_plan',key=user.user_key) #me['_id'])
|
|
|
|
|
#session['plans'] = plans
|
|
|
|
|
session['key'] = user.user_key
|
|
|
|
|
session['uid'] = uid
|
|
|
|
|
session['active-plans'] = [item['id'] for item in plans]
|
|
|
|
|
print (session['active-plans'])
|
|
|
|
|
return (json.dumps(plans),200)
|
|
|
|
|
# @app.route('/subscribe/<product>',methods=['POST'])
|
|
|
|
|
# def subscribe(product):
|
|
|
|
|
# """
|
|
|
|
|
# This function subscribes a user to a given service for an application
|
|
|
|
|
# This function guarantees not to duplicate subscriptions
|
|
|
|
|
# @resource name name of the application {cloud-music}
|
|
|
|
|
# @header key service/plan
|
|
|
|
|
# """
|
|
|
|
|
|
|
|
|
|
# #
|
|
|
|
|
# # The name is the full name of the service
|
|
|
|
|
# #
|
|
|
|
|
# resp = "0"
|
|
|
|
|
# user = User(stripe=stripe,store=CONFIG['couchdb'],product=product)
|
|
|
|
|
# if 'stripeToken' in request.form :
|
|
|
|
|
# stripeToken = request.form['stripeToken']
|
|
|
|
|
# uid = request.form['stripeEmail']
|
|
|
|
|
# tokenType = request.form['stripeTokenType']
|
|
|
|
|
# amount = request.form['amount']
|
|
|
|
|
# pid = request.form['plan']
|
|
|
|
|
|
|
|
|
|
# else:
|
|
|
|
|
# pid = request.headers['pid'] if 'pid' in request.headers else None
|
|
|
|
|
# uid = request.headers['uid']
|
|
|
|
|
# stripeToken = None
|
|
|
|
|
# user.subscribe(uid,pid,stripeToken)
|
|
|
|
|
# if 'auid' in request.headers :
|
|
|
|
|
|
|
|
|
|
# if request.headers['auid'].startswith('[') or request.headers['auid'].startswith("{") :
|
|
|
|
|
# auid = json.loads(request.headers['auid'])
|
|
|
|
|
# else:
|
|
|
|
|
# auid = [request.headers['auid']]
|
|
|
|
|
# user.update(emails=auid)
|
|
|
|
|
# user.refresh(uid)
|
|
|
|
|
|
|
|
|
|
# reader = CouchdbReader(uri=SYS_STORE['uri'],dbname=product,uid=uid,create=False)
|
|
|
|
|
# plans = reader.view('users/active_plan',key=user.user_key) #me['_id'])
|
|
|
|
|
# #session['plans'] = plans
|
|
|
|
|
# session['key'] = user.user_key
|
|
|
|
|
# session['uid'] = uid
|
|
|
|
|
# session['active-plans'] = [item['id'] for item in plans]
|
|
|
|
|
# print (session['active-plans'])
|
|
|
|
|
# return (json.dumps(plans),200)
|
|
|
|
|
|
|
|
|
|
def get_plans(product) :
|
|
|
|
|
lproducts = stripe.Product.list()
|
|
|
|
@ -342,9 +394,16 @@ def is_customer (app_name):
|
|
|
|
|
if __name__ == '__main__' :
|
|
|
|
|
#
|
|
|
|
|
# setup mongodb session management (not sure why)
|
|
|
|
|
app.config['SESSION_TYPE'] = 'mongodb'
|
|
|
|
|
app.config['MONGO_URI'] = 'mongodb://localhost:27017'
|
|
|
|
|
app.config['SESSION_MONGODB_DB'] = 'sessions'
|
|
|
|
|
app.config['SESSION_MONGODB_COLLECT'] = 'store'
|
|
|
|
|
mongo = PyMongo(app)
|
|
|
|
|
app.session_interface = MongoDBSessionInterface(app,mongo.db, 'store')
|
|
|
|
|
|
|
|
|
|
app.debug = True ;
|
|
|
|
|
app.secret_key = '360-8y-[0v@t10n]+kr81v17y'
|
|
|
|
|
app.config['MAX_CONTENT_LENGTH'] = 1600 * 1024 * 1024
|
|
|
|
|
|
|
|
|
|
Session(app)
|
|
|
|
|
app.run(port=PORT,threaded=True,host='0.0.0.0')
|
|
|
|
|
# app.run() #'0.0.0.0',PORT,True,threaded=True)
|
|
|
|
|