@ -10,7 +10,7 @@
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 , Response , redirect
from flask_session import Session
from flask_cors import CORS
from flask_pymongo import PyMongo
@ -54,12 +54,12 @@ CORS(app)
SYS_STORE = CONFIG [ ' store ' ]
@app.route ( " /donate " )
def donate ( ) :
print ( request . args [ ' amount ' ] )
amount = float ( request . args [ ' amount ' ] ) if ' amount ' in request . args else 5.0
args = { ' amount ' : amount , ' context ' : CONTEXT }
return render_template ( ' donate.html ' , * * args )
# @app.route("/donate" )
# def _donate() :
# amount = float(request.args['amount']) if 'amount' in request.args else 5.0
# args = {'amount':amount,'context':CONTEXT}
# return render_template('donate.html',**args)
@app.route ( " / " )
def index ( ) :
mystore = store . factory . instance ( name = ' music ' )
@ -91,7 +91,7 @@ def to_session():
if info :
for key in info :
session [ key ] = info [ key ]
return " {} "
return " {} " , 200
@app.route ( " /signup " , methods = [ ' GET ' , ' POST ' ] )
def signup ( ) :
"""
@ -137,7 +137,8 @@ def signup():
< / script >
""" .replace( " :uri " ,uri)
@app.route ( " /ui/signup/<id> " , methods = [ ' GET ' , ' PUT ' ] )
# @app.route("/ui/signup/<id>",methods=['GET','PUT'])
@app.route ( " /<id>/signup " , methods = [ ' GET ' , ' PUT ' ] )
def signup_form ( id ) :
"""
This function loads the signup form with cloud - view authentication support
@ -154,7 +155,71 @@ def signup_form(id):
args [ ' cloud-view ' ] = CONFIG [ ' cloud-view ' ]
return render_template ( " signup.html " , * * args )
@app.route ( " /ui/<id> " )
@app.route ( " /me " )
def me ( ) :
#
#{'user': {'uid': 'nyemba@gmail.com', 'uii': 'Steve Nyemba', 'usage': {'used': 1.012175691, 'size': 4.02653184, 'units': 'GB'}, 'sid': 'dropbox'}, 'key': 'nsfCKKUWunUAAAAAAAAAAUMzU6oR6qp9TK7t-_zop-sBOcEaM3eb1mRi_PG8bM69', 'features': {}}
# mystore = store.factory.instance(name = session['product']['name'])
# mystore.init(email=session['auth']['user']['uid'])
try :
email = session [ ' auth ' ] [ ' user ' ] [ ' uid ' ]
name = session [ ' product ' ] [ ' name ' ]
mystore = store . factory . instance ( name = name , email = email )
payments = mystore . user . invoices ( )
cards = mystore . user . card . html ( ) if mystore . user . card . exists ( ) else None
_args = { ' context ' : CONTEXT , " user " : session [ ' auth ' ] [ ' user ' ] , " product " : session [ ' product ' ] , " plan " : session [ ' plan ' ] , " payments " : payments , " cards " : cards }
return render_template ( ' me.html ' , * * _args )
except Exception as e :
pass
return redirect ( " https://the-phi.com " )
@app.route ( " /me/card " , methods = [ ' POST ' ] )
def me_card ( ) :
if ' auth ' in session :
email = session [ ' auth ' ] [ ' user ' ] [ ' uid ' ]
name = session [ ' product ' ] [ ' name ' ]
mystore = store . factory . instance ( name = name , email = email )
body = request . json
try :
mystore . user . card . add ( card = body )
except Exception as e :
print ( e )
return " 0 " , 200
return " 1 " , 200
# pricing = mystore.get.checkout() #-- pricing
# pricing = [{"unit_amount":500,"currency":"usd"},{"unit_amount":1000,"currency":"usd"},{"unit_amount":2500,"currency":"usd"}]
# args = {"product":session['product']}
else :
return " 0 " , 403
return render_template ( " card.html " )
@app.route ( " /<id>/cancel " , methods = [ ' POST ' ] )
def cancel ( id ) :
#
# This function will cancel the user's current plan
STATUS = " 1 "
try :
if ' auth ' in session :
email = session [ ' auth ' ] [ ' user ' ] [ ' uid ' ]
mystore = store . factory . instance ( name = id , email = email )
_id = mystore . user . plan . sub_id ( )
mystore . cancel ( _id )
session [ ' plan ' ] = None
session [ ' payments ' ] = mystore . user . invoices ( )
else :
STATUS = " 0 "
except Exception as e :
print ( e )
STATUS = " 0 "
pass
return STATUS , 200
# @app.route("/ui/<id>")
@app.route ( " /<id>/plans " )
def get_plans_ui ( id ) :
"""
This function loads the form for signup and information about the various plans for a given product .
@ -167,9 +232,10 @@ def get_plans_ui(id):
description = mystore . product [ ' metadata ' ] [ ' about ' ] if ' about ' in mystore . product [ ' metadata ' ] else ' '
label = mystore . product [ ' statement_descriptor ' ]
args = { " product " : id , " label " : label , " description " : description , " context " : CONTEXT , " plans " : mystore . get . plans ( ) , " now " : datetime . now ( ) . year }
args [ ' product ' ] = mystore . product
args [ ' theme ' ] = ' theme-clouds '
# print (mystore.product.keys())
session [ ' cloud-view ' ] = CONFIG [ ' cloud-view ' ]
session [ ' cloud-view ' ] = CONFIG [ ' cloud-view ' ] . replace ( ' :id ' , id )
session [ ' product ' ] = mystore . product
return render_template ( ' plans.html ' , * * args )
@app.route ( " /goto/<id> " , methods = [ ' POST ' , ' GET ' ] )
@ -193,7 +259,7 @@ def redirect(id ) :
return " 0 " , 403
pass
@app.route ( " /<id>/donate " )
def paym e ( id ) :
def donat e ( id ) :
"""
This will charge a given user / card for a given product . i . e it is designed for a one - time payment
"""
@ -203,7 +269,18 @@ def payme (id) :
args = { " product " : mystore . product , " plans " : mystore . get . plans ( ) , " context " : CONTEXT , " pricing " : pricing }
return render_template ( " card.html " , * * args )
@app.route ( " /ui/dialog " , methods = [ ' POST ' ] )
@app.route ( " /<id>/pay " )
def pay ( id ) :
email = session [ ' auth ' ] [ ' user ' ] [ ' uid ' ]
fname = session [ ' auth ' ] [ ' user ' ] [ ' uii ' ] . split ( ' ' ) [ 0 ] if ' uii ' in session [ ' auth ' ] [ ' user ' ] else ' '
lname = " " . join ( session [ ' auth ' ] [ ' user ' ] [ ' uii ' ] . split ( ' ' ) [ 1 : ] ) if ' uii ' in session [ ' auth ' ] [ ' user ' ] else ' '
mystore = store . factory . instance ( name = id , email = email ) #--
amount = session [ ' plan ' ] [ ' amount ' ]
# cards = mystore.user.card.html() if mystore.user.card.exists() else None
_args = { " product " : mystore . product , " pricing " : None , " context " : CONTEXT , " email " : email , " lname " : lname , " fname " : fname , " amount " : amount } #,"cards":cards}
return render_template ( " card.html " , * * _args )
@app.route ( " /html/dialog " , methods = [ ' POST ' ] )
def get_dialog ( ) :
info = request . get_json ( )
@ -213,33 +290,61 @@ def get_dialog():
@app.route ( ' /<id>/pay ' , methods = [ ' POST ' , ' PUT ' ] )
def _payme ( id ) :
info = request . get_json ( )
mystore = store . factory . instance ( name = id , email = info [ ' email ' ] )
user = mystore . user
#
# ... Let us massage the data so it can go through properly
_args = { }
if ' has_card ' not in info and not info [ ' has_card ' ] :
card = { " number " : info [ ' number ' ] , " cvc " : info [ ' cvc ' ] }
card [ ' exp_month ' ] = info [ ' exp ' ] . split ( " / " ) [ 0 ]
card [ ' exp_year ' ] = info [ ' exp ' ] . split ( " / " ) [ 1 ]
card [ ' name ' ] = " " . join ( [ info [ " fname " ] , info [ " lname " ] ] )
_args = { " card " : card , " email " : info [ ' email ' ] , " amount " : info [ ' amount ' ] , " currency " : " usd " }
_args = { " email " : info [ ' email ' ] , " amount " : info [ ' amount ' ] , " currency " : " usd " }
else :
#
# Let us make a payment using the source we already have
card = { }
_args [ ' card ' ] = card
#
# if a plan information is provided we are running the card for the plan ?
#
if ' plan ' in info :
if ' plan ' in session :
#
# We are dealing with a subscription here and we should run this through the subscription engine
# and NOT charge the user immediately (handled by stripe)
#
# _args['amount'] = info['plan']['amount']
plan = session [ ' plan ' ]
_args [ ' metadata ' ] = { " payment " : plan [ ' nickname ' ] , " product " : id }
_args [ ' plan ' ] = plan
if user . plan . info ( ) :
r = mystore . plan . upgrade ( plan [ ' id ' ] , info [ ' email ' ] )
else :
r = mystore . plan . subscribe ( id = plan [ ' id ' ] , email = info [ ' email ' ] )
pass
else :
#
# For now we consider this a donation
_args [ ' metadata ' ] = { " payment " : " donation " , " product " : id }
_args [ ' description ' ] = " " . join ( [ id , _args [ ' metadata ' ] [ ' payment ' ] ] )
# For now we consider this a donation or other payment
_args [ ' metadata ' ] = { " payment " : " charge " , " product " : id }
_args [ ' statement_descriptor ' ] = " " . join ( [ str ( info [ ' amount ' ] ) , id ] )
r = user . charge ( * * _args )
if not r :
msg , status = " Problem enountered with card " , 403
msg , status = " P ayment error enountere d" , 403
else :
msg , status = " Payment accepted, Thank you " , 200
return Response ( msg , status = status )
@app.route ( " /me/logout " , methods = [ " POST " , " GET " ] )
def logout ( ) :
session . clear ( )
return " 1 " , 200
@app.route ( " /init/<product> " , methods = [ ' POST ' ] )
def init ( product ) :
@ -337,7 +442,8 @@ def get_plans(product) :
else :
return [ ]
@app.route ( ' /features/<product> ' )
# @app.route('/features/<product>')
@app.route ( ' /<product>/features ' )
def features ( product ) :
"""
This function returns the plan / features of a user for a given application if provided a uid ( email )
@ -361,96 +467,97 @@ def features(product):
#
# formatting plans for the output
#
return json . dumps ( plans )
"""
This function returns a user ' s plans/status for an application
@header uid user ' s email address
"""
@app.route ( ' /status/<app_name> ' )
def status ( app_name ) :
return json . dumps ( plans ) , { " content-type " : " application/json " }
# """
# This function returns a user's plans/status for an application
# @header uid user's email address
# """
# @app.route('/status/<app_name>' )
# def status(app_name) :
uid = request . headers [ ' uid ' ]
# uid = request.headers['uid']
couchdb = CouchdbReader ( uri = CONFIG [ ' couchdb ' ] [ ' uri ' ] , dbname = app_name , uid = uid , create = False )
handler = Domain . User ( couchdb . dbase , stripe )
handler . initialize ( uid )
#lsub = handler.subscriptions()
plans = handler . plans ( )
return json . dumps ( plans )
"""
This endpoint is the signup form for a given application ,
It will allow user ' s to be able to signup for various plans
@pre ' uid ' in request . headers
"""
@app.route ( ' /signup/<product> ' )
def _signup ( product ) :
apikey = CONFIG [ ' stripe ' ] [ ' pub ' ] . strip ( )
# couchdb = CouchdbReader(uri=CONFIG['couchdb']['uri'],dbname=app_name,uid=uid,create=False)
# handler = Domain.User(couchdb.dbase,stripe)
# handler.initialize(uid)
# #lsub = handler.subscriptions()
# plans = handler.plans()
# return json.dumps(plans)
# """
# This endpoint is the signup form for a given application,
# It will allow user's to be able to signup for various plans
# @pre 'uid' in request.headers
# """
# @app.route('/signup/<product>')
# @app.route('/<product>/signup')
# def _signup(product) :
# apikey = CONFIG['stripe']['pub'].strip()
#
# This function returns the plans for a given application
# We assume the application name is the prefix of the plan identifier in stripe
#
if ' user-info ' in session :
_info = session [ ' user-info ' ]
session [ ' uid ' ] = _info [ ' uid ' ]
uid = session [ ' uid ' ] if ' uid ' in session else ' '
can_purchase = True
if uid is None :
uid = request . args . get ( ' uid ' ) if ' uid ' in request . args else None
plans = get_plans ( product )
# #
# # This function returns the plans for a given application
# # We assume the application name is the prefix of the plan identifier in stripe
# #
# if 'user-info' in session :
# _info = session['user-info']
# session['uid'] = _info['uid']
# uid = session['uid'] if 'uid' in session else ''
# can_purchase = True
# if uid is None :
# uid = request.args.get('uid') if 'uid' in request.args else None
# plans = get_plans(product)
#
# @TODO: Mark the plans the current user is signed up for
#
if ' themes ' in CONFIG :
theme = CONFIG [ ' themes ' ] [ product ] if product in CONFIG [ ' themes ' ] else CONFIG [ ' theme ' ] [ ' default ' ]
else :
theme = ' '
platform = ' web ' if ' platform ' not in request . args else request . args [ ' platform ' ]
alias = plans [ 0 ] [ ' product_alias ' ]
if ' user-plan ' in session :
user_plans = [ item [ ' id ' ] for item in session [ ' user-plan ' ] ]
else :
user_plans = [ ]
# active_plan = session['active-plans'] if 'active-plans' in session else []
args = { " context " : CONTEXT , " theme " : theme , " uid " : uid , " alias " : alias , " platform " : platform , " app_name " : product , " apikey " : apikey , " plans " : plans }
args [ ' active_plans ' ] = user_plans
# #
# # @TODO: Mark the plans the current user is signed up for
# #
# if 'themes' in CONFIG:
# theme = CONFIG['themes'][product] if product in CONFIG['themes'] else CONFIG['theme']['default']
# else:
# theme = ''
# platform='web' if 'platform' not in request.args else request.args['platform']
# alias = plans[0]['product_alias']
# if 'user-plan' in session :
# user_plans = [item['id'] for item in session['user-plan']]
# else :
# user_plans = []
# # active_plan = session['active-plans'] if 'active-plans' in session else []
# args = {"context":CONTEXT,"theme":theme,"uid":uid,"alias":alias,"platform":platform,"app_name":product,"apikey":apikey,"plans":plans}
# args['active_plans'] = user_plans
return render_template ( ' subscribe.html ' , * * args ) #context=CONTEXT,uid=uid,alias=alias,platform=platform,app_name=product,plans=plans,apikey=apikey)
# return render_template('subscribe.html',**args) #context=CONTEXT,uid=uid,alias=alias,platform=platform,app_name=product,plans=plans,apikey=apikey)
@app.route ( ' /subscribe/<name> ' , methods = [ ' DELETE ' ] )
def cancel_subscribe ( name ) :
pass
"""
This function defines if a given user is a customer or not
We should be able to tell by how we create customers
"""
@app.route ( ' /checkout/<app_name> ' , methods = [ ' GET ' ] )
def is_customer ( app_name ) :
uid = request . args . get ( ' uid ' )
pid = request . args . get ( ' pid ' )
couchdb = CouchdbReader ( uri = CONFIG [ ' couchdb ' ] [ ' uri ' ] , dbname = app_name , uid = uid , create = False )
r = couchdb . view ( ' federation/uid_map ' , key = uid )
id = r [ 0 ] [ ' value ' ]
couchdb = CouchdbReader ( uri = CONFIG [ ' couchdb ' ] [ ' uri ' ] , dbname = app_name , uid = id , create = False )
info = couchdb . read ( )
lsub = info [ ' subscriptions ' ]
plans = [ dict ( dict ( item [ ' plan ' ] , * * { " status " : item [ ' status ' ] } ) , * * { " subscription " : item [ ' id ' ] } ) for item in lsub ]
if pid is not None :
plans = [ item for item in plans if item [ ' id ' ] == pid ]
#
# Caching the subscription identifiers so we can create an invoice later on (if need be)
# @TODO Improve this process later on by allowing user's to pay for what they can (not everything)
#
session [ ' plans ' ] = plans
# @app.route('/subscribe/<name>',methods=['DELETE'] )
# def cancel_subscribe(name) :
# pass
# """
# This function defines if a given user is a customer or not
# We should be able to tell by how we create customers
# """
# @app.route('/checkout/<app_name>',methods=['GET'] )
# def is_customer (app_name) :
# uid = request.args.get('uid')
# pid = request.args.get('pid')
# couchdb = CouchdbReader(uri=CONFIG['couchdb']['uri'],dbname=app_name,uid=uid,create=False)
# r = couchdb.view('federation/uid_map',key=uid)
# id = r[0]['value']
# couchdb = CouchdbReader(uri=CONFIG['couchdb']['uri'],dbname=app_name,uid=id,create=False)
# info = couchdb.read()
# lsub = info['subscriptions']
# plans = [dict(dict(item['plan'],**{"status":item['status']}),**{"subscription":item['id']}) for item in lsub]
# if pid is not None:
# plans = [item for item in plans if item['id'] == pid]
# #
# # Caching the subscription identifiers so we can create an invoice later on (if need be)
# # @TODO Improve this process later on by allowing user's to pay for what they can (not everything)
# #
# session['plans'] = plans
session [ ' plans ' ]
amount = sum ( [ item [ ' amount ' ] for item in plans ] )
apikey = CONFIG [ ' stripe ' ] [ ' pub ' ] . strip ( )
# session['plans']
# amount = sum([item['amount'] for item in plans])
# apikey = CONFIG['stripe']['pub'].strip()
amount = amount / 100
return render_template ( ' bill.html ' , context = CONTEXT , apikey = apikey , app_name = app_name . replace ( ' - ' , ' ' ) , plans = plans , total_amount = amount )
# amount = amount / 100
# return render_template('bill.html',context=CONTEXT,apikey=apikey,app_name=app_name.replace('-',' '),plans=plans,total_amount=amount)
if __name__ == ' __main__ ' :
#