gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [taler-donations] 03/09: actual donations logic


From: gnunet
Subject: [GNUnet-SVN] [taler-donations] 03/09: actual donations logic
Date: Fri, 24 Nov 2017 20:25:01 +0100

This is an automated email from the git hooks/post-receive script.

marcello pushed a commit to branch master
in repository donations.

commit f7f95782434a2268bc3583fe46fd0c386a1c1439
Author: Marcello Stanisci <address@hidden>
AuthorDate: Fri Nov 24 20:01:43 2017 +0100

    actual donations logic
---
 talerdonations/donations/donations.py | 212 ++++++++++++++++++++++++++++++++++
 1 file changed, 212 insertions(+)

diff --git a/talerdonations/donations/donations.py 
b/talerdonations/donations/donations.py
new file mode 100644
index 0000000..a86479d
--- /dev/null
+++ b/talerdonations/donations/donations.py
@@ -0,0 +1,212 @@
+# This file is part of GNU TALER.
+# Copyright (C) 2014-2016 INRIA
+#
+# TALER is free software; you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free 
Software
+# Foundation; either version 2.1, or (at your option) any later version.
+#
+# TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more 
details.
+#
+# You should have received a copy of the GNU Lesser General Public License 
along with
+# GNU TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+#
+# @author Florian Dold
+# @author Marcello Stanisci
+
+import flask
+from urllib.parse import urljoin, urlencode, quote, parse_qsl
+import requests
+import logging
+import os
+import base64
+import random
+import time
+from datetime import datetime
+import jinja2
+from talerfrontends.talerconfig import TalerConfig
+from talerfrontends.helpers import (make_url,
+expect_parameter, amount_from_float, amount_to_float,
+join_urlparts, get_query_string, MissingParameterException,
+backend_error)
+
+logger = logging.getLogger(__name__)
+
+base_dir = os.path.dirname(os.path.abspath(__file__))
+
+app = flask.Flask(__name__, template_folder=base_dir)
+app.debug = True
+app.secret_key = base64.b64encode(os.urandom(64)).decode('utf-8')
+
+tc = TalerConfig.from_env()
+BACKEND_URL = tc["frontends"]["backend"].value_string(required=True)
+FRACTION = tc["frontends"]["fraction"].value_int(required=True)
+CURRENCY = tc["taler"]["currency"].value_string(required=True)
+MAX_FEE = dict(value=3, fraction=0, currency=CURRENCY)
+
+app.config.from_object(__name__)
+
address@hidden
+def utility_processor():
+    def url(my_url):
+        return join_urlparts(flask.request.script_root, my_url)
+    def env(name, default=None):
+        return os.environ.get(name, default)
+    return dict(url=url, env=env)
+
+
address@hidden("/")
+def index():
+    return flask.render_template("templates/index.html", 
merchant_currency=CURRENCY)
+
address@hidden("/javascript")
+def javascript_licensing():
+    return flask.render_template("templates/javascript.html")
+
+
address@hidden("/checkout", methods=["GET"])
+def checkout():
+    amount_str = expect_parameter("donation_amount")
+    donation_receiver = expect_parameter("donation_receiver")
+    try:
+        amount = float(amount_str)
+    except ValueError:
+        logger.warn("Invalid amount ('%s')", amount_str)
+        e = flask.jsonify(error="invalid amount")
+        return flask.make_response(e, 400)
+    display_alert = flask.request.args.get("display_alert", None)
+    return flask.render_template("templates/checkout.html",
+            donation_amount=amount_str,
+            donation_receiver=donation_receiver,
+            merchant_currency=CURRENCY,
+            display_alert=display_alert)
+
+
address@hidden("/generate-contract", methods=["GET"])
+def generate_contract():
+    try:
+        donation_receiver = expect_parameter("donation_receiver")
+        donation_amount = expect_parameter("donation_amount")
+    except MissingParameterException as e:
+        return flask.jsonify(dict(error="Missing parameter '%s'" % e)), 400
+    amount = amount_from_float(float(donation_amount))
+    order_id = "donation-%s-%X-%s" % \
+               (donation_receiver,
+               random.randint(0, 0xFFFFFFFF),
+               datetime.today().strftime('%H_%M_%S'))
+    order = dict(
+        summary="Donation!",
+        nonce=flask.request.args.get("nonce"),
+        amount=amount,
+        max_fee=dict(value=1, fraction=0, currency=CURRENCY),
+        order_id=order_id,
+        products=[
+            dict(
+                description="Donation to %s" % (donation_receiver,),
+                quantity=1,
+                product_id=0,
+                price=amount,
+            ),
+        ],
+        fulfillment_url=make_url("/fulfillment", ("order_id", order_id)),
+        pay_url=make_url("/pay"),
+        merchant=dict(
+            instance=donation_receiver,
+            address="nowhere",
+            name="Kudos Inc.",
+            jurisdiction="none",
+        ),
+    )
+    r = requests.post(urljoin(BACKEND_URL, 'proposal'), json=dict(order=order))
+    if 200 != r.status_code:
+        # It is important to use 'backend_error()', as it handles
+        # the case where the backend gives NO JSON as response.
+        # For example, if it dies, or nginx hijacks somehow the
+        # response.
+        return backend_error(r)
+    return flask.jsonify(r.json()), r.status_code
+
address@hidden("/donate")
+def donate():
+    donation_receiver = expect_parameter("donation_receiver")
+    donation_amount = expect_parameter("donation_amount")
+    payment_system = expect_parameter("payment_system")
+    if "taler" != payment_system:
+        return flask.redirect(make_url("checkout",
+                                       ("donation_receiver", 
donation_receiver),
+                                       ("donation_amount", donation_amount),
+                                       ("display_alert", True)))
+    response = 
flask.make_response(flask.render_template('templates/fallback.html'), 402)
+    response.headers["X-Taler-Contract-Url"] = \
+    make_url("/generate-contract",
+             ("donation_receiver", donation_receiver),
+             ("donation_amount", donation_amount))
+    return response
+
+
address@hidden("/fulfillment")
+def fulfillment():
+    order_id = expect_parameter("order_id")
+    payed_order_ids = flask.session.get("payed_order_ids", [])
+    print("order_id:", repr(order_id))
+    print("session:", repr(flask.session))
+    if order_id in payed_order_ids:
+        data = payed_order_ids[order_id]
+        return flask.render_template(
+                "templates/fulfillment.html",
+                donation_receiver=data["donation_receiver"],
+                donation_amount=data["donation_amount"],
+                order_id=order_id,
+                currency=CURRENCY)
+        
+    response = 
flask.make_response(flask.render_template("templates/fallback.html"), 402)
+    response.headers["X-Taler-Contract-Query"] = "fulfillment_url"
+    response.headers["X-Taler-Offer-Url"] = make_url("/")
+    return response
+
+
address@hidden("/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 backend_error(r)
+    proposal_data = r.json()["contract_terms"]
+    order_id = proposal_data["order_id"]
+    payed_order_ids = flask.session["payed_order_ids"] = 
flask.session.get("payed_order_ids", {})
+    payed_order_ids[order_id] = dict(
+        donation_receiver=proposal_data["merchant"]["instance"],
+        donation_amount=amount_to_float(proposal_data["amount"])
+    )
+    print("received payment for", order_id)
+    return flask.jsonify(r.json()), r.status_code
+
address@hidden("/backoffice")
+def track():
+    response = 
flask.make_response(flask.render_template("templates/backoffice.html"))
+    return response
+
+
address@hidden("/history")
+def history():
+    qs = get_query_string().decode("utf-8")
+    url = urljoin(BACKEND_URL, "history")
+    r = requests.get(url, params=dict(parse_qsl(qs)))
+    if 200 != r.status_code:
+        return backend_error(r)
+    return flask.jsonify(r.json()), r.status_code
+
+
address@hidden("/track/order")
+def track_order():
+    instance = expect_parameter("instance")
+    order_id = expect_parameter("order_id")
+    url = urljoin(BACKEND_URL, "track/transaction")
+    r = requests.get(url, params=dict(order_id=order_id, instance=instance))
+    if 200 != r.status_code:
+        return backend_error(r)
+    return flask.jsonify(r.json()), r.status_code

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]