gnunet-svn
[Top][All Lists]
Advanced

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

[taler-taler-merchant-demos] 07/18: towards supporting language switchin


From: gnunet
Subject: [taler-taler-merchant-demos] 07/18: towards supporting language switching
Date: Sat, 10 Oct 2020 22:55:41 +0200

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

grothoff pushed a commit to branch master
in repository taler-merchant-demos.

commit d6459ab53ef80f1c799324ea5fa9709f6652db38
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sun Sep 6 18:47:50 2020 +0200

    towards supporting language switching
---
 talermerchantdemos/blog/articles/scrap1_11.html    |  1 -
 talermerchantdemos/blog/blog.py                    | 48 ++++++++++++++--------
 talermerchantdemos/blog/content.py                 | 13 +++---
 .../blog/templates/article_frame.html              |  5 ++-
 .../blog/templates/confirm_refund.html             |  4 +-
 talermerchantdemos/blog/templates/index.html       |  7 ++--
 6 files changed, 47 insertions(+), 31 deletions(-)

diff --git a/talermerchantdemos/blog/articles/scrap1_11.html 
b/talermerchantdemos/blog/articles/scrap1_11.html
index 71c693b..17471df 100644
--- a/talermerchantdemos/blog/articles/scrap1_11.html
+++ b/talermerchantdemos/blog/articles/scrap1_11.html
@@ -52,4 +52,3 @@ traditional style, please visit
   <br/>
  </p>
  <img alt="song-book-jutta-scrunch-crop" 
src="/essay/11._The_Free_Software_Song/data/song-book-jutta-scrunch-crop.jpg"/>
-
diff --git a/talermerchantdemos/blog/blog.py b/talermerchantdemos/blog/blog.py
index c54a8d6..37d7c20 100644
--- a/talermerchantdemos/blog/blog.py
+++ b/talermerchantdemos/blog/blog.py
@@ -94,18 +94,29 @@ def internal_error(e):
 
 
 ##
-# Serve the main index page.
+# Serve the main index page, redirecting to /<lang>/
 #
 # @return response object of the index page.
 @app.route("/")
 def index():
+    supported = ['en', 'de' ]
+    default = 'en'
+    target = flask.request.accept_languages.best_match(supported, default)
+    return flask.redirect("/" + target + "/", code=302)
+
+##
+# Serve the main index page for a particular language.
+#
+# @return response object of the index page.
+@app.route("/<lang>/")
+def start(lang):
     return flask.render_template(
-        "templates/index.html", merchant_currency=CURRENCY, 
articles=ARTICLES.values()
+        "templates/index.html", lang=lang, merchant_currency=CURRENCY, 
articles=ARTICLES.values()
     )
 
 
-@app.route("/confirm-refund/<order_id>", methods=["GET"])
-def confirm_refund(order_id):
+@app.route("/<lang>/confirm-refund/<order_id>", methods=["GET"])
+def confirm_refund(lang, order_id):
     session_id = flask.session.get("session_id", "")
     pay_status = backend_get(
         BACKEND_URL, f"private/orders/{order_id}", 
params=dict(session_id=session_id)
@@ -113,7 +124,7 @@ def confirm_refund(order_id):
     order_status = pay_status.get("order_status")
     if order_status != "paid":
         err_abort(
-            400, message="can't refund unpaid article",
+            400, message="Cannot refund unpaid article",
         )
     article_name = pay_status["contract_terms"]["extra"]["article_name"]
     return flask.render_template(
@@ -127,16 +138,15 @@ def confirm_refund(order_id):
 #
 # @param order_id the order ID of the transaction to refund.
 # @return the following errors (named by HTTP response code):
-#         - 400: no article was asked to be refunded!
-#         - 401: the refund was asked on a non-payed article.
-#         - 500: the backend was unable to give response.
-#         Or, in the successful case, a redirection to the
-#         "refund URL" is returned; then the wallet will run
-#         the refund protocol in a transparent way.
+#         - 400: order unknown
+#         - 402: the refund was asked on an unpaid article.
+#         - 302: in the successful case, a redirection to the
+#           "refund URL" is returned; then the wallet will run
+#           the refund protocol in a transparent way.
 @app.route("/refund/<order_id>", methods=["POST"])
-def refund(order_id):
+def refund(lang, order_id):
     if not order_id:
-        return flask.jsonify(dict(error="Aborting refund: article not 
payed")), 401
+        return flask.jsonify(dict(error="Aborting refund: order unknown")), 400
     session_id = flask.session.get("session_id", "")
     pay_status = backend_get(
         BACKEND_URL, f"private/orders/{order_id}", 
params=dict(session_id=session_id)
@@ -204,9 +214,10 @@ def render_article(article_name, data, order_id):
 #         In the successful case, either the article is returned, or
 #         the browser gets redirected to a page where the wallet can
 #         send the payment.
-@app.route("/essay/<article_name>")
+@app.route("/<lang>/essay/<article_name>")
+@app.route("/<lang>/essay/<article_name>/data/<data>")
 @app.route("/essay/<article_name>/data/<data>")
-def article(article_name, data=None):
+def article(article_name, lang=None, data=None):
     # We use an explicit session ID so that each payment (or payment replay) is
     # bound to a browser.  This forces re-play and prevents sharing the article
     # by just sharing the URL.
@@ -218,9 +229,11 @@ def article(article_name, data=None):
     ##
     # First-timer; generate order first.
     if not order_id:
+        if not lang:
+            err_abort(403, message="Direct access forbidden")
         order = dict(
             amount=ARTICLE_AMOUNT,
-            extra=dict(article_name=article_name),
+            extra=dict(article_name=article_name,lang=lang),
             fulfillment_url=flask.request.base_url,
             summary="Essay: " + article_name.replace("_", " "),
             # 10 minutes time for a refund
@@ -251,5 +264,6 @@ def article(article_name, data=None):
     # Redirect the browser to a page where the wallet can
     # run the payment protocol.
     response = flask.redirect(pay_status["order_status_url"])
-    response.set_cookie("order_id", order_id, path=f"/essay/{article_name}")
+    response.set_cookie("order_id", order_id, 
path=urllib.parse.quote(f"/essay/{article_name}"))
+    response.set_cookie("order_id", order_id, 
path=urllib.parse.quote(f"/{lang}/essay/{article_name}"))
     return response
diff --git a/talermerchantdemos/blog/content.py 
b/talermerchantdemos/blog/content.py
index a0e90dd..fa9ace2 100644
--- a/talermerchantdemos/blog/content.py
+++ b/talermerchantdemos/blog/content.py
@@ -26,7 +26,7 @@ from pkg_resources import resource_stream, resource_filename
 LOGGER = logging.getLogger(__name__)
 NOISY_LOGGER = logging.getLogger("chardet.charsetprober")
 NOISY_LOGGER.setLevel(logging.INFO)
-Article = namedtuple("Article", "slug title teaser main_file extra_files")
+Article = namedtuple("Article", "slug title teaser main_file extra_files lang")
 
 ##
 # @var if a article is added to this list, then it will
@@ -43,8 +43,9 @@ ARTICLES = OrderedDict()
 # @param main_file path to the article's HTML file.
 # @param extra_file collection of extra files associated with the
 #        article, like images and sounds.
-def add_article(slug, title, teaser, main_file, extra_files):
-    ARTICLES[slug] = Article(slug, title, teaser, main_file, extra_files)
+# @param lang language of the arcile
+def add_article(slug, title, teaser, main_file, extra_files, lang='en'):
+    ARTICLES[slug] = Article(slug, title, teaser, main_file, extra_files, lang)
 
 
 ##
@@ -85,7 +86,7 @@ def add_from_html(resource_name, teaser_paragraph=0, 
title=None):
     if title is None:
         title_el = soup.find("h1", attrs={"class": ["chapter", "unnumbered"]})
         if title_el is None:
-            LOGGER.warning("Can't extract title from '%s'", resource_name)
+            LOGGER.warning("Cannot extract title from '%s'", resource_name)
             title = resource_name
         else:
             title = title_el.get_text().strip()
@@ -97,7 +98,7 @@ def add_from_html(resource_name, teaser_paragraph=0, 
title=None):
         teaser = paragraphs[teaser_paragraph].get_text()
     else:
         teaser = teaser.get_text()
-    re_proc = re.compile("^/essay/[^/]+/data/[^/]+$")
+    re_proc = re.compile("^/[^/][^/]/essay/[^/]+/data/[^/]+$")
     imgs = soup.find_all("img")
     extra_files = []
     for img in imgs:
@@ -114,7 +115,7 @@ def add_from_html(resource_name, teaser_paragraph=0, 
title=None):
             else:
                 LOGGER.warning("Image src and slug don't match: '%s' != '%s'" \
                                % (img['src'].split(os.sep)[2], slug))
-    add_article(slug, title, teaser, resource_name, extra_files)
+    add_article(slug, title, teaser, resource_name, extra_files, 'en')
 
 
 add_from_html("blog/articles/scrap1_U.0.html", 0)
diff --git a/talermerchantdemos/blog/templates/article_frame.html 
b/talermerchantdemos/blog/templates/article_frame.html
index 1efc0d1..8c2b6d4 100644
--- a/talermerchantdemos/blog/templates/article_frame.html
+++ b/talermerchantdemos/blog/templates/article_frame.html
@@ -4,7 +4,8 @@
 
 <hr>
 <p>
-  You don't like this article?  <a href="{{ url_for('confirm_refund', 
order_id=order_id) }}">Get a refund</a> within
-  the first hour after buying it.
+  You did not like this article?
+  <a href="{{ url_for('confirm_refund', lang='en', order_id=order_id) }}">Get 
a refund</a>
+  within the first hour after buying it.
 </p>
 {% endblock main %}
diff --git a/talermerchantdemos/blog/templates/confirm_refund.html 
b/talermerchantdemos/blog/templates/confirm_refund.html
index 10aaa74..c4773d3 100644
--- a/talermerchantdemos/blog/templates/confirm_refund.html
+++ b/talermerchantdemos/blog/templates/confirm_refund.html
@@ -3,12 +3,12 @@
   <h1>Refund Article?</h1>
 
   <p>
-    Do you want to get a refund for the article <em>{{ article_name }}</em>?  
After you've requested a refund,
+    Do you want to get a refund for the article <em>{{ article_name }}</em>?  
After you have requested a refund,
     you won't be able to read the article anymore.
   </p>
 
   <p>
-      You will only be able to receive the refund on the same wallet that 
you've used to pay
+      You will only be able to receive the refund on the same wallet that you 
have used to pay
       for this article originally.
   </p>
 
diff --git a/talermerchantdemos/blog/templates/index.html 
b/talermerchantdemos/blog/templates/index.html
index 0159779..0702bf7 100644
--- a/talermerchantdemos/blog/templates/index.html
+++ b/talermerchantdemos/blog/templates/index.html
@@ -24,14 +24,15 @@
     <h2>Chapters</h2>
     <div>
       Click on an individual chapter to to purchase it.  You can
-      get free, virtual money to buy articles on this page at the <a href="{{ 
env('TALER_ENV_URL_BANK', '#') }}">bank</a>.
+      get free, virtual money to buy articles on this page at the
+      <a href="{{ env('TALER_ENV_URL_BANK', '#') }}">bank</a>.
     </div>
 
     <div>
       {% for article in articles %}
       <div class="notice">
-      <h3><a href="{{ url_for('article', article_name=article.slug) 
}}">{{article.title}}</a></h3>
-      <p>{{ article.teaser|safe }} <a href="{{ url_for('article', 
article_name=article.slug) }}">(Pay to read more...)</a></p>
+      <h3><a href="{{ url_for('article', lang=article.lang, 
article_name=article.slug) }}">{{article.title}}</a></h3>
+      <p>{{ article.teaser|safe }} <a href="{{ url_for('article', 
lang=article.lang, article_name=article.slug) }}">(Pay to read more...)</a></p>
       </div>
       {% else %}
       <em>(No articles available)</em>

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

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