console_scripts.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #!/usr/bin/env python
  2. """
  3. qr - Convert stdin (or the first argument) to a QR Code.
  4. When stdout is a tty the QR Code is printed to the terminal and when stdout is
  5. a pipe to a file an image is written. The default image format is PNG.
  6. """
  7. import sys
  8. import optparse
  9. import os
  10. import qrcode
  11. # The next block is added to get the terminal to display properly on MS platforms
  12. if sys.platform.startswith(('win', 'cygwin')):
  13. import colorama
  14. colorama.init()
  15. default_factories = {
  16. 'pil': 'qrcode.image.pil.PilImage',
  17. 'pymaging': 'qrcode.image.pure.PymagingImage',
  18. 'svg': 'qrcode.image.svg.SvgImage',
  19. 'svg-fragment': 'qrcode.image.svg.SvgFragmentImage',
  20. 'svg-path': 'qrcode.image.svg.SvgPathImage',
  21. }
  22. error_correction = {
  23. 'L': qrcode.ERROR_CORRECT_L,
  24. 'M': qrcode.ERROR_CORRECT_M,
  25. 'Q': qrcode.ERROR_CORRECT_Q,
  26. 'H': qrcode.ERROR_CORRECT_H,
  27. }
  28. def main(args=None):
  29. if args is None:
  30. args = sys.argv[1:]
  31. from pkg_resources import get_distribution
  32. version = get_distribution('qrcode').version
  33. parser = optparse.OptionParser(usage=__doc__.strip(), version=version)
  34. parser.add_option(
  35. "--factory", help="Full python path to the image factory class to "
  36. "create the image with. You can use the following shortcuts to the "
  37. "built-in image factory classes: {0}.".format(
  38. ", ".join(sorted(default_factories.keys()))))
  39. parser.add_option(
  40. "--optimize", type=int, help="Optimize the data by looking for chunks "
  41. "of at least this many characters that could use a more efficient "
  42. "encoding method. Use 0 to turn off chunk optimization.")
  43. parser.add_option(
  44. "--error-correction", type='choice',
  45. choices=sorted(error_correction.keys()), default='M',
  46. help="The error correction level to use. Choices are L (7%), "
  47. "M (15%, default), Q (25%), and H (30%).")
  48. opts, args = parser.parse_args(args)
  49. qr = qrcode.QRCode(
  50. error_correction=error_correction[opts.error_correction])
  51. if opts.factory:
  52. module = default_factories.get(opts.factory, opts.factory)
  53. if '.' not in module:
  54. parser.error("The image factory is not a full python path")
  55. module, name = module.rsplit('.', 1)
  56. imp = __import__(module, {}, [], [name])
  57. image_factory = getattr(imp, name)
  58. else:
  59. image_factory = None
  60. if args:
  61. data = args[0]
  62. else:
  63. # Use sys.stdin.buffer if available (Python 3) avoiding
  64. # UnicodeDecodeErrors.
  65. stdin_buffer = getattr(sys.stdin, 'buffer', sys.stdin)
  66. data = stdin_buffer.read()
  67. if opts.optimize is None:
  68. qr.add_data(data)
  69. else:
  70. qr.add_data(data, optimize=opts.optimize)
  71. if image_factory is None and os.isatty(sys.stdout.fileno()):
  72. qr.print_ascii(tty=True)
  73. return
  74. img = qr.make_image(image_factory=image_factory)
  75. sys.stdout.flush()
  76. # Use sys.stdout.buffer if available (Python 3), avoiding
  77. # UnicodeDecodeErrors.
  78. stdout_buffer = getattr(sys.stdout, 'buffer', None)
  79. if not stdout_buffer:
  80. if sys.platform == 'win32': # pragma: no cover
  81. import msvcrt
  82. msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
  83. stdout_buffer = sys.stdout
  84. img.save(stdout_buffer)
  85. if __name__ == "__main__":
  86. main()