commit 31f311e2813e9f20f36c2710d5f3a343685b8235
parent 00e4c27a5f83471d50c290e233a9b7e5925fcf7d
Author: Marcello Stanisci <marcello.stanisci@inria.fr>
Date: Tue, 21 Feb 2017 16:35:39 +0100
Completing tutorial code.
Diffstat:
3 files changed, 67 insertions(+), 17 deletions(-)
diff --git a/Python/lib/Makefile b/Python/lib/Makefile
@@ -1,6 +1,4 @@
-# TALER_PREFIX must point to 'site-packages' dir.
-
-all:
+install:
pip3 install . --install-option="--prefix=$(TALER_PREFIX)"
check:
diff --git a/Python/lib/pytaler/__pycache__/amounts.cpython-35.pyc b/Python/lib/pytaler/__pycache__/amounts.cpython-35.pyc
Binary files differ.
diff --git a/Python/tutorial/tutorial.py b/Python/tutorial/tutorial.py
@@ -1,41 +1,61 @@
import flask
-from urllib.parse import urljoin
+import requests
+from urllib.parse import urljoin, urlencode
from pytaler import amounts
+import base64
+import os
app = flask.Flask(__name__)
-
-CURRENCY = "KUDOS"
+app.secret_key = base64.b64encode(os.urandom(64)).decode('utf-8')
+CURRENCY = "PUDOS"
BACKEND_URL = "http://backend.test.taler.net/"
-@app.route('/')
+def make_url(page, *query_params):
+ """
+ Return a URL to a page in the current Flask application with the given
+ query parameters (sequence of key/value pairs).
+ """
+ query = urlencode(query_params)
+ if page.startswith("/"):
+ root = flask.request.url_root
+ page = page.lstrip("/")
+ else:
+ root = flask.request.base_url
+ url = urljoin(root, "%s?%s" % (page, query))
+ # urlencode is overly eager with quoting, the wallet right now
+ # needs some characters unquoted.
+ return url.replace("%24", "$").replace("%7B", "{").replace("%7D", "}")
+
+@app.route("/")
def index():
- return flask.render_template('index.html')
+ return flask.render_template("index.html")
-@app.route('/donate')
+@app.route("/donate")
def donate():
resp = flask.Response(status=402)
- resp.headers['X-Taler-Contract-Url'] = '/generate-contract'
+ resp.headers["X-Taler-Contract-Url"] = "/generate-contract"
return resp
-@app.route('/generate-contract')
+@app.route("/generate-contract")
def generate_contract():
-
+ DONATION = amounts.string_to_amount("0.1:%s" % CURRENCY)
+ MAX_FEE = amounts.string_to_amount("0.05:%s" % CURRENCY)
order = dict(
nonce=flask.request.args.get("nonce"),
- amount=amounts.string_to_amount("1.0:%s" % CURRENCY),
- max_fee=amounts.string_to_amount("1.0:%s" % CURRENCY),
+ amount=DONATION,
+ max_fee=MAX_FEE,
products=[
dict(
description="Donation",
quantity=1,
product_id=0,
- price=amount,
+ price=DONATION,
),
],
- fulfillment_url=make_url("/fulfillment/"),
+ fulfillment_url=make_url("/fulfillment"),
merchant=dict(
address="nowhere",
name="Donation tutorial",
@@ -43,7 +63,7 @@ def generate_contract():
),
)
- url = urljoin(BACKEND_URL, 'proposal')
+ url = urljoin(BACKEND_URL, "proposal")
r = requests.post(url, json=dict(order=order))
if r.status_code != 200:
@@ -51,3 +71,35 @@ def generate_contract():
return r.status_code, r.text
proposal_resp = r.json()
return flask.jsonify(**proposal_resp)
+
+
+@app.route("/fulfillment")
+def fulfillment():
+ paid = flask.session.get("paid", False)
+ if paid:
+ return "Thank you!"
+
+ response = flask.Response(status=402)
+ response.headers["X-Taler-Contract-Url"] = make_url("/generate-contract")
+ response.headers["X-Taler-Contract-Query"] = "fulfillment_url"
+ response.headers["X-Taler-Pay-Url"] = make_url("/pay")
+ response.headers["X-Taler-Offer-Url"] = make_url("/donate")
+
+ return response
+
+
+@app.route("/pay", methods=["POST"])
+def pay():
+ deposit_permission = flask.request.get_json()
+ if deposit_permission is None:
+ e = flask.jsonify(error="no json in body")
+ return e, 400
+
+ r = requests.post(urljoin(BACKEND_URL, 'pay'), json=deposit_permission)
+ if 200 != r.status_code:
+ return r.text, r.status_code
+
+ flask.session["paid"] = True
+
+ return flask.Response(status=200)
+