[tor-commits] [bridgedb/develop] Add support for generating QRCodes for bridge lines on bridges.html.

isis at torproject.org isis at torproject.org
Mon Feb 2 19:53:00 UTC 2015


commit 9692235f7f08724be7bfd542553f563c8bab517d
Author: Isis Lovecruft <isis at torproject.org>
Date:   Thu Jan 15 21:58:55 2015 +0000

    Add support for generating QRCodes for bridge lines on bridges.html.
    
     * FIXES #11345 https://bugs.torproject.org/11345
---
 lib/bridgedb/HTTPServer.py          |    9 ++++-
 lib/bridgedb/qrcodes.py             |   59 ++++++++++++++++++++++++++++++++
 lib/bridgedb/templates/bridges.html |   64 ++++++++++++++++++++++++++++++++++-
 3 files changed, 130 insertions(+), 2 deletions(-)

diff --git a/lib/bridgedb/HTTPServer.py b/lib/bridgedb/HTTPServer.py
index 6aebba1..b073542 100644
--- a/lib/bridgedb/HTTPServer.py
+++ b/lib/bridgedb/HTTPServer.py
@@ -49,6 +49,7 @@ from bridgedb.Filters import filterBridgesByIP6
 from bridgedb.Filters import filterBridgesByTransport
 from bridgedb.Filters import filterBridgesByNotBlockedIn
 from bridgedb.parse import headers
+from bridgedb.qrcodes import generateQR
 from bridgedb.safelog import logSafely
 
 
@@ -785,6 +786,11 @@ class WebResourceBridges(resource.Resource):
             rendered = bridgeLines
         else:
             request.setHeader("Content-Type", "text/html; charset=utf-8")
+            qrcode = None
+            qrjpeg = generateQR(bridgeLines)
+
+            if qrjpeg:
+                qrcode = 'data:image/jpeg;base64,%s' % base64.b64encode(qrjpeg)
             try:
                 langs = translations.getLocaleFromHTTPRequest(request)
                 rtl = translations.usingRTLLang(langs)
@@ -792,7 +798,8 @@ class WebResourceBridges(resource.Resource):
                 rendered = template.render(strings,
                                            rtl=rtl,
                                            lang=langs[0],
-                                           answer=bridgeLines)
+                                           answer=bridgeLines,
+                                           qrcode=qrcode)
             except Exception as err:
                 rendered = replaceErrorPage(err)
 
diff --git a/lib/bridgedb/qrcodes.py b/lib/bridgedb/qrcodes.py
new file mode 100644
index 0000000..ae25f06
--- /dev/null
+++ b/lib/bridgedb/qrcodes.py
@@ -0,0 +1,59 @@
+# -*- coding: utf-8 ; test-case-name: bridgedb.test.test_qrcodes ; -*-
+#_____________________________________________________________________________
+#
+# This file is part of BridgeDB, a Tor bridge distribution system.
+#
+# :authors: Isis Lovecruft 0xA3ADB67A2CDB8B35 <isis at torproject.org>
+#           please also see AUTHORS file
+# :copyright: (c) 2007-2015, The Tor Project, Inc.
+#             (c) 2014-2015, Isis Lovecruft
+# :license: see LICENSE for licensing information
+#_____________________________________________________________________________
+
+"""Utilities for working with QRCodes."""
+
+
+import cStringIO
+import logging
+
+
+def generateQR(bridgelines, imageFormat=u'JPEG'):
+    """Generate a QRCode for the client's bridge lines.
+
+    :param str bridgelines: The Bridge Lines which we are distributing to the
+        client.
+    :rtype: str or ``None``
+
+    :returns: The generated QRCode, as a string.
+    """
+    logging.debug("Attempting to encode bridge lines into a QRCode...")
+
+    if not bridgelines:
+        return
+
+    try:
+        import qrcode
+
+        qr = qrcode.QRCode()
+        qr.add_data(bridgelines)
+        buf = cStringIO.StringIO()
+        img = qr.make_image().resize([350, 350])
+        img.save(buf, imageFormat)
+        buf.seek(0)
+        imgstr = buf.read()
+        logging.debug("Got QRCode image string.")
+        
+        return imgstr
+
+    except ImportError as error:
+        logging.error(str(error))
+        logging.debug(("You'll need the qrcode Python module for this to "
+                       "work. On Debian-based systems, this should be in the "
+                       "python-qrcode package."))
+    except KeyError as error:
+        logging.error(str(error))
+        logging.debug(("It seems python-imaging doesn't understand how to "
+                       "save in the %s format.") % imgFormat)
+    except Exception as error:
+        logging.error(("There was an error while attempting to generate the "
+                       "QRCode: %s") % str(error))
diff --git a/lib/bridgedb/templates/bridges.html b/lib/bridgedb/templates/bridges.html
index d3c10c1..8048919 100644
--- a/lib/bridgedb/templates/bridges.html
+++ b/lib/bridgedb/templates/bridges.html
@@ -1,7 +1,7 @@
 ## -*- coding: utf-8 -*-
 
 <%inherit file="base.html"/>
-<%page args="strings, rtl=False, lang='en', answer=0, **kwargs"/>
+<%page args="strings, rtl=False, lang='en', answer=0, qrcode=0, **kwargs"/>
 
   </div>
 </div>
@@ -31,6 +31,20 @@
       window.alert(e);
     }
   }
+
+  function displayOrHide(element) {
+    try {
+      e = document.getElementById(element);
+
+      if (e.style.display === 'none') {
+        document.getElementById(element).style.display = 'block';
+      } else if (e.style.display === 'block') {
+        document.getElementById(element).style.display = 'none';
+      }
+    } catch (e) {
+      window.alert(e);
+    }
+  }
 </script>
 
 <div class="container-narrow">
@@ -66,6 +80,50 @@ ${answer.replace("\n", "<br />")}
                 title="Select all bridge lines">
           <i class="icon icon-2x icon-paste"></i>   ${_("""Select All""")}
         </button>
+% if qrcode:
+        <a class="btn btn-primary" type="button" id="qrcodebtn"
+           href="${qrcode}" title="Show QRCode for bridge lines"
+           onclick="displayOrHide('qrcode')">
+          <i class="icon icon-2x icon-qrcode"></i>   ${_("""Show QRCode""")}
+        </a>
+% endif
+      </div>
+
+      <div class="modal" id="qrcode" style="display: none;">
+        <div class="modal-dialog modal-sm" style="width: 400px;">
+          <div class="modal-content">
+            <div class="modal-header">
+              <button type="button" class="close" aria-hidden="true"
+                      onclick="displayOrHide('qrcode')">
+                ×
+              </button>
+              <h4 class="modal-title">${_("""QRCode for your bridge lines""")}</h4>
+            </div>
+            <div class="modal-body">
+% if qrcode:
+              <p style="text-align: center;">
+                <img width="350" height="350"
+                     title="QRCode for your bridge lines from BridgeDB"
+                     src="${qrcode}" />
+              </p>
+% else:
+              <p class="text-danger">
+## TRANSLATORS: Please translate this into some silly way to say
+##              "There was a problem!" in your language. For example,
+##              for Italian, you might translate this into "Mama mia!",
+##              or for French: "Sacrebleu!". :)
+${_("""Uh oh, spaghettios!""")}
+${_("""It seems there was an error getting your QRCode.""")}
+                <i class="icon icon-frown"></i>
+              </p>
+% endif
+              <p>
+${_("""This QRCode contains your bridge lines. Scan it with a QRCode """ \
+    """reader to copy your bridge lines onto mobile and other devices.""")}
+              </p>
+            </div>
+          </div>
+        </div>
       </div>
     </div>
 
@@ -133,6 +191,10 @@ ${_("""Uh oh, spaghettios!""")}
 <script type="text/javascript">
   // Make the 'Select All' button clickable:
   document.getElementById('selectbtn').className = "btn btn-primary";
+
+  // Remove the href attribute which opens the QRCode image as a data URL if
+  // JS is disabled:
+  document.getElementById('qrcodebtn').removeAttribute('href');
 </script>
 
 <hr />





More information about the tor-commits mailing list