taler-merchant-demos

Python-based Frontends for the Demonstration Web site
Log | Files | Refs | Submodules | README | LICENSE

landing.py (5209B)


      1 ##
      2 # This file is part of GNU TALER.
      3 # Copyright (C) 2017, 2020 Taler Systems SA
      4 #
      5 # TALER is free software; you can redistribute it and/or modify it under the
      6 # terms of the GNU Lesser General Public License as published by the Free Software
      7 # Foundation; either version 2.1, or (at your option) any later version.
      8 #
      9 # TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     10 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11 # A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
     12 #
     13 # You should have received a copy of the GNU Lesser General Public License along with
     14 # GNU TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15 #
     16 # @author Christian Grothoff
     17 # @brief Minimal Website for the landing page.
     18 
     19 import os
     20 import base64
     21 import logging
     22 import flask
     23 import werkzeug
     24 from flask import url_for
     25 from flask_babel import Babel
     26 from flask_babel import gettext
     27 from werkzeug.middleware.proxy_fix import ProxyFix
     28 import traceback
     29 from ..appconfig import load_taler_config
     30 from ..httpcommon import (
     31     get_locale,
     32     make_utility_processor,
     33 )
     34 import sys
     35 
     36 if not sys.version_info.major == 3 and sys.version_info.minor >= 6:
     37     print("Python 3.6 or higher is required.")
     38     print(
     39         "You are using Python {}.{}.".format(
     40             sys.version_info.major, sys.version_info.minor
     41         )
     42     )
     43     sys.exit(1)
     44 
     45 app = flask.Flask(__name__, template_folder="../templates", static_folder="../static")
     46 app.wsgi_app = ProxyFix(app.wsgi_app, x_host=1, x_prefix=1)
     47 app.debug = True
     48 app.secret_key = base64.b64encode(os.urandom(64)).decode("utf-8")
     49 
     50 LOGGER = logging.getLogger(__name__)
     51 
     52 config = load_taler_config()
     53 
     54 CURRENCY = config["taler"]["currency"].value_string(required=True)
     55 
     56 
     57 BABEL_TRANSLATION_DIRECTORIES = "../translations"
     58 
     59 app.config.from_object(__name__)
     60 
     61 babel = Babel(app, locale_selector=get_locale)
     62 
     63 # Add context processor that will make additional variables
     64 # and functions available in the template.
     65 app.context_processor(
     66     make_utility_processor("landing", os.environ.get("TALER_ENV_URL_INTRO"))
     67 )
     68 
     69 
     70 ##
     71 # Exception handler to capture all the unmanaged errors.
     72 #
     73 # @param e the Exception object, currently unused.
     74 # @return flask-native response object carrying the error message
     75 #         (and execution stack!).
     76 @app.errorhandler(Exception)
     77 def internal_error(e):
     78     return flask.render_template(
     79         "landing-error.html.j2",
     80         page_title=gettext("GNU Taler Demo: Error"),
     81         message=gettext("Internal error"),
     82         stack=traceback.format_exc(),
     83     )
     84 
     85 
     86 ##
     87 # Serve the /favicon.ico requests.
     88 #
     89 # @return the favicon.ico file.
     90 @app.route("/favicon.ico")
     91 def favicon():
     92     LOGGER.info("will look into: " + os.path.join(app.root_path, "static"))
     93     return flask.send_from_directory(
     94         os.path.join(app.root_path, "static"),
     95         "favicon.ico",
     96         mimetype="image/vnd.microsoft.ico",
     97     )
     98 
     99 
    100 ##
    101 # Serve the main index page, redirecting to /<lang>/
    102 #
    103 # @return response object of the index page.
    104 @app.route("/")
    105 def index():
    106     default = "en"
    107     translations = [x.language for x in babel.list_translations()]
    108     target = flask.request.accept_languages.best_match(translations, default)
    109     return flask.redirect(url_for("index") + target + "/", code=302)
    110 
    111 
    112 ##
    113 # Serve the internationalized main index page.
    114 #
    115 # @return response object of the index page.
    116 @app.route("/<lang>/", methods=["GET"])
    117 def start(lang):
    118 
    119     # get_locale defaults to english, hence the
    120     # condition below happens only when lang is
    121     # wrong or unsupported, respond 404.
    122     if lang != get_locale():
    123         raise werkzeug.exceptions.NotFound()
    124 
    125     if x := os.environ.get("TALER_ENV_URL_BANK"):
    126         bank_url = x
    127         bank_register_url = bank_url
    128         bank_public_accounts_url = bank_url + "#public-accounts"
    129     else:
    130         bank_register_url = "#"
    131         bank_url = "#"
    132         bank_public_accounts_url = "#"
    133 
    134     if x := os.environ.get("TALER_ENV_URL_MERCHANT_BLOG"):
    135         merchant_blog_url = "/".join([x.strip("/"), lang])
    136     else:
    137         merchant_blog_url = "#"
    138 
    139     if x := os.environ.get("TALER_ENV_URL_MERCHANT_DONATIONS"):
    140         merchant_donations_url = "/".join([x.strip("/"), lang])
    141     else:
    142         merchant_donations_url = "#"
    143 
    144     return flask.render_template(
    145         "landing-index.html.j2",
    146         merchant_currency=CURRENCY,
    147         page_title=gettext("GNU Taler Demo"),
    148         bank_register_url=bank_register_url,
    149         bank_url=bank_url,
    150         bank_public_accounts_url=bank_public_accounts_url,
    151         merchant_blog_url=merchant_blog_url,
    152         merchant_donations_url=merchant_donations_url,
    153     )
    154 
    155 
    156 @app.errorhandler(404)  # How to trigger this?
    157 @app.errorhandler(werkzeug.exceptions.NotFound)
    158 def handler_404(e):
    159     return flask.render_template(
    160         "landing-error.html.j2",
    161         page_title=gettext("GNU Taler Demo: Error"),
    162         message=gettext("Page not found"),
    163     )
    164 
    165 
    166 @app.errorhandler(405)
    167 def handler_405(e):
    168     return flask.render_template(
    169         "landing-error.html.j2",
    170         page_title=gettext("GNU Taler Demo: Error"),
    171         message=gettext("HTTP method not allowed for this page"),
    172     )