merchant-frontend-examples

ZZZ: Inactive/Deprecated
Log | Files | Refs

commit 74423fa10229a3f806d64880b4ba058f8194ae59
parent bcf9120d9815b1e2aa9caf0939a080f0ea355c31
Author: Marcello Stanisci <marcello.stanisci@inria.fr>
Date:   Wed, 22 Feb 2017 14:47:16 +0100

python tutorial compiles

Diffstat:
MMakefile | 12+++++++-----
Acommon/README | 3+++
Rgraphics/arch.dot -> common/graphics/arch.dot | 0
Acommon/graphics/arch.jpg | 0
Acommon/graphics/arch.pdf | 0
Acommon/graphics/arch.png | 0
Acommon/graphics/arch_nobo.dot | 19+++++++++++++++++++
Acommon/graphics/arch_nobo.jpg | 0
Acommon/graphics/arch_nobo.pdf | 0
Mphp/doc/Makefile | 12+++++++-----
Rpython/tutorial/templates/index.html -> python/example/templates/index.html | 0
Apython/example/tutorial.py | 108+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dpython/tutorial/tutorial.py | 108-------------------------------------------------------------------------------
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)