Make getCaptchaImage return (bytes, str).
[tor-bridgedb.git] / bridgedb / qrcodes.py
blob6030a420e2cf3b98888c2837d94156836217d56f
1 # -*- coding: utf-8 ; test-case-name: bridgedb.test.test_qrcodes ; -*-
2 #_____________________________________________________________________________
4 # This file is part of BridgeDB, a Tor bridge distribution system.
6 # :authors: Isis Lovecruft 0xA3ADB67A2CDB8B35 <isis@torproject.org>
7 # please also see AUTHORS file
8 # :copyright: (c) 2007-2017, The Tor Project, Inc.
9 # (c) 2014-2017, Isis Lovecruft
10 # :license: see LICENSE for licensing information
11 #_____________________________________________________________________________
13 """Utilities for working with QRCodes."""
16 import io
17 import logging
19 try:
20 import qrcode
21 except ImportError: # pragma: no cover
22 qrcode = False
23 logging.warn("Could not import Python qrcode module.")
24 logging.debug(("You'll need the qrcode Python module for this to "
25 "work. On Debian-based systems, this should be in the "
26 "python-qrcode package."))
29 def generateQR(bridgelines, imageFormat='JPEG', bridgeSchema=False):
30 """Generate a QRCode for the client's bridge lines.
32 :param str bridgelines: The Bridge Lines which we are distributing to the
33 client.
34 :param bool bridgeSchema: If ``True``, prepend ``'bridge://'`` to the
35 beginning of each bridge line before QR encoding.
36 :rtype: str or ``None``
37 :returns: The generated QRCode, as a string.
38 """
39 logging.debug("Attempting to encode bridge lines into a QRCode...")
41 if not bridgelines:
42 return
44 if not qrcode:
45 logging.info("Not creating QRCode for bridgelines; no qrcode module.")
46 return
48 try:
49 if bridgeSchema:
50 # See https://bugs.torproject.org/12639 for why bridge:// is used.
51 # (Hopefully, Orbot will pick up the ACTION_VIEW intent.)
52 schema = 'bridge://'
53 prefixed = []
54 for line in bridgelines.strip().split('\n'):
55 prefixed.append(schema + line)
56 bridgelines = '\n'.join(prefixed)
58 logging.debug("QR encoding bridge lines: %s" % bridgelines)
60 qr = qrcode.QRCode()
61 qr.add_data(bridgelines)
63 buf = io.BytesIO()
64 img = qr.make_image().resize([350, 350])
65 img.save(buf, imageFormat)
66 buf.seek(0)
68 imgstr = buf.read()
69 return imgstr
71 except KeyError as error:
72 logging.error(str(error))
73 logging.debug(("It seems python-imaging doesn't understand how to "
74 "save in the %s format.") % imageFormat)
75 except Exception as error: # pragma: no cover
76 logging.error(("There was an error while attempting to generate the "
77 "QRCode: %s") % str(error))