summaryrefslogtreecommitdiff
path: root/talermerchantdemos
diff options
context:
space:
mode:
Diffstat (limited to 'talermerchantdemos')
-rw-r--r--talermerchantdemos/landing/__init__.py3
-rw-r--r--talermerchantdemos/landing/landing.py164
l---------talermerchantdemos/landing/static1
-rw-r--r--talermerchantdemos/landing/templates/base.html.j2114
-rw-r--r--talermerchantdemos/landing/templates/error.html.j213
-rw-r--r--talermerchantdemos/landing/templates/index.html.j273
l---------talermerchantdemos/landing/translations1
7 files changed, 369 insertions, 0 deletions
diff --git a/talermerchantdemos/landing/__init__.py b/talermerchantdemos/landing/__init__.py
new file mode 100644
index 0000000..b5d856c
--- /dev/null
+++ b/talermerchantdemos/landing/__init__.py
@@ -0,0 +1,3 @@
+from talermerchantdemos.landing.landing import app
+
+__all__ = ["app"]
diff --git a/talermerchantdemos/landing/landing.py b/talermerchantdemos/landing/landing.py
new file mode 100644
index 0000000..6bc4249
--- /dev/null
+++ b/talermerchantdemos/landing/landing.py
@@ -0,0 +1,164 @@
+##
+# This file is part of GNU TALER.
+# Copyright (C) 2017, 2020 Taler Systems SA
+#
+# 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 Christian Grothoff
+# @brief Minimal Website for the landing page.
+
+import os
+import re
+import datetime
+import base64
+import logging
+from urllib.parse import urljoin
+import flask
+from flask import request
+from flask_babel import Babel
+from flask_babel import refresh
+from flask_babel import force_locale
+from flask_babel import gettext
+import traceback
+from taler.util.talerconfig import TalerConfig, ConfigurationError
+from ..httpcommon import backend_get, backend_post, self_localized
+import sys
+
+if not sys.version_info.major == 3 and sys.version_info.minor >= 6:
+ print("Python 3.6 or higher is required.")
+ print("You are using Python {}.{}.".format(sys.version_info.major, sys.version_info.minor))
+ sys.exit(1)
+
+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')
+
+LOGGER = logging.getLogger(__name__)
+TC = TalerConfig.from_env()
+try:
+ BACKEND_URL = TC["frontends"]["backend"].value_string(required=True)
+ CURRENCY = TC["taler"]["currency"].value_string(required=True)
+ APIKEY = TC["frontends"]["backend_apikey"].value_string(required=True)
+except ConfigurationError as ce:
+ print(ce)
+ exit(1)
+
+app.config.from_object(__name__)
+babel = Babel(app)
+
+LOGGER.info("Using translations from:" + ':'.join(list(babel.translation_directories)))
+translations = [str(translation) for translation in babel.list_translations()]
+if not 'en' in translations:
+ translations.append('en')
+LOGGER.info("Operating with the following translations available: " + ' '.join(translations))
+
+app.jinja_env.globals.update(self_localized=self_localized)
+
+@babel.localeselector
+def get_locale():
+ parts = request.path.split('/', 2)
+ if (2 >= len(parts)):
+ # Totally unexpected path format, do not localize
+ return "en"
+ lang = parts[1]
+ if lang in translations:
+ return lang
+ return "en"
+
+##
+# Make the environment available into templates.
+#
+# @return the environment-reading function.
+@app.context_processor
+def utility_processor():
+ def env(name, default=None):
+ return os.environ.get(name, default)
+
+ def prettydate(talerdate):
+ parsed_time = re.search(r"/Date\(([0-9]+)\)/", talerdate)
+ if not parsed_time:
+ return "malformed date given"
+ parsed_time = int(parsed_time.group(1))
+ timestamp = datetime.datetime.fromtimestamp(parsed_time)
+ # returns the YYYY-MM-DD date format.
+ return timestamp.strftime("%Y-%b-%d")
+
+ return dict(env=env, prettydate=prettydate)
+
+
+##
+# Exception handler to capture all the unmanaged errors.
+#
+# @param e the Exception object, currently unused.
+# @return flask-native response object carrying the error message
+# (and execution stack!).
+@app.errorhandler(Exception)
+def internal_error(e):
+ return flask.render_template(
+ "templates/error.html.j2",
+ message=gettext("Internal error"),
+ stack=traceback.format_exc(),
+ lang=get_locale()
+ )
+
+##
+# Serve the /favicon.ico requests.
+#
+# @return the favicon.ico file.
+@app.route("/favicon.ico")
+def favicon():
+ LOGGER.info("will look into: " + os.path.join(app.root_path, 'static'))
+ return flask.send_from_directory(
+ os.path.join(app.root_path, 'static'),
+ "favicon.ico",
+ mimetype="image/vnd.microsoft.ico"
+ )
+
+
+##
+# Serve the main index page, redirecting to /<lang>/
+#
+# @return response object of the index page.
+@app.route("/")
+def index():
+ default = 'en'
+ target = flask.request.accept_languages.best_match(translations, default)
+ return flask.redirect("/" + target + "/", code=302)
+
+##
+# Serve the internationalized main index page.
+#
+# @return response object of the index page.
+@app.route("/<lang>/", methods=["GET"])
+def start(lang):
+ return flask.render_template(
+ "templates/index.html.j2",
+ merchant_currency=CURRENCY,
+ lang=lang
+ )
+
+@app.errorhandler(404)
+def handler(e):
+ return flask.render_template(
+ "templates/error.html.j2",
+ message=gettext("Page not found"),
+ lang=get_locale()
+ )
+
+@app.errorhandler(405)
+def handler(e):
+ return flask.render_template(
+ "templates/error.html.j2",
+ message=gettext("HTTP method not allowed for this page"),
+ lang=get_locale()
+ )
diff --git a/talermerchantdemos/landing/static b/talermerchantdemos/landing/static
new file mode 120000
index 0000000..d9bc54d
--- /dev/null
+++ b/talermerchantdemos/landing/static
@@ -0,0 +1 @@
+../static/ \ No newline at end of file
diff --git a/talermerchantdemos/landing/templates/base.html.j2 b/talermerchantdemos/landing/templates/base.html.j2
new file mode 100644
index 0000000..7cf16f1
--- /dev/null
+++ b/talermerchantdemos/landing/templates/base.html.j2
@@ -0,0 +1,114 @@
+<!DOCTYPE html>
+<!--
+ This file is part of GNU TALER.
+ Copyright (C) 2014, 2015, 2016, 2020 Taler Systems SA
+
+ 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
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+-->
+
+<html data-taler-nojs="true">
+<head>
+ <title>{{ gettext("Taler Demo") }}</title>
+ <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='pure.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='demo.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='navbar.css') }}" />
+ <style>
+ .warn {
+ background-color: #aa393977;
+ padding: 1em;
+ }
+ @keyframes hoveranim {
+ from {left:0;}
+ to {left:1vw;}
+ }
+ @keyframes hoveranimrevert {
+ from {left:1vw;}
+ to {left:0;}
+ }
+ .notice {
+ border-radius: 1em;
+ background: #0333;
+ border-left: 0.3em solid #033;
+ padding-left: 1em;
+ padding-top: 0.5em;
+ padding-bottom: 0.5em;
+ margin-top: 2em;
+ margin-bottom: 2em;
+ }
+ .notice {
+ position: relative;
+ left: 0;
+ animation-name: hoveranimrevert;
+ animation-duration: 1s;
+ }
+ .notice:hover {
+ left: 1vw;
+ animation-name: hoveranim;
+ animation-duration: 1s;
+ }
+ #main a:link, #main a:visited, #main a:hover, #main a:active {
+ color: black;
+ }
+ </style>
+
+ {% block styles %}{% endblock %}
+ {% block scripts %}{% endblock %}
+</head>
+
+<body>
+ <header class="demobar" style="display: flex; flex-direction: column;">
+ <h1><span class="tt adorn-brackets">{{ gettext("Taler Demo") }}</span></h1>
+ <h1><span class="it"><a href="{{ env('TALER_ENV_URL_MERCHANT_SURVEY') }}">{{ gettext("Survey") }}</a></span></h1>
+ <p>{{
+ gettext("This is the Taler demo.") + "<br>" +
+ gettext("Here you can try out the Taler payment system using a toy currency.")
+ }}
+ </p>
+ </header>
+ <div style="display:flex; flex-direction: column;" class="navcontainer">
+ <nav class="demolist">
+ <a href="{{ env('TALER_ENV_URL_INTRO', '#') }}" class="active">{{gettext("Introduction")}}</a>
+ <a href="{{ env('TALER_ENV_URL_BANK', '#') }}">{{gettext("Bank")}}</a>
+ <a href="{{ env('TALER_ENV_URL_MERCHANT_BLOG', '#') }}">{{gettext("Essay Shop")}}</a>
+ <a href="{{ env('TALER_ENV_URL_MERCHANT_DONATIONS', '#') }}">{{gettext("Donations")}}</a>
+ <a href="{{ env('TALER_ENV_URL_MERCHANT_SURVEY', '#') }}">{{gettext("Tipping/Survey")}}</a>
+ <!-- a href="{{ env('TALER_ENV_URL_BACKOFFICE', '#') }}">{{gettext("Back-office")}}</a -->
+ <span class="right">
+ {{ gettext("English [en]") }}
+ <!-- <input type="checkbox"> -->
+ <div class="nav">
+ <br>
+ <!--<hr style="width: 100%;">-->
+ {% if lang != 'en' %}
+ <a href="/en/" class="navbtn">English [en]</a><br>
+ {% endif %}
+ {% if lang != 'de' %}
+ <a href="/de/" class="navbtn">Deutsch [de]</a><br>
+ {% endif %}
+ </div>
+ </span>
+ </nav>
+ </div>
+
+ <section id="main" class="content">
+ {% block main %}
+ This is the main content of the page.
+ {% endblock %}
+ <hr />
+ <div>
+ <p>{{ gettext('You can learn more about Taler on our main <a href="{site}">website</a>.').format(site="https://taler.net/") }}</p>
+ <div style="flex-grow:1"></div>
+ <p>Copyright &copy; 2014&mdash;2020 Taler Systems SA</p>
+ </div>
+ </section>
+</body>
+</html>
diff --git a/talermerchantdemos/landing/templates/error.html.j2 b/talermerchantdemos/landing/templates/error.html.j2
new file mode 100644
index 0000000..009947c
--- /dev/null
+++ b/talermerchantdemos/landing/templates/error.html.j2
@@ -0,0 +1,13 @@
+{% extends "templates/base.html.j2" %}
+{% block main %}
+ <h1>{{ gettext("Error encountered") }}</h1>
+
+ <p>{{ message }}</p>
+
+ {% if stack %}
+ <p>{{gettext("Stack trace:")}}</p>
+ <pre>
+ {{ stack }}
+ </pre>
+ {% endif %}
+{% endblock main %}
diff --git a/talermerchantdemos/landing/templates/index.html.j2 b/talermerchantdemos/landing/templates/index.html.j2
new file mode 100644
index 0000000..cc6b874
--- /dev/null
+++ b/talermerchantdemos/landing/templates/index.html.j2
@@ -0,0 +1,73 @@
+{% extends "templates/base.html.j2" %}
+{% block main %}
+ <article>
+ <h2>Step 1: Install the Taler wallet</h2>
+ Install the wallet from the <a href="https://wallet.taler.net/">installation page</a>.
+ It only takes one click.
+ <p class="bluebox taler-installed-hide">
+ You don't have a wallet installed yet.
+ </p>
+ <p class="greenbox taler-installed-show">
+ Congratulations, you have installed the Taler wallet correctly.
+ You can now proceed with the next steps.
+ </p>
+ </article>
+
+ <article>
+ <h2>Step 2: Withdraw coins</h2>
+ <p>
+
+ Now you can withdraw coins into your wallet by going to our <a href="{{ bank_url }}">bank</a>.
+
+ In this demo you are paying with KUDOS, an imaginary currency. When you
+ create an account at our bank, you'll get 100 KUDOS for free.
+ </p>
+ <p class="graybox">
+ We cannnot check if you were able to complete this step, since websites
+ cannot see the balance in your wallet. Please click on the Taler icon
+ in your browser to check your balance.
+ </p>
+ </article>
+
+ <article>
+ <h2>Step 3: Pay</h2>
+ We have two demo merchants where you can spend your coins:
+ <ul>
+ <li>
+ The <a href="{{ merchant_blog_url }}">essay store</a>, where you can pay KUDOS for
+ individual chapters of Richard Stallman's book "Free Software, Free
+ Society", which is also available for free at <a href="http://www.fsf.org/">the FSF</a>.
+ </li>
+ <li>
+ The <a href="{{ merchant_donations_url }}">project donation website</a>, where
+ you can show respect to a software project of your choice
+ by giving them KUDOS.
+ </li>
+ </ul>
+ </article>
+ <article>
+ <h2>Step 4: Check money flow</h2>
+ <ul>
+ <li>
+ Check if people who received your Taler payment got eventually
+ paid by the exchange via a wire transfer; visit the:
+ <a href="{{ bank_url }}/public-accounts">public accounts page</a> at the bank.
+ Note that only those account whose owners gave permission are showed
+ on that page.
+ </li>
+ </ul>
+ </article>
+ <!-- article>
+ <h2>Step 5: Merchant? Consult back-office</h2>
+ <ul>
+ <li>
+ If you are a merchant, you can check the <a href="{{ backoffice_url }}">back-office</a>
+ website to see how your Taler transactions got payed back by bank wire transfers.
+ </li>
+ </ul>
+ </article -->
+ <article>
+ <h2>Step 5: Reach out to us</h2>
+ Let us know what you think by <a href="mailto:demo-feedback@taler.net">contacting us</a>.
+ </article>
+{% endblock %}
diff --git a/talermerchantdemos/landing/translations b/talermerchantdemos/landing/translations
new file mode 120000
index 0000000..0a951f7
--- /dev/null
+++ b/talermerchantdemos/landing/translations
@@ -0,0 +1 @@
+../../translations/ \ No newline at end of file