[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] [taler-survey] branch stable updated (ac0b8a1 -> 90d2bb4)
From: |
gnunet |
Subject: |
[GNUnet-SVN] [taler-survey] branch stable updated (ac0b8a1 -> 90d2bb4) |
Date: |
Thu, 18 Jan 2018 18:48:22 +0100 |
This is an automated email from the git hooks/post-receive script.
dold pushed a change to branch stable
in repository survey.
discard ac0b8a1 use new tipping API, fix various little things
This update removed existing revisions from the reference, leaving the
reference pointing at a previous point in the repository history.
* -- * -- N refs/heads/stable (90d2bb4)
\
O -- O -- O (ac0b8a1)
Any revisions marked "omit" are not gone; other references still
refer to them. Any revisions marked "discard" are gone forever.
No new revisions were added by this update.
Summary of changes:
talersurvey/survey/amount.py | 135 ++++++++++++++++++++++++++++++++
talersurvey/survey/survey.py | 66 ++++++++--------
talersurvey/survey/templates/base.html | 10 +--
talersurvey/survey/templates/index.html | 2 +-
4 files changed, 175 insertions(+), 38 deletions(-)
create mode 100644 talersurvey/survey/amount.py
diff --git a/talersurvey/survey/amount.py b/talersurvey/survey/amount.py
new file mode 100644
index 0000000..46e3446
--- /dev/null
+++ b/talersurvey/survey/amount.py
@@ -0,0 +1,135 @@
+# This file is part of TALER
+# (C) 2017 TALER SYSTEMS
+#
+# This library 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 of the License, or (at your option) any later version.
+#
+# This library 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 this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
+#
+# @author Marcello Stanisci
+# @version 0.1
+# @repository https://git.taler.net/copylib.git/
+# This code is "copylib", it is versioned under the Git repository
+# mentioned above, and it is meant to be manually copied into any project
+# which might need it.
+
+class CurrencyMismatch(Exception):
+ def __init__(self, curr1, curr2):
+ super(CurrencyMismatch, self).__init__(
+ "%s vs %s" % (curr1, curr2))
+
+class BadFormatAmount(Exception):
+ def __init__(self, faulty_str):
+ super(BadFormatAmount, self).__init__(
+ "Bad format amount: " + faulty_str)
+
+class Amount:
+ # How many "fraction" units make one "value" unit of currency
+ # (Taler requires 10^8). Do not change this 'constant'.
+ @staticmethod
+ def _fraction():
+ return 10 ** 8
+
+ @staticmethod
+ def _max_value():
+ return (2 ** 53) - 1
+
+ def __init__(self, currency, value=0, fraction=0):
+ # type: (str, int, int) -> Amount
+ assert value >= 0 and fraction >= 0
+ self.value = value
+ self.fraction = fraction
+ self.currency = currency
+ self.__normalize()
+ assert self.value <= Amount._max_value()
+
+ # Normalize amount
+ def __normalize(self):
+ if self.fraction >= Amount._fraction():
+ self.value += int(self.fraction / Amount._fraction())
+ self.fraction = self.fraction % Amount._fraction()
+
+ # Parse a string matching the format "A:B.C"
+ # instantiating an amount object.
+ @classmethod
+ def parse(cls, amount_str):
+ exp = r'^\s*([-_*A-Za-z0-9]+):([0-9]+)\.([0-9]+)\s*$'
+ import re
+ parsed = re.search(exp, amount_str)
+ if not parsed:
+ raise BadFormatAmount(amount_str)
+ value = int(parsed.group(2))
+ fraction = 0
+ for i, digit in enumerate(parsed.group(3)):
+ fraction += int(int(digit) * (Amount._fraction() / 10 ** (i+1)))
+ return cls(parsed.group(1), value, fraction)
+
+ # Comare two amounts, return:
+ # -1 if a < b
+ # 0 if a == b
+ # 1 if a > b
+ @staticmethod
+ def cmp(am1, am2):
+ if am1.currency != am2.currency:
+ raise CurrencyMismatch(am1.currency, am2.currency)
+ if am1.value == am2.value:
+ if am1.fraction < am2.fraction:
+ return -1
+ if am1.fraction > am2.fraction:
+ return 1
+ return 0
+ if am1.value < am2.value:
+ return -1
+ return 1
+
+ def set(self, currency, value=0, fraction=0):
+ self.currency = currency
+ self.value = value
+ self.fraction = fraction
+
+ # Add the given amount to this one
+ def add(self, amount):
+ if self.currency != amount.currency:
+ raise CurrencyMismatch(self.currency, amount.currency)
+ self.value += amount.value
+ self.fraction += amount.fraction
+ self.__normalize()
+
+ # Subtract passed amount from this one
+ def subtract(self, amount):
+ if self.currency != amount.currency:
+ raise CurrencyMismatch(self.currency, amount.currency)
+ if self.fraction < amount.fraction:
+ self.fraction += Amount._fraction()
+ self.value -= 1
+ if self.value < amount.value:
+ raise ValueError('self is lesser than amount to be subtracted')
+ self.value -= amount.value
+ self.fraction -= amount.fraction
+
+ # Dump string from this amount, will put 'ndigits' numbers
+ # after the dot.
+ def stringify(self, ndigits):
+ assert ndigits > 0
+ ret = '%s:%s.' % (self.currency, str(self.value))
+ fraction = self.fraction
+ while ndigits > 0:
+ ret += str(int(fraction / (Amount._fraction() / 10)))
+ fraction = (fraction * 10) % (Amount._fraction())
+ ndigits -= 1
+ return ret
+
+ # Dump the Taler-compliant 'dict' amount
+ def dump(self):
+ return dict(value=self.value,
+ fraction=self.fraction,
+ currency=self.currency)
diff --git a/talersurvey/survey/survey.py b/talersurvey/survey/survey.py
index d068f66..6c2f4c8 100644
--- a/talersurvey/survey/survey.py
+++ b/talersurvey/survey/survey.py
@@ -48,53 +48,55 @@ def backend_error(requests_response):
@app.context_processor
def utility_processor():
+
+ def join_urlparts(*parts):
+ ret = ""
+ part = 0
+ while part < len(parts):
+ buf = parts[part]
+ part += 1
+ if ret.endswith("/"):
+ buf = buf.lstrip("/")
+ elif ret and not buf.startswith("/"):
+ buf = "/" + buf
+ ret += buf
+ return ret
+
+ 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)
-def err_abort(abort_status_code, **params):
- t = flask.render_template("templates/error.html", **params)
- flask.abort(flask.make_response(t, abort_status_code))
-
-
-def backend_post(endpoint, json):
- try:
- resp = requests.post(urljoin(BACKEND_URL, endpoint), json=json)
- except requests.ConnectionError:
- err_abort(500, message="Could not establish connection to backend")
- try:
- response_json = resp.json()
- except ValueError:
- err_abort(500, message="Could not parse response from backend",
- status_code=resp.status_code)
address@hidden("/tip-pickup", methods=["POST"])
+def pick():
+ request_body = flask.request.get_json()
+ resp = requests.post(urljoin(BACKEND_URL, "tip-pickup"),
+ json=request_body)
if resp.status_code != 200:
- err_abort(500, message="Backend returned error status",
- json=response_json, status_code=resp.status_code)
- return response_json
-
-
address@hidden(Exception)
-def internal_error(e):
- return flask.render_template("templates/error.html",
- message="Internal error",
- stack=traceback.format_exc())
-
+ return backend_error(resp)
+ response_body = resp.json()
+ return flask.jsonify(response_body)
@app.route("/submit-survey", methods=["POST"])
def submit_survey():
tip_spec = dict(pickup_url=urljoin(flask.request.base_url, "/tip-pickup"),
- amount=CURRENCY + ":1.0",
+ amount=Amount(CURRENCY, 1).dump(),
next_url=os.environ.get("TALER_ENV_URL_INTRO",
"https://taler.net/"),
instance="default",
justification="Payment methods survey")
- resp = backend_post("tip-authorize", tip_spec)
+ resp = requests.post(urljoin(BACKEND_URL, "tip-authorize"),
+ json=tip_spec)
+ if resp.status_code != 200:
+ return backend_error(resp)
- if resp.get("tip_redirect_url"):
- flask.redirect(resp["tip_redirect_url"]
+ response = flask.make_response(
+ flask.render_template("templates/wait.html", success=True),
+ 402)
+ response.headers["X-Taler-Tip"] = resp.json()["tip_token"]
- err_abort(500, message="Tipping failed, unexpected backend response",
- json=resp)
+ return response
@app.route("/", methods=["GET"])
diff --git a/talersurvey/survey/templates/base.html
b/talersurvey/survey/templates/base.html
index 879a24d..3826797 100644
--- a/talersurvey/survey/templates/base.html
+++ b/talersurvey/survey/templates/base.html
@@ -18,10 +18,10 @@
<html>
<head>
<title>Taler Survey Demo</title>
- <link rel="stylesheet" type="text/css" href="{{ url_for('static',
filename='web-common/pure.css') }}" />
- <link rel="stylesheet" type="text/css" href="{{ url_for('static',
filename='web-common/demo.css') }}" />
- <script src="{{ url_for('static', filename='web-common/taler-wallet-lib.js')
}}" type="application/javascript"></script>
- <script src="{{ url_for('static', filename='static/web-common/lang.js') }}"
type="application/javascript"></script>
+ <link rel="stylesheet" type="text/css" href="{{
url('/static/web-common/pure.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{
url('/static/web-common/demo.css') }}" />
+ <script src="{{ url("/static/web-common/taler-wallet-lib.js") }}"
type="application/javascript"></script>
+ <script src="{{ url("/static/web-common/lang.js") }}"
type="application/javascript"></script>
{% block styles %}{% endblock %}
{% block scripts %}{% endblock %}
</head>
@@ -41,7 +41,7 @@
</div>
<section id="main" class="content">
- <a href="{{ url_for('index') }}">
+ <a href="{{ url("/") }}">
<div id="logo">
<svg height="100" width="100">
<circle cx="50" cy="50" r="40" stroke="darkcyan" stroke-width="6"
fill="white" />
diff --git a/talersurvey/survey/templates/index.html
b/talersurvey/survey/templates/index.html
index f40c235..1799abd 100644
--- a/talersurvey/survey/templates/index.html
+++ b/talersurvey/survey/templates/index.html
@@ -8,7 +8,7 @@
</p>
</div>
<div>
- <form action="{{ url_for('submit_survey') }}" method="post"
class="pure-form pure-form-stacked">
+ <form action="{{ url('/submit-survey') }}" method="post" class="pure-form
pure-form-stacked">
<legend>What do you prefer?</legend>
<fieldset>
<label for="option-taler">
--
To stop receiving notification emails like this one, please contact
address@hidden
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] [taler-survey] branch stable updated (ac0b8a1 -> 90d2bb4),
gnunet <=