gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] branch master updated: first steps towards generating (


From: gnunet
Subject: [taler-merchant] branch master updated: first steps towards generating (ugly) HTML replies for /orders/
Date: Sun, 26 Jul 2020 12:44:56 +0200

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

grothoff pushed a commit to branch master
in repository merchant.

The following commit(s) were added to refs/heads/master by this push:
     new 602f5e3  first steps towards generating (ugly) HTML replies for 
/orders/
602f5e3 is described below

commit 602f5e3e0824d9c2c9dd1fab29342ecbce3b78da
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sun Jul 26 12:44:53 2020 +0200

    first steps towards generating (ugly) HTML replies for /orders/
---
 README                                           |   2 +-
 configure.ac                                     |  35 ++++
 src/backend/Makefile.am                          |  21 +-
 src/backend/taler-merchant-httpd_get-orders-ID.c | 237 +++++++++++++++++++++--
 4 files changed, 257 insertions(+), 38 deletions(-)

diff --git a/README b/README
index 9977eef..69f3a3f 100644
--- a/README
+++ b/README
@@ -27,7 +27,7 @@ libgcrypt: LGPL, owned by Free Software Foundation
 postgresql: PostgreSQL License, AGPL- and LGPL-Compatible, owned by The 
PostgreSQL
 Global Development Group
 libgnunetutil (in all of its variants): GPLv3+, owned by GNUnet e.V.
-PHP:  PHP License, AGPL- and LGPL-Compatible, owned by The PHP Group
+libqrencode: LGPL v2.1+, Copyright Kentaro Fukuchi
 
 5. DIRECTORY STRUCTURE
 
diff --git a/configure.ac b/configure.ac
index 0f5a5fb..399f759 100644
--- a/configure.ac
+++ b/configure.ac
@@ -132,6 +132,41 @@ PKG_CHECK_MODULES([JANSSON], [jansson >= 2.3],
 *** You need libjansson to build this program.
 ***]])])
 
+
+# test for libqrencode
+qrencode=0
+QR_LIBS="-lqrencode"
+AC_MSG_CHECKING(for libqrencode)
+AC_ARG_WITH(qrencode,
+   [  --with-qrencode=PFX    Base of libqrencode installation],
+   [AC_MSG_RESULT([$with_qrencode])
+    AS_CASE([$with_qrencode],
+      [no],[],
+      [yes],[
+        AC_CHECK_HEADERS(qrencode.h,qrencode=1)
+      ],
+      [
+        CPPFLAGS="-I$with_qrencode/include $CPPFLAGS"
+        QR_CFLAGS="-I$with_qrencode/include"
+        QR_LIBS="-L$with_qrencode/lib -lqrencode"
+        AC_CHECK_HEADERS(qrencode.h,qrencode=1)
+      ])
+   ],
+   [AC_MSG_RESULT([--with-qrencode not specified])
+    AC_CHECK_HEADERS(qrencode.h,qrencode=1)])
+
+AS_IF([test "$qrencode" != 1],
+[AC_MSG_ERROR([[
+***
+*** You need libqrencode to build this program.
+*** ]])])
+
+
+AC_SUBST(QR_CFLAGS)
+AC_SUBST(QR_LIBS)
+
+
+
 # check for libgnurl
 # libgnurl
 LIBGNURL_CHECK_CONFIG(,7.34.0,gnurl=1,gnurl=0)
diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am
index 87bd5ef..a95026f 100644
--- a/src/backend/Makefile.am
+++ b/src/backend/Makefile.am
@@ -91,24 +91,6 @@ taler_merchant_httpd_SOURCES = \
     taler-merchant-httpd_post-tips-ID-pickup.h \
   taler-merchant-httpd_reserves.c \
     taler-merchant-httpd_reserves.h
-
-DEAD = \
-  taler-merchant-httpd_check-payment.c taler-merchant-httpd_check-payment.h \
-  taler-merchant-httpd_history.c taler-merchant-httpd_history.h \
-  taler-merchant-httpd_order.c taler-merchant-httpd_order.h \
-  taler-merchant-httpd_pay.c taler-merchant-httpd_pay.h \
-  taler-merchant-httpd_poll-payment.c taler-merchant-httpd_poll-payment.h \
-  taler-merchant-httpd_proposal.c taler-merchant-httpd_proposal.h \
-  taler-merchant-httpd_refund.c taler-merchant-httpd_refund.h \
-  taler-merchant-httpd_refund_increase.c 
taler-merchant-httpd_refund_increase.h \
-  taler-merchant-httpd_refund_lookup.c taler-merchant-httpd_refund_lookup.h \
-  taler-merchant-httpd_tip-authorize.c taler-merchant-httpd_tip-authorize.h \
-  taler-merchant-httpd_tip-pickup.c taler-merchant-httpd_tip-pickup.h \
-  taler-merchant-httpd_tip-pickup_get.c \
-  taler-merchant-httpd_tip-query.c taler-merchant-httpd_tip-query.h \
-  taler-merchant-httpd_tip-reserve-helper.c 
taler-merchant-httpd_tip-reserve-helper.h \
-  taler-merchant-httpd_track-transaction.c 
taler-merchant-httpd_track-transaction.h \
-  taler-merchant-httpd_track-transfer.c taler-merchant-httpd_track-transfer.h
 taler_merchant_httpd_LDADD = \
   $(top_builddir)/src/backenddb/libtalermerchantdb.la \
   -ltalerexchange \
@@ -122,4 +104,7 @@ taler_merchant_httpd_LDADD = \
   -lgnunetcurl \
   -lgnunetjson \
   -lgnunetutil \
+  @QR_LIBS@
   $(XLIB)
+taler_merchant_httpd_CFLAGS = \
+  @QR_CFLAGS@
diff --git a/src/backend/taler-merchant-httpd_get-orders-ID.c 
b/src/backend/taler-merchant-httpd_get-orders-ID.c
index 2158269..7310483 100644
--- a/src/backend/taler-merchant-httpd_get-orders-ID.c
+++ b/src/backend/taler-merchant-httpd_get-orders-ID.c
@@ -21,6 +21,7 @@
  */
 #include "platform.h"
 #include <jansson.h>
+#include <qrencode.h>
 #include <taler/taler_signatures.h>
 #include <taler/taler_json_lib.h>
 #include <taler/taler_exchange_service.h>
@@ -220,6 +221,12 @@ struct GetOrderData
    */
   bool refunded;
 
+  /**
+   * Set to true if the client requested HTML, otherwise
+   * we generate JSON.
+   */
+  bool generate_html;
+
 };
 
 
@@ -234,6 +241,77 @@ static struct GetOrderData *god_head;
 static struct GetOrderData *god_tail;
 
 
+/**
+ * Create the QR code image for a URI.
+ *
+ * @param uri input string to encode
+ * @return NULL on error, encoded URI otherwise
+ */
+static char *
+create_qrcode (const char *uri)
+{
+  QRinput *qri;
+  QRcode *qrc;
+  struct GNUNET_Buffer buf = { 0 };
+
+  qri = QRinput_new2 (0,
+                      QR_ECLEVEL_M);
+  if (NULL == qri)
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+                         "QRinput_new2");
+    return NULL;
+  }
+  /* first try encoding as uppercase-only alpha-numerical
+     QR code (much smaller encoding); if that fails, also
+     try using binary encoding */
+  if ( (0 !=
+        QRinput_append (qri,
+                        QR_MODE_AN,
+                        strlen (uri),
+                        (unsigned char *) uri)) &&
+       (0 !=
+        QRinput_append (qri,
+                        QR_MODE_8,
+                        strlen (uri),
+                        (unsigned char *) uri)) )
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+                         "QRinput_append");
+    QRinput_free (qri);
+    return NULL;
+  }
+  qrc = QRcode_encodeInput (qri);
+  if (NULL == qrc)
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
+                         "QRcode_encodeInput");
+    QRinput_free (qri);
+    return NULL;
+  }
+  QRinput_free (qri);
+  /* FIXME-Dold: generate <img> with inline SVG instead of <pre> here! */
+  GNUNET_buffer_write_str (&buf,
+                           "<pre>\n\n\n\n        ");
+  for (unsigned int y = 0; y<qrc->width; y++)
+  {
+    for (unsigned int x = 0; x<qrc->width; x++)
+    {
+      unsigned int off = x + y * qrc->width;
+      GNUNET_buffer_write_fstr (&buf,
+                                "%s",
+                                (0 != (qrc->data[off] & 1)) ? "██" : "  ");
+    }
+    GNUNET_buffer_write_str (&buf,
+                             "\n        ");
+  }
+  GNUNET_buffer_write_str (&buf,
+                           "\n\n\n\n</pre>");
+  QRcode_free (qrc);
+  return GNUNET_buffer_reap_str (&buf);
+}
+
+
 /**
  * Force resuming all suspended order lookups, needed during shutdown.
  */
@@ -375,13 +453,54 @@ send_pay_request (struct GetOrderData *god,
                                           god->order_id,
                                           god->session_id,
                                           god->hc->instance->settings.id);
-  ret = TALER_MHD_reply_json_pack (god->sc.con,
-                                   MHD_HTTP_OK,
-                                   "{s:s, s:s, s:s?}",
-                                   "taler_pay_uri", taler_pay_uri,
-                                   "order_status", "unpaid",
-                                   "already_paid_order_id",
-                                   already_paid_order_id);
+  if (god->generate_html)
+  {
+    struct MHD_Response *reply;
+    char *qr;
+    char *body;
+
+    qr = create_qrcode (taler_pay_uri);
+    if (NULL == qr)
+    {
+      GNUNET_break (0);
+      return MHD_NO;
+    }
+    GNUNET_asprintf (&body,
+                     "<html><body>%s</body></html>",
+                     qr);
+    GNUNET_free (qr);
+    reply = MHD_create_response_from_buffer (strlen (body),
+                                             body,
+                                             MHD_RESPMEM_MUST_COPY);
+    GNUNET_free (body);
+    if (NULL == reply)
+    {
+      GNUNET_break (0);
+      return MHD_NO;
+    }
+    GNUNET_break (MHD_NO !=
+                  MHD_add_response_header (reply,
+                                           "Taler",
+                                           taler_pay_uri));
+    GNUNET_break (MHD_NO !=
+                  MHD_add_response_header (reply,
+                                           MHD_HTTP_HEADER_CONTENT_TYPE,
+                                           "text/html"));
+    ret = MHD_queue_response (god->sc.con,
+                              MHD_HTTP_OK,
+                              reply);
+    MHD_destroy_response (reply);
+  }
+  else
+  {
+    ret = TALER_MHD_reply_json_pack (god->sc.con,
+                                     MHD_HTTP_OK,
+                                     "{s:s, s:s, s:s?}",
+                                     "taler_pay_uri", taler_pay_uri,
+                                     "order_status", "unpaid",
+                                     "already_paid_order_id",
+                                     already_paid_order_id);
+  }
   GNUNET_free (taler_pay_uri);
   return ret;
 }
@@ -683,6 +802,44 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
       }
     }
 
+    { /* check for 'Accept' header */
+      const char *accept;
+
+      accept = MHD_lookup_connection_value (connection,
+                                            MHD_HEADER_KIND,
+                                            MHD_HTTP_HEADER_ACCEPT);
+      if (NULL != accept)
+      {
+        char *a = GNUNET_strdup (accept);
+        char *saveptr;
+
+        for (char *t = strtok_r (a, ",", &saveptr);
+             NULL != t;
+             t = strtok_r (NULL, ",", &saveptr))
+        {
+          char *end;
+
+          /* skip leading whitespace */
+          while (isspace ((unsigned char) t[0]))
+            t++;
+          /* trim of ';q=' parameter and everything after space */
+          end = strchr (t, ';');
+          if (NULL != end)
+            *end = '\0';
+          end = strchr (t, ' ');
+          if (NULL != end)
+            *end = '\0';
+          if (0 == strcasecmp ("text/html",
+                               t))
+          {
+            god->generate_html = true;
+            break;
+          }
+        }
+        GNUNET_free (a);
+      }
+    } /* end check for 'Accept' header */
+
     {
       const char *long_poll_timeout_s;
 
@@ -1058,18 +1215,60 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh,
                                refund));
     }
 
-    return TALER_MHD_reply_json_pack (
-      connection,
-      MHD_HTTP_OK,
-      "{s:s, s:b, s:o, s:o, s:o}",
-      "order_status", "paid",
-      "refunded", god->refunded,
-      "refund_amount",
-      TALER_JSON_from_amount (&god->refund_amount),
-      "refunds",
-      ra,
-      "merchant_pub",
-      GNUNET_JSON_from_data_auto (&hc->instance->merchant_pub));
+    if (god->generate_html)
+    {
+      int ret;
+      struct MHD_Response *reply;
+      char *body;
+
+#if 0
+      char *qr;
+
+      qr = create_qrcode (taler_refund_uri);
+      if (NULL == qr)
+      {
+        GNUNET_break (0);
+        return MHD_NO;
+      }
+#endif
+      GNUNET_asprintf (&body,
+                       "<html><body>Paid. Refund: %s</body></html>",
+                       TALER_amount2s (&god->refund_amount));
+      // GNUNET_free (qr);
+      reply = MHD_create_response_from_buffer (strlen (body),
+                                               body,
+                                               MHD_RESPMEM_MUST_COPY);
+      GNUNET_free (body);
+      if (NULL == reply)
+      {
+        GNUNET_break (0);
+        return MHD_NO;
+      }
+      GNUNET_break (MHD_NO !=
+                    MHD_add_response_header (reply,
+                                             MHD_HTTP_HEADER_CONTENT_TYPE,
+                                             "text/html"));
+      ret = MHD_queue_response (god->sc.con,
+                                MHD_HTTP_OK,
+                                reply);
+      MHD_destroy_response (reply);
+      return ret;
+    }
+    else
+    {
+      return TALER_MHD_reply_json_pack (
+        connection,
+        MHD_HTTP_OK,
+        "{s:s, s:b, s:o, s:o, s:o}",
+        "order_status", "paid",
+        "refunded", god->refunded,
+        "refund_amount",
+        TALER_JSON_from_amount (&god->refund_amount),
+        "refunds",
+        ra,
+        "merchant_pub",
+        GNUNET_JSON_from_data_auto (&hc->instance->merchant_pub));
+    }
   }
 }
 

-- 
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]