Unverified Commit 9692235f authored by Isis Lovecruft's avatar Isis Lovecruft
Browse files

Add support for generating QRCodes for bridge lines on bridges.html.

parent c542e055
Loading
Loading
Loading
Loading
+8 −1
Changes for lib/bridgedb/HTTPServer.py: 8 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -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)

+59 −0
Changes for lib/bridgedb/qrcodes.py: 59 added lines, 0 removed lines.
Original line number Diff line number Diff line
# -*- 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@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))
+63 −1
Changes for lib/bridgedb/templates/bridges.html: 63 added lines, 1 removed line.
Original line number Diff line number Diff line
## -*- 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> &nbsp; ${_("""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> &nbsp; ${_("""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')">
                &times;
              </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 />