commit 74423fa10229a3f806d64880b4ba058f8194ae59
parent bcf9120d9815b1e2aa9caf0939a080f0ea355c31
Author: Marcello Stanisci <marcello.stanisci@inria.fr>
Date: Wed, 22 Feb 2017 14:47:16 +0100
python tutorial compiles
Diffstat:
13 files changed, 144 insertions(+), 118 deletions(-)
diff --git a/Makefile b/Makefile
@@ -2,14 +2,16 @@
.PHONY: graphics
-SUBDIRS := php
+SUBDIRS := php/doc python/doc
all: $(SUBDIRS)
$(SUBDIRS): graphics
- cp -t $@/doc graphics/arch.png
- cd $@/doc/; texi2pdf tutorial.texi
- cd $@/doc/; zip samples.zip ../*.$@
+ cp -t $@ common/graphics/arch.png
+ $(MAKE) -C $@
graphics:
- cd graphics; dot -Tpng arch.dot > arch.png
+ cd common/graphics; dot -Tpdf arch.dot > arch.pdf
+ cd common/graphics; dot -Tpdf arch_nobo.dot > arch_nobo.pdf
+ cd common/graphics; dot -Tjpg arch.dot > arch.jpg
+ cd common/graphics; dot -Tjpg arch_nobo.dot > arch_nobo.jpg
diff --git a/common/README b/common/README
@@ -0,0 +1,3 @@
+This directory contains all those parts that are
+common to any tutorial regardless of the language,
+like graphics and introductory chapters.
diff --git a/graphics/arch.dot b/common/graphics/arch.dot
diff --git a/common/graphics/arch.jpg b/common/graphics/arch.jpg
Binary files differ.
diff --git a/common/graphics/arch.pdf b/common/graphics/arch.pdf
Binary files differ.
diff --git a/common/graphics/arch.png b/common/graphics/arch.png
Binary files differ.
diff --git a/common/graphics/arch_nobo.dot b/common/graphics/arch_nobo.dot
@@ -0,0 +1,19 @@
+digraph G {
+
+ user[label="Customer browser"];
+ admin[label="Shop admin"];
+ subgraph cluster_0 {
+ Frontend;
+ Backend;
+ DBMS;
+ label="Shop server";
+ }
+ subgraph cluster_1 {
+ Exchange;
+ label="Exchange";
+ }
+ user->Frontend;
+ Frontend->Backend;
+ Backend->DBMS;
+ Backend->Exchange;
+}
diff --git a/common/graphics/arch_nobo.jpg b/common/graphics/arch_nobo.jpg
Binary files differ.
diff --git a/common/graphics/arch_nobo.pdf b/common/graphics/arch_nobo.pdf
Binary files differ.
diff --git a/php/doc/Makefile b/php/doc/Makefile
@@ -2,16 +2,18 @@ all: tutorial.pdf tutorial.html
tutorial.pdf: arch.pdf tutorial.texi
texi2pdf tutorial.texi
+
tutorial.html: arch.jpg tutorial.texi
texi2html tutorial.texi
-arch.pdf: arch.dot
- dot -Tpdf arch.dot > arch.pdf
-arch.jpg: arch.dot
- dot -Tjpg arch.dot > arch.jpg
+
+arch.pdf:
+ cp ../../common/graphics/arch.pdf .
+
+arch.jpg:
+ cp ../../common/graphics/arch.jpg .
clean:
rm -f arch.jpg arch.pdf tutorial.html tutorial.pdf
-
info_TEXINFOS = tutorial.texi
manual_TEXINFOS = version.texi
diff --git a/python/tutorial/templates/index.html b/python/example/templates/index.html
diff --git a/python/example/tutorial.py b/python/example/tutorial.py
@@ -0,0 +1,108 @@
+import flask
+import requests
+from urllib.parse import urljoin, urlencode
+from pytaler import amounts
+import base64
+import os
+import logging
+import json
+
+
+app = flask.Flask(__name__)
+app.secret_key = base64.b64encode(os.urandom(64)).decode('utf-8')
+logger = logging.getLogger(__name__)
+
+CURRENCY = "PUDOS"
+BACKEND_URL = "http://backend.test.taler.net/"
+
+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")
+
+
+@app.route("/donate")
+def donate():
+ response = flask.Response(status=402)
+ response.headers["X-Taler-Contract-Url"] = "/generate-proposal"
+ return response
+
+
+@app.route("/generate-proposal")
+def generate_proposal():
+ 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=DONATION,
+ max_fee=MAX_FEE,
+ products=[
+ dict(
+ description="Donation",
+ quantity=1,
+ product_id=0,
+ price=DONATION,
+ ),
+ ],
+ fulfillment_url=make_url("/fulfillment"),
+ merchant=dict(
+ address="nowhere",
+ name="Donation tutorial",
+ jurisdiction="none",
+ ),
+ )
+
+ url = urljoin(BACKEND_URL, "proposal")
+
+ r = requests.post(url, json=dict(order=order))
+ if r.status_code != 200:
+ logger.error("failed to POST to '%s'", url)
+ return r.text, r.status_code
+ 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)
diff --git a/python/tutorial/tutorial.py b/python/tutorial/tutorial.py
@@ -1,108 +0,0 @@
-import flask
-import requests
-from urllib.parse import urljoin, urlencode
-from pytaler import amounts
-import base64
-import os
-import logging
-import json
-
-
-app = flask.Flask(__name__)
-app.secret_key = base64.b64encode(os.urandom(64)).decode('utf-8')
-logger = logging.getLogger(__name__)
-
-CURRENCY = "PUDOS"
-BACKEND_URL = "http://backend.test.taler.net/"
-
-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")
-
-
-@app.route("/donate")
-def donate():
- response = flask.Response(status=402)
- response.headers["X-Taler-Contract-Url"] = "/generate-contract"
- return response
-
-
-@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=DONATION,
- max_fee=MAX_FEE,
- products=[
- dict(
- description="Donation",
- quantity=1,
- product_id=0,
- price=DONATION,
- ),
- ],
- fulfillment_url=make_url("/fulfillment"),
- merchant=dict(
- address="nowhere",
- name="Donation tutorial",
- jurisdiction="none",
- ),
- )
-
- url = urljoin(BACKEND_URL, "proposal")
-
- r = requests.post(url, json=dict(order=order))
- if r.status_code != 200:
- logger.error("failed to POST to '%s'", url)
- return r.text, r.status_code
- 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)