qrcode-5.0.1/0000775000175000017500000000000012347745010013241 5ustar chrischris00000000000000qrcode-5.0.1/qrcode/0000775000175000017500000000000012347745010014516 5ustar chrischris00000000000000qrcode-5.0.1/qrcode/__init__.py0000664000175000017500000000075112117523334016630 0ustar chrischris00000000000000from qrcode.main import QRCode, make from qrcode.constants import * from qrcode import image def run_example(data="http://www.lincolnloop.com", *args, **kwargs): """ Build an example QR Code and display it. There's an even easier way than the code here though: just use the ``make`` shortcut. """ qr = QRCode(*args, **kwargs) qr.add_data(data) im = qr.make_image() im.show() if __name__ == '__main__': import sys run_example(*sys.argv[1:]) qrcode-5.0.1/qrcode/util.py0000664000175000017500000003555212347723567016074 0ustar chrischris00000000000000import re import math import six from six.moves import xrange from qrcode import base, exceptions # QR encoding modes. MODE_NUMBER = 1 << 0 MODE_ALPHA_NUM = 1 << 1 MODE_8BIT_BYTE = 1 << 2 MODE_KANJI = 1 << 3 # Encoding mode sizes. MODE_SIZE_SMALL = { MODE_NUMBER: 10, MODE_ALPHA_NUM: 9, MODE_8BIT_BYTE: 8, MODE_KANJI: 8, } MODE_SIZE_MEDIUM = { MODE_NUMBER: 12, MODE_ALPHA_NUM: 11, MODE_8BIT_BYTE: 16, MODE_KANJI: 10, } MODE_SIZE_LARGE = { MODE_NUMBER: 14, MODE_ALPHA_NUM: 13, MODE_8BIT_BYTE: 16, MODE_KANJI: 12, } ALPHA_NUM = six.b('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:') RE_ALPHA_NUM = re.compile(six.b('^[') + re.escape(ALPHA_NUM) + six.b(']*\Z')) # The number of bits for numeric delimited data lengths. NUMBER_LENGTH = {3: 10, 2: 7, 1: 4} PATTERN_POSITION_TABLE = [ [], [6, 18], [6, 22], [6, 26], [6, 30], [6, 34], [6, 22, 38], [6, 24, 42], [6, 26, 46], [6, 28, 50], [6, 30, 54], [6, 32, 58], [6, 34, 62], [6, 26, 46, 66], [6, 26, 48, 70], [6, 26, 50, 74], [6, 30, 54, 78], [6, 30, 56, 82], [6, 30, 58, 86], [6, 34, 62, 90], [6, 28, 50, 72, 94], [6, 26, 50, 74, 98], [6, 30, 54, 78, 102], [6, 28, 54, 80, 106], [6, 32, 58, 84, 110], [6, 30, 58, 86, 114], [6, 34, 62, 90, 118], [6, 26, 50, 74, 98, 122], [6, 30, 54, 78, 102, 126], [6, 26, 52, 78, 104, 130], [6, 30, 56, 82, 108, 134], [6, 34, 60, 86, 112, 138], [6, 30, 58, 86, 114, 142], [6, 34, 62, 90, 118, 146], [6, 30, 54, 78, 102, 126, 150], [6, 24, 50, 76, 102, 128, 154], [6, 28, 54, 80, 106, 132, 158], [6, 32, 58, 84, 110, 136, 162], [6, 26, 54, 82, 110, 138, 166], [6, 30, 58, 86, 114, 142, 170] ] G15 = ((1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0)) G18 = ((1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0)) G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1) PAD0 = 0xEC PAD1 = 0x11 # Precompute bit count limits, indexed by error correction level and code size _data_count = lambda block: block.data_count BIT_LIMIT_TABLE = [ [0] + [8*sum(map(_data_count, base.rs_blocks(version, error_correction))) for version in xrange(1, 41)] for error_correction in xrange(4) ] def BCH_type_info(data): d = data << 10 while BCH_digit(d) - BCH_digit(G15) >= 0: d ^= (G15 << (BCH_digit(d) - BCH_digit(G15))) return ((data << 10) | d) ^ G15_MASK def BCH_type_number(data): d = data << 12 while BCH_digit(d) - BCH_digit(G18) >= 0: d ^= (G18 << (BCH_digit(d) - BCH_digit(G18))) return (data << 12) | d def BCH_digit(data): digit = 0 while data != 0: digit += 1 data >>= 1 return digit def pattern_position(version): return PATTERN_POSITION_TABLE[version - 1] def mask_func(pattern): """ Return the mask function for the given mask pattern. """ if pattern == 0: # 000 return lambda i, j: (i + j) % 2 == 0 if pattern == 1: # 001 return lambda i, j: i % 2 == 0 if pattern == 2: # 010 return lambda i, j: j % 3 == 0 if pattern == 3: # 011 return lambda i, j: (i + j) % 3 == 0 if pattern == 4: # 100 return lambda i, j: (math.floor(i / 2) + math.floor(j / 3)) % 2 == 0 if pattern == 5: # 101 return lambda i, j: (i * j) % 2 + (i * j) % 3 == 0 if pattern == 6: # 110 return lambda i, j: ((i * j) % 2 + (i * j) % 3) % 2 == 0 if pattern == 7: # 111 return lambda i, j: ((i * j) % 3 + (i + j) % 2) % 2 == 0 raise TypeError("Bad mask pattern: " + pattern) def mode_sizes_for_version(version): if version < 10: return MODE_SIZE_SMALL elif version < 27: return MODE_SIZE_MEDIUM else: return MODE_SIZE_LARGE def length_in_bits(mode, version): if mode not in (MODE_NUMBER, MODE_ALPHA_NUM, MODE_8BIT_BYTE, MODE_KANJI): raise TypeError("Invalid mode (%s)" % mode) if version < 1 or version > 40: raise ValueError("Invalid version (was %s, expected 1 to 40)" % version) return mode_sizes_for_version(version)[mode] def lost_point(modules): modules_count = len(modules) lost_point = 0 lost_point = _lost_point_level1(modules, modules_count) lost_point += _lost_point_level2(modules, modules_count) lost_point += _lost_point_level3(modules, modules_count) lost_point += _lost_point_level4(modules, modules_count) return lost_point def _lost_point_level1(modules, modules_count): lost_point = 0 modules_range = xrange(modules_count) row_range_first = (0, 1) row_range_last = (-1, 0) row_range_standard = (-1, 0, 1) col_range_first = ((0, 1), (1,)) col_range_last = ((-1, 0), (-1,)) col_range_standard = ((-1, 0, 1), (-1, 1)) for row in modules_range: if row == 0: row_range = row_range_first elif row == modules_count-1: row_range = row_range_last else: row_range = row_range_standard for col in modules_range: sameCount = 0 dark = modules[row][col] if col == 0: col_range = col_range_first elif col == modules_count-1: col_range = col_range_last else: col_range = col_range_standard for r in row_range: row_offset = row + r if r != 0: col_idx = 0 else: col_idx = 1 for c in col_range[col_idx]: if dark == modules[row_offset][col + c]: sameCount += 1 if sameCount > 5: lost_point += (3 + sameCount - 5) return lost_point def _lost_point_level2(modules, modules_count): lost_point = 0 modules_range = xrange(modules_count - 1) for row in modules_range: this_row = modules[row] next_row = modules[row+1] for col in modules_range: count = 0 if this_row[col]: count += 1 if next_row[col]: count += 1 if this_row[col + 1]: count += 1 if next_row[col + 1]: count += 1 if count == 0 or count == 4: lost_point += 3 return lost_point def _lost_point_level3(modules, modules_count): modules_range_short = xrange(modules_count-6) lost_point = 0 for row in xrange(modules_count): this_row = modules[row] for col in modules_range_short: if (this_row[col] and not this_row[col + 1] and this_row[col + 2] and this_row[col + 3] and this_row[col + 4] and not this_row[col + 5] and this_row[col + 6]): lost_point += 40 for col in xrange(modules_count): for row in modules_range_short: if (modules[row][col] and not modules[row + 1][col] and modules[row + 2][col] and modules[row + 3][col] and modules[row + 4][col] and not modules[row + 5][col] and modules[row + 6][col]): lost_point += 40 return lost_point def _lost_point_level4(modules, modules_count): modules_range = xrange(modules_count) dark_count = 0 for row in modules_range: this_row = modules[row] for col in modules_range: if this_row[col]: dark_count += 1 ratio = abs(100 * dark_count / modules_count / modules_count - 50) / 5 return ratio * 10 def optimal_data_chunks(data, minimum=4): """ An iterator returning QRData chunks optimized to the data content. :param minimum: The minimum number of bytes in a row to split as a chunk. """ data = to_bytestring(data) re_repeat = six.b('{') + six.text_type(minimum).encode('ascii') + six.b(',}') num_pattern = re.compile(six.b('\d') + re_repeat) num_bits = _optimal_split(data, num_pattern) alpha_pattern = re.compile( six.b('[') + re.escape(ALPHA_NUM) + six.b(']') + re_repeat) for is_num, chunk in num_bits: if is_num: yield QRData(chunk, mode=MODE_NUMBER, check_data=False) else: for is_alpha, sub_chunk in _optimal_split(chunk, alpha_pattern): if is_alpha: mode = MODE_ALPHA_NUM else: mode = MODE_8BIT_BYTE yield QRData(sub_chunk, mode=mode, check_data=False) def _optimal_split(data, pattern): while data: match = re.search(pattern, data) if not match: break start, end = match.start(), match.end() if start: yield False, data[:start] yield True, data[start:end] data = data[end:] if data: yield False, data def to_bytestring(data): """ Convert data to a (utf-8 encoded) byte-string if it isn't a byte-string already. """ if not isinstance(data, six.binary_type): data = six.text_type(data).encode('utf-8') return data def optimal_mode(data): """ Calculate the optimal mode for this chunk of data. """ if data.isdigit(): return MODE_NUMBER if RE_ALPHA_NUM.match(data): return MODE_ALPHA_NUM return MODE_8BIT_BYTE class QRData: """ Data held in a QR compatible format. Doesn't currently handle KANJI. """ def __init__(self, data, mode=None, check_data=True): """ If ``mode`` isn't provided, the most compact QR data type possible is chosen. """ if check_data: data = to_bytestring(data) if mode is None: self.mode = optimal_mode(data) else: self.mode = mode if mode not in (MODE_NUMBER, MODE_ALPHA_NUM, MODE_8BIT_BYTE): raise TypeError("Invalid mode (%s)" % mode) if check_data and mode < optimal_mode(data): raise ValueError( "Provided data can not be represented in mode " "{0}".format(mode)) self.data = data def __len__(self): return len(self.data) def write(self, buffer): if self.mode == MODE_NUMBER: for i in xrange(0, len(self.data), 3): chars = self.data[i:i + 3] bit_length = NUMBER_LENGTH[len(chars)] buffer.put(int(chars), bit_length) elif self.mode == MODE_ALPHA_NUM: for i in xrange(0, len(self.data), 2): chars = self.data[i:i + 2] if len(chars) > 1: buffer.put(ALPHA_NUM.find(chars[0]) * 45 + ALPHA_NUM.find(chars[1]), 11) else: buffer.put(ALPHA_NUM.find(chars), 6) else: if six.PY3: # Iterating a bytestring in Python 3 returns an integer, # no need to ord(). data = self.data else: data = [ord(c) for c in self.data] for c in data: buffer.put(c, 8) def __repr__(self): return repr(self.data) class BitBuffer: def __init__(self): self.buffer = [] self.length = 0 def __repr__(self): return ".".join([str(n) for n in self.buffer]) def get(self, index): buf_index = math.floor(index / 8) return ((self.buffer[buf_index] >> (7 - index % 8)) & 1) == 1 def put(self, num, length): for i in range(length): self.put_bit(((num >> (length - i - 1)) & 1) == 1) def __len__(self): return self.length def put_bit(self, bit): buf_index = self.length // 8 if len(self.buffer) <= buf_index: self.buffer.append(0) if bit: self.buffer[buf_index] |= (0x80 >> (self.length % 8)) self.length += 1 def create_bytes(buffer, rs_blocks): offset = 0 maxDcCount = 0 maxEcCount = 0 dcdata = [0] * len(rs_blocks) ecdata = [0] * len(rs_blocks) for r in range(len(rs_blocks)): dcCount = rs_blocks[r].data_count ecCount = rs_blocks[r].total_count - dcCount maxDcCount = max(maxDcCount, dcCount) maxEcCount = max(maxEcCount, ecCount) dcdata[r] = [0] * dcCount for i in range(len(dcdata[r])): dcdata[r][i] = 0xff & buffer.buffer[i + offset] offset += dcCount # Get error correction polynomial. rsPoly = base.Polynomial([1], 0) for i in range(ecCount): rsPoly = rsPoly * base.Polynomial([1, base.gexp(i)], 0) rawPoly = base.Polynomial(dcdata[r], len(rsPoly) - 1) modPoly = rawPoly % rsPoly ecdata[r] = [0] * (len(rsPoly) - 1) for i in range(len(ecdata[r])): modIndex = i + len(modPoly) - len(ecdata[r]) if (modIndex >= 0): ecdata[r][i] = modPoly[modIndex] else: ecdata[r][i] = 0 totalCodeCount = 0 for rs_block in rs_blocks: totalCodeCount += rs_block.total_count data = [None] * totalCodeCount index = 0 for i in range(maxDcCount): for r in range(len(rs_blocks)): if i < len(dcdata[r]): data[index] = dcdata[r][i] index += 1 for i in range(maxEcCount): for r in range(len(rs_blocks)): if i < len(ecdata[r]): data[index] = ecdata[r][i] index += 1 return data def create_data(version, error_correction, data_list): buffer = BitBuffer() for data in data_list: buffer.put(data.mode, 4) buffer.put(len(data), length_in_bits(data.mode, version)) data.write(buffer) # Calculate the maximum number of bits for the given version. rs_blocks = base.rs_blocks(version, error_correction) bit_limit = 0 for block in rs_blocks: bit_limit += block.data_count * 8 if len(buffer) > bit_limit: raise exceptions.DataOverflowError( "Code length overflow. Data size (%s) > size available (%s)" % (len(buffer), bit_limit)) # Terminate the bits (add up to four 0s). for i in range(min(bit_limit - len(buffer), 4)): buffer.put_bit(False) # Delimit the string into 8-bit words, padding with 0s if necessary. delimit = len(buffer) % 8 if delimit: for i in range(8 - delimit): buffer.put_bit(False) # Add special alternating padding bitstrings until buffer is full. bytes_to_fill = (bit_limit - len(buffer)) // 8 for i in range(bytes_to_fill): if i % 2 == 0: buffer.put(PAD0, 8) else: buffer.put(PAD1, 8) return create_bytes(buffer, rs_blocks) qrcode-5.0.1/qrcode/mecard.py0000666000175000017500000000162012336520424016322 0ustar chrischris00000000000000import six # {'code': 'N', 'label': 'Name', 'required': True, 'multipart': [ # 'Last Name', 'First Name']}, PROPERTIES = { 'NICKNAME': {'label': 'Nickname'}, 'BDAY': {'label': 'Birthday', 'date': True}, 'TEL': {'label': 'Phone'}, 'EMAIL': {'label': 'E-mail'}, 'ADR': {'label': 'Address', 'multipart': [ 'PO Box', 'Room Number', 'House Number', 'City', 'Prefecture', 'Zip Code', 'Country']}, 'URL': {'label': 'URL'}, 'MEMO': {'label': 'Note'}, } def build_code(data): notation = [] name = data['N'] if not isinstance(name, six.text_type): name = ','.join(name) notation.append('N', name) for prop in PROPERTIES: value = data.get(prop['code']) if not value: continue if prop['date']: value = value.strftime('%Y%m%d') elif prop['multipart']: value = ','.join(value) qrcode-5.0.1/qrcode/base.py0000664000175000017500000001633612336505167016020 0ustar chrischris00000000000000from qrcode import constants EXP_TABLE = list(range(256)) LOG_TABLE = list(range(256)) for i in range(8): EXP_TABLE[i] = 1 << i for i in range(8, 256): EXP_TABLE[i] = (EXP_TABLE[i - 4] ^ EXP_TABLE[i - 5] ^ EXP_TABLE[i - 6] ^ EXP_TABLE[i - 8]) for i in range(255): LOG_TABLE[EXP_TABLE[i]] = i RS_BLOCK_OFFSET = { constants.ERROR_CORRECT_L: 0, constants.ERROR_CORRECT_M: 1, constants.ERROR_CORRECT_Q: 2, constants.ERROR_CORRECT_H: 3, } RS_BLOCK_TABLE = [ # L # M # Q # H # 1 [1, 26, 19], [1, 26, 16], [1, 26, 13], [1, 26, 9], # 2 [1, 44, 34], [1, 44, 28], [1, 44, 22], [1, 44, 16], # 3 [1, 70, 55], [1, 70, 44], [2, 35, 17], [2, 35, 13], # 4 [1, 100, 80], [2, 50, 32], [2, 50, 24], [4, 25, 9], # 5 [1, 134, 108], [2, 67, 43], [2, 33, 15, 2, 34, 16], [2, 33, 11, 2, 34, 12], # 6 [2, 86, 68], [4, 43, 27], [4, 43, 19], [4, 43, 15], # 7 [2, 98, 78], [4, 49, 31], [2, 32, 14, 4, 33, 15], [4, 39, 13, 1, 40, 14], # 8 [2, 121, 97], [2, 60, 38, 2, 61, 39], [4, 40, 18, 2, 41, 19], [4, 40, 14, 2, 41, 15], # 9 [2, 146, 116], [3, 58, 36, 2, 59, 37], [4, 36, 16, 4, 37, 17], [4, 36, 12, 4, 37, 13], # 10 [2, 86, 68, 2, 87, 69], [4, 69, 43, 1, 70, 44], [6, 43, 19, 2, 44, 20], [6, 43, 15, 2, 44, 16], # 11 [4, 101, 81], [1, 80, 50, 4, 81, 51], [4, 50, 22, 4, 51, 23], [3, 36, 12, 8, 37, 13], # 12 [2, 116, 92, 2, 117, 93], [6, 58, 36, 2, 59, 37], [4, 46, 20, 6, 47, 21], [7, 42, 14, 4, 43, 15], # 13 [4, 133, 107], [8, 59, 37, 1, 60, 38], [8, 44, 20, 4, 45, 21], [12, 33, 11, 4, 34, 12], # 14 [3, 145, 115, 1, 146, 116], [4, 64, 40, 5, 65, 41], [11, 36, 16, 5, 37, 17], [11, 36, 12, 5, 37, 13], # 15 [5, 109, 87, 1, 110, 88], [5, 65, 41, 5, 66, 42], [5, 54, 24, 7, 55, 25], [11, 36, 12], # 16 [5, 122, 98, 1, 123, 99], [7, 73, 45, 3, 74, 46], [15, 43, 19, 2, 44, 20], [3, 45, 15, 13, 46, 16], # 17 [1, 135, 107, 5, 136, 108], [10, 74, 46, 1, 75, 47], [1, 50, 22, 15, 51, 23], [2, 42, 14, 17, 43, 15], # 18 [5, 150, 120, 1, 151, 121], [9, 69, 43, 4, 70, 44], [17, 50, 22, 1, 51, 23], [2, 42, 14, 19, 43, 15], # 19 [3, 141, 113, 4, 142, 114], [3, 70, 44, 11, 71, 45], [17, 47, 21, 4, 48, 22], [9, 39, 13, 16, 40, 14], # 20 [3, 135, 107, 5, 136, 108], [3, 67, 41, 13, 68, 42], [15, 54, 24, 5, 55, 25], [15, 43, 15, 10, 44, 16], # 21 [4, 144, 116, 4, 145, 117], [17, 68, 42], [17, 50, 22, 6, 51, 23], [19, 46, 16, 6, 47, 17], # 22 [2, 139, 111, 7, 140, 112], [17, 74, 46], [7, 54, 24, 16, 55, 25], [34, 37, 13], # 23 [4, 151, 121, 5, 152, 122], [4, 75, 47, 14, 76, 48], [11, 54, 24, 14, 55, 25], [16, 45, 15, 14, 46, 16], # 24 [6, 147, 117, 4, 148, 118], [6, 73, 45, 14, 74, 46], [11, 54, 24, 16, 55, 25], [30, 46, 16, 2, 47, 17], # 25 [8, 132, 106, 4, 133, 107], [8, 75, 47, 13, 76, 48], [7, 54, 24, 22, 55, 25], [22, 45, 15, 13, 46, 16], # 26 [10, 142, 114, 2, 143, 115], [19, 74, 46, 4, 75, 47], [28, 50, 22, 6, 51, 23], [33, 46, 16, 4, 47, 17], # 27 [8, 152, 122, 4, 153, 123], [22, 73, 45, 3, 74, 46], [8, 53, 23, 26, 54, 24], [12, 45, 15, 28, 46, 16], # 28 [3, 147, 117, 10, 148, 118], [3, 73, 45, 23, 74, 46], [4, 54, 24, 31, 55, 25], [11, 45, 15, 31, 46, 16], # 29 [7, 146, 116, 7, 147, 117], [21, 73, 45, 7, 74, 46], [1, 53, 23, 37, 54, 24], [19, 45, 15, 26, 46, 16], # 30 [5, 145, 115, 10, 146, 116], [19, 75, 47, 10, 76, 48], [15, 54, 24, 25, 55, 25], [23, 45, 15, 25, 46, 16], # 31 [13, 145, 115, 3, 146, 116], [2, 74, 46, 29, 75, 47], [42, 54, 24, 1, 55, 25], [23, 45, 15, 28, 46, 16], # 32 [17, 145, 115], [10, 74, 46, 23, 75, 47], [10, 54, 24, 35, 55, 25], [19, 45, 15, 35, 46, 16], # 33 [17, 145, 115, 1, 146, 116], [14, 74, 46, 21, 75, 47], [29, 54, 24, 19, 55, 25], [11, 45, 15, 46, 46, 16], # 34 [13, 145, 115, 6, 146, 116], [14, 74, 46, 23, 75, 47], [44, 54, 24, 7, 55, 25], [59, 46, 16, 1, 47, 17], # 35 [12, 151, 121, 7, 152, 122], [12, 75, 47, 26, 76, 48], [39, 54, 24, 14, 55, 25], [22, 45, 15, 41, 46, 16], # 36 [6, 151, 121, 14, 152, 122], [6, 75, 47, 34, 76, 48], [46, 54, 24, 10, 55, 25], [2, 45, 15, 64, 46, 16], # 37 [17, 152, 122, 4, 153, 123], [29, 74, 46, 14, 75, 47], [49, 54, 24, 10, 55, 25], [24, 45, 15, 46, 46, 16], # 38 [4, 152, 122, 18, 153, 123], [13, 74, 46, 32, 75, 47], [48, 54, 24, 14, 55, 25], [42, 45, 15, 32, 46, 16], # 39 [20, 147, 117, 4, 148, 118], [40, 75, 47, 7, 76, 48], [43, 54, 24, 22, 55, 25], [10, 45, 15, 67, 46, 16], # 40 [19, 148, 118, 6, 149, 119], [18, 75, 47, 31, 76, 48], [34, 54, 24, 34, 55, 25], [20, 45, 15, 61, 46, 16] ] def glog(n): if n < 1: raise ValueError("glog(%s)" % n) return LOG_TABLE[n] def gexp(n): return EXP_TABLE[n % 255] class Polynomial: def __init__(self, num, shift): if not num: raise Exception("%s/%s" % (len(num), shift)) offset = 0 for item in num: if item != 0: break offset += 1 self.num = [0] * (len(num) - offset + shift) for i in range(len(num) - offset): self.num[i] = num[i + offset] def __getitem__(self, index): return self.num[index] def __iter__(self): return iter(self.num) def __len__(self): return len(self.num) def __mul__(self, other): num = [0] * (len(self) + len(other) - 1) for i, item in enumerate(self): for j, other_item in enumerate(other): num[i + j] ^= gexp(glog(item) + glog(other_item)) return Polynomial(num, 0) def __mod__(self, other): difference = len(self) - len(other) if difference < 0: return self ratio = glog(self[0]) - glog(other[0]) num = self[:] num = [ item ^ gexp(glog(other_item) + ratio) for item, other_item in zip(self, other)] if difference: num.extend(self[-difference:]) # recursive call return Polynomial(num, 0) % other class RSBlock: def __init__(self, total_count, data_count): self.total_count = total_count self.data_count = data_count def rs_blocks(version, error_correction): if error_correction not in RS_BLOCK_OFFSET: raise Exception("bad rs block @ version: %s / error_correction: %s" % (version, error_correction)) offset = RS_BLOCK_OFFSET[error_correction] rs_block = RS_BLOCK_TABLE[(version - 1) * 4 + offset] blocks = [] for i in range(0, len(rs_block), 3): count, total_count, data_count = rs_block[i:i + 3] for j in range(count): blocks.append(RSBlock(total_count, data_count)) return blocks qrcode-5.0.1/qrcode/speedy.py0000666000175000001530000000015612247235463016707 0ustar chrisscanner00000000000000import string import qrcode qr = qrcode.QRCode() qr.add_data(string.letters*13) qr.make() print(qr.version) qrcode-5.0.1/qrcode/main.py0000664000175000017500000003076212347723567016041 0ustar chrischris00000000000000from qrcode import constants, exceptions, util from qrcode.image.base import BaseImage import six from bisect import bisect_left def make(data=None, **kwargs): qr = QRCode(**kwargs) qr.add_data(data) return qr.make_image() class QRCode: def __init__(self, version=None, error_correction=constants.ERROR_CORRECT_M, box_size=10, border=4, image_factory=None): self.version = version and int(version) self.error_correction = int(error_correction) self.box_size = int(box_size) # Spec says border should be at least four boxes wide, but allow for # any (e.g. for producing printable QR codes). self.border = int(border) self.image_factory = image_factory if image_factory is not None: assert issubclass(image_factory, BaseImage) self.clear() def clear(self): """ Reset the internal data. """ self.modules = None self.modules_count = 0 self.data_cache = None self.data_list = [] def add_data(self, data, optimize=20): """ Add data to this QR Code. :param optimize: Data will be split into multiple chunks to optimize the QR size by finding to more compressed modes of at least this length. Set to ``0`` to avoid optimizing at all. """ if isinstance(data, util.QRData): self.data_list.append(data) else: if optimize: self.data_list.extend(util.optimal_data_chunks(data)) else: self.data_list.append(util.QRData(data)) self.data_cache = None def make(self, fit=True): """ Compile the data into a QR Code array. :param fit: If ``True`` (or if a size has not been provided), find the best fit for the data to avoid data overflow errors. """ if fit or not self.version: self.best_fit(start=self.version) self.makeImpl(False, self.best_mask_pattern()) def makeImpl(self, test, mask_pattern): self.modules_count = self.version * 4 + 17 self.modules = [None] * self.modules_count for row in range(self.modules_count): self.modules[row] = [None] * self.modules_count for col in range(self.modules_count): self.modules[row][col] = None # (col + row) % 3 self.setup_position_probe_pattern(0, 0) self.setup_position_probe_pattern(self.modules_count - 7, 0) self.setup_position_probe_pattern(0, self.modules_count - 7) self.sutup_position_adjust_pattern() self.setup_timing_pattern() self.setup_type_info(test, mask_pattern) if self.version >= 7: self.setup_type_number(test) if self.data_cache is None: self.data_cache = util.create_data( self.version, self.error_correction, self.data_list) self.map_data(self.data_cache, mask_pattern) def setup_position_probe_pattern(self, row, col): for r in range(-1, 8): if row + r <= -1 or self.modules_count <= row + r: continue for c in range(-1, 8): if col + c <= -1 or self.modules_count <= col + c: continue if (0 <= r and r <= 6 and (c == 0 or c == 6) or (0 <= c and c <= 6 and (r == 0 or r == 6)) or (2 <= r and r <= 4 and 2 <= c and c <= 4)): self.modules[row + r][col + c] = True else: self.modules[row + r][col + c] = False def best_fit(self, start=None): """ Find the minimum size required to fit in the data. """ if start is None: start = 1 elif start < 1 or start > 40: raise ValueError("Invalid version (was %s, expected 1 to 40)" % version) # Corresponds to the code in util.create_data, except we don't yet know # version, so optimistically assume start and check later mode_sizes = util.mode_sizes_for_version(start) buffer = util.BitBuffer() for data in self.data_list: buffer.put(data.mode, 4) buffer.put(len(data), mode_sizes[data.mode]) data.write(buffer) needed_bits = len(buffer) self.version = bisect_left(util.BIT_LIMIT_TABLE[self.error_correction], needed_bits, start) if self.version == 41: raise exceptions.DataOverflowError() # Now check whether we need more bits for the mode sizes, recursing if # our guess was too low if mode_sizes is not util.mode_sizes_for_version(self.version): self.best_fit(start=self.version) return self.version def best_mask_pattern(self): """ Find the most efficient mask pattern. """ min_lost_point = 0 pattern = 0 for i in range(8): self.makeImpl(True, i) lost_point = util.lost_point(self.modules) if i == 0 or min_lost_point > lost_point: min_lost_point = lost_point pattern = i return pattern def print_tty(self, out=None): """ Output the QR Code only using TTY colors. If the data has not been compiled yet, make it first. """ if out is None: import sys out = sys.stdout if not out.isatty(): raise OSError("Not a tty") if self.data_cache is None: self.make() modcount = self.modules_count out.write("\x1b[1;47m" + (" " * (modcount * 2 + 4)) + "\x1b[0m\n") for r in range(modcount): out.write("\x1b[1;47m \x1b[40m") for c in range(modcount): if self.modules[r][c]: out.write(" ") else: out.write("\x1b[1;47m \x1b[40m") out.write("\x1b[1;47m \x1b[0m\n") out.write("\x1b[1;47m" + (" " * (modcount * 2 + 4)) + "\x1b[0m\n") out.flush() def print_ascii(self, out=None, tty=False, invert=False): """ Output the QR Code using ASCII characters. :param tty: use fixed TTY color codes (forces invert=True) :param invert: invert the ASCII characters (solid <-> transparent) """ if out is None: import sys out = sys.stdout if tty and not out.isatty(): raise OSError("Not a tty") if self.data_cache is None: self.make() modcount = self.modules_count codes = [ chr(code).decode('cp437') for code in (255, 223, 220, 219)] if tty: invert = True if invert: codes.reverse() def get_module(x, y): if (invert and self.border and max(x, y) >= modcount+self.border): return 1 if min(x, y) < 0 or max(x, y) >= modcount: return 0 return self.modules[x][y] for r in range(-self.border, modcount+self.border, 2): if tty: if not invert or r < modcount+self.border-1: out.write('\x1b[48;5;232m') # Background black out.write('\x1b[38;5;255m') # Foreground white for c in range(-self.border, modcount+self.border): pos = get_module(r, c) + (get_module(r+1, c) << 1) out.write(codes[pos]) if tty: out.write('\x1b[0m') out.write('\n') out.flush() def make_image(self, image_factory=None, **kwargs): """ Make an image from the QR Code data. If the data has not been compiled yet, make it first. """ if self.data_cache is None: self.make() if image_factory is not None: assert issubclass(image_factory, BaseImage) else: image_factory = self.image_factory if image_factory is None: # Use PIL by default from qrcode.image.pil import PilImage image_factory = PilImage im = image_factory( self.border, self.modules_count, self.box_size, **kwargs) for r in range(self.modules_count): for c in range(self.modules_count): if self.modules[r][c]: im.drawrect(r, c) return im def setup_timing_pattern(self): for r in range(8, self.modules_count - 8): if self.modules[r][6] is not None: continue self.modules[r][6] = (r % 2 == 0) for c in range(8, self.modules_count - 8): if self.modules[6][c] is not None: continue self.modules[6][c] = (c % 2 == 0) def sutup_position_adjust_pattern(self): pos = util.pattern_position(self.version) for i in range(len(pos)): for j in range(len(pos)): row = pos[i] col = pos[j] if self.modules[row][col] is not None: continue for r in range(-2, 3): for c in range(-2, 3): if (r == -2 or r == 2 or c == -2 or c == 2 or (r == 0 and c == 0)): self.modules[row + r][col + c] = True else: self.modules[row + r][col + c] = False def setup_type_number(self, test): bits = util.BCH_type_number(self.version) for i in range(18): mod = (not test and ((bits >> i) & 1) == 1) self.modules[i // 3][i % 3 + self.modules_count - 8 - 3] = mod for i in range(18): mod = (not test and ((bits >> i) & 1) == 1) self.modules[i % 3 + self.modules_count - 8 - 3][i // 3] = mod def setup_type_info(self, test, mask_pattern): data = (self.error_correction << 3) | mask_pattern bits = util.BCH_type_info(data) # vertical for i in range(15): mod = (not test and ((bits >> i) & 1) == 1) if i < 6: self.modules[i][8] = mod elif i < 8: self.modules[i + 1][8] = mod else: self.modules[self.modules_count - 15 + i][8] = mod # horizontal for i in range(15): mod = (not test and ((bits >> i) & 1) == 1) if i < 8: self.modules[8][self.modules_count - i - 1] = mod elif i < 9: self.modules[8][15 - i - 1 + 1] = mod else: self.modules[8][15 - i - 1] = mod # fixed module self.modules[self.modules_count - 8][8] = (not test) def map_data(self, data, mask_pattern): inc = -1 row = self.modules_count - 1 bitIndex = 7 byteIndex = 0 mask_func = util.mask_func(mask_pattern) data_len = len(data) for col in six.moves.xrange(self.modules_count - 1, 0, -2): if col <= 6: col -= 1 col_range = (col, col-1) while True: for c in col_range: if self.modules[row][c] is None: dark = False if byteIndex < data_len: dark = (((data[byteIndex] >> bitIndex) & 1) == 1) if mask_func(row, c): dark = not dark self.modules[row][c] = dark bitIndex -= 1 if bitIndex == -1: byteIndex += 1 bitIndex = 7 row += inc if row < 0 or self.modules_count <= row: row -= inc inc = -inc break def get_matrix(self): """ Return the QR Code as a multidimensonal array, including the border. To return the array without a border, set ``self.border`` to 0 first. """ if self.data_cache is None: self.make() if not self.border: return self.modules width = len(self.modules) + self.border*2 code = [[False]*width] * self.border x_border = [False]*self.border for module in self.modules: code.append(x_border + module + x_border) code += [[False]*width] * self.border return code qrcode-5.0.1/qrcode/tests.py0000644000175000001530000000745212347705523016562 0ustar chrisscanner00000000000000import six import qrcode import qrcode.util import qrcode.image.svg try: import qrcode.image.pure import pymaging_png # ensure that PNG support is installed except ImportError: pymaging_png = None from qrcode.exceptions import DataOverflowError from qrcode.util import ( MODE_NUMBER, MODE_ALPHA_NUM, MODE_8BIT_BYTE) try: import unittest2 as unittest except ImportError: import unittest UNICODE_TEXT = u'\u03b1\u03b2\u03b3' class QRCodeTests(unittest.TestCase): def test_basic(self): qr = qrcode.QRCode(version=1) qr.add_data('a') qr.make(fit=False) def test_overflow(self): qr = qrcode.QRCode(version=1) qr.add_data('abcdefghijklmno') self.assertRaises(DataOverflowError, qr.make, fit=False) def test_fit(self): qr = qrcode.QRCode() qr.add_data('a') qr.make() self.assertEqual(qr.version, 1) qr.add_data('bcdefghijklmno') qr.make() self.assertEqual(qr.version, 2) def test_mode_number(self): qr = qrcode.QRCode() qr.add_data('1234567890123456789012345678901234', optimize=0) qr.make() self.assertEqual(qr.version, 1) self.assertEqual(qr.data_list[0].mode, MODE_NUMBER) def test_mode_alpha(self): qr = qrcode.QRCode() qr.add_data('ABCDEFGHIJ1234567890', optimize=0) qr.make() self.assertEqual(qr.version, 1) self.assertEqual(qr.data_list[0].mode, MODE_ALPHA_NUM) def test_regression_mode_comma(self): qr = qrcode.QRCode() qr.add_data(',', optimize=0) qr.make() self.assertEqual(qr.data_list[0].mode, MODE_8BIT_BYTE) def test_mode_8bit(self): qr = qrcode.QRCode() qr.add_data(u'abcABC' + UNICODE_TEXT, optimize=0) qr.make() self.assertEqual(qr.version, 1) self.assertEqual(qr.data_list[0].mode, MODE_8BIT_BYTE) def test_mode_8bit_newline(self): qr = qrcode.QRCode() qr.add_data('ABCDEFGHIJ1234567890\n', optimize=0) qr.make() self.assertEqual(qr.data_list[0].mode, MODE_8BIT_BYTE) def test_render_svg(self): qr = qrcode.QRCode() qr.add_data(UNICODE_TEXT) img = qr.make_image(image_factory=qrcode.image.svg.SvgImage) img.save(six.BytesIO()) def test_render_svg_path(self): qr = qrcode.QRCode() qr.add_data(UNICODE_TEXT) img = qr.make_image(image_factory=qrcode.image.svg.SvgPathImage) img.save(six.BytesIO()) @unittest.skipIf(not pymaging_png, "Requires pymaging with PNG support") def test_render_pymaging_png(self): qr = qrcode.QRCode() qr.add_data(UNICODE_TEXT) img = qr.make_image(image_factory=qrcode.image.pure.PymagingImage) img.save(six.BytesIO()) def test_optimize(self): qr = qrcode.QRCode() text = 'A1abc12345def1HELLOa' qr.add_data(text, optimize=4) qr.make() self.assertEqual(len(qr.data_list), 5) self.assertEqual(qr.data_list[0].mode, MODE_8BIT_BYTE) self.assertEqual(qr.data_list[1].mode, MODE_NUMBER) self.assertEqual(qr.data_list[2].mode, MODE_8BIT_BYTE) self.assertEqual(qr.data_list[3].mode, MODE_ALPHA_NUM) self.assertEqual(qr.data_list[4].mode, MODE_8BIT_BYTE) self.assertEqual(qr.version, 2) def test_optimize_size(self): text = 'A1abc12345123451234512345def1HELLOHELLOHELLOHELLOa' * 5 qr = qrcode.QRCode() qr.add_data(text) qr.make() self.assertEqual(qr.version, 10) qr = qrcode.QRCode() qr.add_data(text, optimize=0) qr.make() self.assertEqual(qr.version, 11) def test_qrdata_repr(self): data = b'hello' data_obj = qrcode.util.QRData(data) self.assertEqual(repr(data_obj), repr(data)) qrcode-5.0.1/qrcode/image/0000775000175000017500000000000012347745010015600 5ustar chrischris00000000000000qrcode-5.0.1/qrcode/image/__init__.py0000664000175000017500000000000012035627776017713 0ustar chrischris00000000000000qrcode-5.0.1/qrcode/image/base.py0000644000175000001530000000326712212203760017377 0ustar chrisscanner00000000000000class BaseImage(object): """ Base QRCode image output class. """ kind = None allowed_kinds = None def __init__(self, border, width, box_size, *args, **kwargs): self.border = border self.width = width self.box_size = box_size self.pixel_size = (self.width + self.border*2) * self.box_size self._img = self.new_image(**kwargs) def drawrect(self, row, col): """ Draw a single rectangle of the QR code. """ raise NotImplementedError("BaseImage.drawrect") def save(self, stream, kind=None): """ Save the image file. """ raise NotImplementedError("BaseImage.save") def pixel_box(self, row, col): """ A helper method for pixel-based image generators that specifies the four pixel coordinates for a single rect. """ x = (col + self.border) * self.box_size y = (row + self.border) * self.box_size return [(x, y), (x + self.box_size - 1, y + self.box_size - 1)] def new_image(self, **kwargs): """ Build the image class. Subclasses should return the class created. """ return None def check_kind(self, kind, transform=None): """ Get the image type. """ if kind is None: kind = self.kind allowed = not self.allowed_kinds or kind in self.allowed_kinds if transform: kind = transform(kind) if not allowed: allowed = kind in self.allowed_kinds if not allowed: raise ValueError( "Cannot set %s type to %s" % (type(self).__name__, kind)) return kind qrcode-5.0.1/qrcode/image/svg.py0000644000175000001530000001122212212202533017247 0ustar chrisscanner00000000000000from decimal import Decimal # On Python 2.6 must install lxml since the older xml.etree.ElementTree # version can not be used to create SVG images. try: import lxml.etree as ET except ImportError: import xml.etree.ElementTree as ET import qrcode.image.base class SvgFragmentImage(qrcode.image.base.BaseImage): """ SVG image builder Creates a QR-code image as a SVG document fragment. """ _SVG_namespace = "http://www.w3.org/2000/svg" kind = "SVG" allowed_kinds = ("SVG",) def __init__(self, *args, **kwargs): ET.register_namespace("svg", self._SVG_namespace) super(SvgFragmentImage, self).__init__(*args, **kwargs) # Save the unit size, for example the default box_size of 10 is '1mm'. self.unit_size = self.units(self.box_size) def drawrect(self, row, col): self._img.append(self._rect(row, col)) def units(self, pixels, text=True): """ A box_size of 10 (default) equals 1mm. """ units = Decimal(pixels) / 10 if not text: return units return '%smm' % units def save(self, stream, kind=None): self.check_kind(kind=kind) self._write(stream) def new_image(self, **kwargs): return self._svg() def _svg(self, tag=None, version='1.1', **kwargs): if tag is None: tag = ET.QName(self._SVG_namespace, "svg") dimension = self.units(self.pixel_size) return ET.Element( tag, width=dimension, height=dimension, version=version, **kwargs) def _rect(self, row, col, tag=None): if tag is None: tag = ET.QName(self._SVG_namespace, "rect") x, y = self.pixel_box(row, col)[0] return ET.Element( tag, x=self.units(x), y=self.units(y), width=self.unit_size, height=self.unit_size) def _write(self, stream): ET.ElementTree(self._img).write(stream, xml_declaration=False) class SvgImage(SvgFragmentImage): """ Standalone SVG image builder Creates a QR-code image as a standalone SVG document. """ background = None def _svg(self, tag='svg', **kwargs): svg = super(SvgImage, self)._svg(tag=tag, **kwargs) svg.set("xmlns", self._SVG_namespace) if self.background: svg.append( ET.Element( 'rect', fill=self.background, x='0', y='0', width='100%', height='100%')) return svg def _rect(self, row, col): return super(SvgImage, self)._rect(row, col, tag="rect") def _write(self, stream): ET.ElementTree(self._img).write(stream, encoding="UTF-8", xml_declaration=True) class SvgPathImage(SvgImage): """ SVG image builder with one single element (removes white spaces between individual QR points). """ QR_PATH_STYLE = 'fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none' def __init__(self, *args, **kwargs): self._points = set() super(SvgPathImage, self).__init__(*args, **kwargs) def _svg(self, viewBox=None, **kwargs): if viewBox is None: dimension = self.units(self.pixel_size, text=False) viewBox = '0 0 %(d)s %(d)s' % {'d': dimension} return super(SvgPathImage, self)._svg(viewBox=viewBox, **kwargs) def drawrect(self, row, col): # (x, y) self._points.add((col, row)) def _generate_subpaths(self): """Generates individual QR points as subpaths""" rect_size = self.units(self.box_size, text=False) for point in self._points: x_base = self.units( (point[0]+self.border)*self.box_size, text=False) y_base = self.units( (point[1]+self.border)*self.box_size, text=False) yield ( 'M %(x0)s %(y0)s L %(x0)s %(y1)s L %(x1)s %(y1)s L %(x1)s ' '%(y0)s z' % dict( x0=x_base, y0=y_base, x1=x_base+rect_size, y1=y_base+rect_size, )) def make_path(self): subpaths = self._generate_subpaths() return ET.Element( ET.QName("path"), style=self.QR_PATH_STYLE, d=' '.join(subpaths), id="qr-path" ) def _write(self, stream): self._img.append(self.make_path()) super(SvgPathImage, self)._write(stream) class SvgFillImage(SvgImage): """ An SvgImage that fills the background to white. """ background = 'white' class SvgPathFillImage(SvgPathImage): """ An SvgPathImage that fills the background to white. """ background = 'white' qrcode-5.0.1/qrcode/image/pure.py0000644000175000001530000000265412212202533017434 0ustar chrisscanner00000000000000from pymaging import Image from pymaging.colors import RGB from pymaging.formats import registry from pymaging.shapes import Line from pymaging.webcolors import Black, White from pymaging_png.png import PNG import qrcode.image.base class PymagingImage(qrcode.image.base.BaseImage): """ pymaging image builder, default format is PNG. """ kind = "PNG" allowed_kinds = ("PNG",) def __init__(self, *args, **kwargs): """ Register PNG with pymaging. """ registry.formats = [] registry.names = {} registry._populate() registry.register(PNG) super(PymagingImage, self).__init__(*args, **kwargs) def new_image(self, **kwargs): return Image.new(RGB, self.pixel_size, self.pixel_size, White) def drawrect(self, row, col): (x, y), (x2, y2) = self.pixel_box(row, col) for r in range(self.box_size): line_y = y + r line = Line(x, line_y, x2, line_y) self._img.draw(line, Black) def save(self, stream, kind=None): self._img.save(stream, self.check_kind(kind)) def check_kind(self, kind, transform=None, **kwargs): """ pymaging (pymaging_png at least) uses lower case for the type. """ if transform is None: transform = lambda x: x.lower() return super(PymagingImage, self).check_kind( kind, transform=transform, **kwargs) qrcode-5.0.1/qrcode/image/pil.py0000664000175000017500000000157712336505167016755 0ustar chrischris00000000000000# Needed on case-insensitive filesystems from __future__ import absolute_import # Try to import PIL in either of the two ways it can be installed. try: from PIL import Image, ImageDraw except ImportError: import Image import ImageDraw import qrcode.image.base class PilImage(qrcode.image.base.BaseImage): """ PIL image builder, default format is PNG. """ kind = "PNG" def new_image(self, **kwargs): img = Image.new("1", (self.pixel_size, self.pixel_size), "white") self._idr = ImageDraw.Draw(img) return img def drawrect(self, row, col): box = self.pixel_box(row, col) self._idr.rectangle(box, fill="black") def save(self, stream, kind=None): if kind is None: kind = self.kind self._img.save(stream, kind) def __getattr__(self, name): return getattr(self._img, name) qrcode-5.0.1/qrcode/constants.py0000664000175000017500000000015212035627776017116 0ustar chrischris00000000000000# QR error correct levels ERROR_CORRECT_L = 1 ERROR_CORRECT_M = 0 ERROR_CORRECT_Q = 3 ERROR_CORRECT_H = 2 qrcode-5.0.1/qrcode/exceptions.py0000664000175000017500000000005512035627776017265 0ustar chrischris00000000000000class DataOverflowError(Exception): pass qrcode-5.0.1/LICENSE0000664000175000017500000000413712035627776014267 0ustar chrischris00000000000000Copyright (c) 2011, Lincoln Loop All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the package name nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------- Original text and license from the pyqrnative package where this was forked from (http://code.google.com/p/pyqrnative): #Ported from the Javascript library by Sam Curren # #QRCode for Javascript #http://d-project.googlecode.com/svn/trunk/misc/qrcode/js/qrcode.js # #Copyright (c) 2009 Kazuhiko Arase # #URL: http://www.d-project.com/ # #Licensed under the MIT license: # http://www.opensource.org/licenses/mit-license.php # # The word "QR Code" is registered trademark of # DENSO WAVE INCORPORATED # http://www.denso-wave.com/qrcode/faqpatent-e.html qrcode-5.0.1/PKG-INFO0000664000175000017500000001361412347745010014343 0ustar chrischris00000000000000Metadata-Version: 1.1 Name: qrcode Version: 5.0.1 Summary: QR Code image generator Home-page: https://github.com/lincolnloop/python-qrcode Author: Lincoln Loop Author-email: info@lincolnloop.com License: BSD Description: ============================= Pure python QR Code generator ============================= This module uses image libraries, Python Imaging Library (PIL) by default, to generate QR Codes. It is recommended to use the pillow_ fork rather than PIL itself. .. _pillow: https://pypi.python.org/pypi/Pillow What is a QR Code? ================== A Quick Response code is a two-dimensional pictographic code used for its fast readability and comparatively large storage capacity. The code consists of black modules arranged in a square pattern on a white background. The information encoded can be made up of any kind of data (e.g., binary, alphanumeric, or Kanji symbols) Usage ===== From the command line, use the installed ``qr`` script:: qr "Some text" > test.png Or in Python, use the ``make`` shortcut function:: import qrcode img = qrcode.make('Some data here') Advanced Usage -------------- For more control, use the ``QRCode`` class. For example:: import qrcode qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=4, ) qr.add_data('Some data') qr.make(fit=True) img = qr.make_image() The ``version`` parameter is an integer from 1 to 40 that controls the size of the QR Code (the smallest, version 1, is a 21x21 matrix). Set to ``None`` and use the ``fit`` parameter when making the code to determine this automatically. The ``error_correction`` parameter controls the error correction used for the QR Code. The following four constants are made available on the ``qrcode`` package: ``ERROR_CORRECT_L`` About 7% or less errors can be corrected. ``ERROR_CORRECT_M`` (default) About 15% or less errors can be corrected. ``ERROR_CORRECT_Q`` About 25% or less errors can be corrected. ``ERROR_CORRECT_H``. About 30% or less errors can be corrected. The ``box_size`` parameter controls how many pixels each "box" of the QR code is. The ``border`` parameter controls how many boxes thick the border should be (the default is 4, which is the minimum according to the specs). Other image factories ===================== You can encode as SVG, or use a new pure Python image processor to encode to PNG images. The Python examples below use the ``make`` shortcut. The same ``image_factory`` keyword argument is a valid option for the ``QRCode`` class for more advanced usage. SVG --- On Python 2.6 must install lxml since the older xml.etree.ElementTree version can not be used to create SVG images. You can create the entire SVG or an SVG fragment. When building an entire SVG image, you can use the factory that combines as a path (recommended, and default for the script) or a factory that creates a simple set of rectangles. From your command line:: qr --factory=svg-path "Some text" > test.svg qr --factory=svg "Some text" > test.svg qr --factory=svg-fragment "Some text" > test.svg Or in Python:: import qrcode import qrcode.image.svg if method == 'basic': # Simple factory, just a set of rects. factory = qrcode.image.svg.SvgImage elif method == 'fragment': # Fragment factory (also just a set of rects) factory = qrcode.image.svg.SvgFragmentImage else: # Combined path factory, fixes white space that may occur when zooming factory = qrcode.image.svg.SvgPathImage img = qrcode.make('Some data here', image_factory=factory) Two other related factories are available that work the same, but also fill the background of the SVG with white:: qrcode.image.svg.SvgFillImage qrcode.image.svg.SvgPathFillImage Pure Python PNG --------------- Install the following two packages:: pip install git+git://github.com/ojii/pymaging.git#egg=pymaging pip install git+git://github.com/ojii/pymaging-png.git#egg=pymaging-png From your command line:: qr --factory=pymaging "Some text" > test.png Or in Python:: import qrcode from qrcode.image.pure import PymagingImage img = qrcode.make('Some data here', image_factory=PymagingImage) Platform: any Classifier: Development Status :: 5 - Production/Stable Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Intended Audience :: Developers Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2.5 Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3.3 Classifier: Topic :: Multimedia :: Graphics Classifier: Topic :: Software Development :: Libraries :: Python Modules qrcode-5.0.1/MANIFEST.in0000644000175000001530000000003712211221002015266 0ustar chrisscanner00000000000000include LICENSE *.rst doc/qr.1 qrcode-5.0.1/TESTING.rst0000644000175000001530000000116312211221002015400 0ustar chrisscanner00000000000000Testing ======= First, install tox into your virtualenv:: pip install -U tox To run all the qrcode tests, you'll need to install the older Python interpreters. Here's how you'll do it on a modern Ubuntu distribution:: sudo add-apt-repository ppa:fkrull/deadsnakes sudo apt-get update sudo apt-get install python2.4-dev python2.6-dev Ensure you have the libraries to build PIL, too:: sudo apt-get install build-essential python-dev python3-dev sudo apt-get install libjpeg8-dev zlib1g-dev Finally, just run ``tox``! If you want, you can test against a specific version like this: ``tox -e py33`` qrcode-5.0.1/setup.cfg0000664000175000017500000000007312347745010015062 0ustar chrischris00000000000000[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 qrcode-5.0.1/setup.py0000644000175000001530000000220012347744550015270 0ustar chrisscanner00000000000000#!/usr/bin/env python from setuptools import setup, find_packages setup( name='qrcode', version='5.0.1', url='https://github.com/lincolnloop/python-qrcode', #download_url='', description='QR Code image generator', license='BSD', long_description=open('README.rst').read(), author='Lincoln Loop', author_email='info@lincolnloop.com', platforms=['any'], packages=find_packages(), scripts=[ 'scripts/qr', ], install_requires=['six'], data_files=[('share/man/man1', ['doc/qr.1'])], include_package_data=True, classifiers=[ 'Development Status :: 5 - Production/Stable', 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', 'Intended Audience :: Developers', 'Programming Language :: Python', 'Programming Language :: Python :: 2.5', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3.3', 'Topic :: Multimedia :: Graphics', 'Topic :: Software Development :: Libraries :: Python Modules', ], ) qrcode-5.0.1/CHANGES.rst0000644000175000001530000000767412347744674015413 0ustar chrisscanner00000000000000========== Change log ========== Version 5.0 =========== * Speed optimizations. * Change the output when using the ``qr`` script to use ASCII rather than just colors, better using the terminal real estate. * Fix a bug in passing bytecode data directly when in Python 3. * Substation speed optimizations to best-fit algorithm (thanks Jacob Welsh!). Version 5.0.1 ------------- * Update version numbers correctly. Version 4.0 =========== * Made qrcode work on Python 2.4 - Thanks tcely. Note: officially, qrcode only supports 2.5+. * Support pure-python PNG generation (via pymaging) for Python 2.6+ -- thanks Adam Wisniewski! * SVG image generation now supports alternate sizing (the default box size of 10 == 1mm per rectangle). * SVG path image generation allows cleaner SVG output by combining all QR rects into a single path. Thank you, Viktor Stískala. * Added some extra simple SVG factories that fill the background white. Version 4.0.1 ------------- * Fix the pymaging backend not able to save the image to a buffer. Thanks ilj! Version 4.0.2 ------------- * Fix incorrect regex causing a comma to be considered part of the alphanumeric set. * Switch to using setuptools for setup.py. Version 4.0.3 ------------- * Fix bad QR code generation due to the regex comma fix in version 4.0.2. Version 4.0.4 ------------- * Bad version number for previous hotfix release. Version 3.1 =========== * Important fixes for incorrect matches of the alpha-numeric encoding mode. Previously, the pattern would match if a single line was alpha-numeric only (even if others wern't). Also, the two characters ``{`` and ``}`` had snuck in as valid characters. Thanks to Eran Tromer for the report and fix. * Optimized chunking -- if the parts of the data stream can be encoded more efficiently, the data will be split into chunks of the most efficient modes. Version 3.1.1 ------------- * Update change log to contain version 3.1 changes. :P * Give the ``qr`` script an ``--optimize`` argument to control the chunk optimization setting. Version 3.0 =========== * Python 3 support. * Add QRCode.get_matrix, an easy way to get the matrix array of a QR code including the border. Thanks Hugh Rawlinson. * Add in a workaround so that Python 2.6 users can use SVG generation (they must install ``lxml``). * Some initial tests! And tox support (``pip install tox``) for testing across Python platforms. Version 2.7 =========== * Fix incorrect termination padding. Version 2.6 =========== * Fix the first four columns incorrectly shifted by one. Thanks to Josep Gómez-Suay for the report and fix. * Fix strings within 4 bits of the QR version limit being incorrectly terminated. Thanks to zhjie231 for the report. Version 2.5 =========== * The PilImage wrapper is more transparent - you can use any methods or attributes available to the underlying PIL Image instance. * Fixed the first column of the QR Code coming up empty! Thanks to BecoKo. Version 2.5.1 ------------- * Fix installation error on Windows. Version 2.4 =========== * Use a pluggable backend system for generating images, thanks to Branko Čibej! Comes with PIL and SVG backends built in. Version 2.4.1 ------------- * Fix a packaging issue Version 2.4.2 ------------- * Added a ``show`` method to the PIL image wrapper so the ``run_example`` function actually works. Version 2.3 =========== * When adding data, auto-select the more efficient encoding methods for numbers and alphanumeric data (KANJI still not supported). Version 2.3.1 ------------- * Encode unicode to utf-8 bytestrings when adding data to a QRCode. Version 2.2 =========== * Fixed tty output to work on both white and black backgrounds. * Added `border` parameter to allow customizing of the number of boxes used to create the border of the QR code Version 2.1 =========== * Added a ``qr`` script which can be used to output a qr code to the tty using background colors, or to a file via a pipe. qrcode-5.0.1/qrcode.egg-info/0000775000175000017500000000000012347745010016210 5ustar chrischris00000000000000qrcode-5.0.1/qrcode.egg-info/PKG-INFO0000664000175000017500000001361412347745010017312 0ustar chrischris00000000000000Metadata-Version: 1.1 Name: qrcode Version: 5.0.1 Summary: QR Code image generator Home-page: https://github.com/lincolnloop/python-qrcode Author: Lincoln Loop Author-email: info@lincolnloop.com License: BSD Description: ============================= Pure python QR Code generator ============================= This module uses image libraries, Python Imaging Library (PIL) by default, to generate QR Codes. It is recommended to use the pillow_ fork rather than PIL itself. .. _pillow: https://pypi.python.org/pypi/Pillow What is a QR Code? ================== A Quick Response code is a two-dimensional pictographic code used for its fast readability and comparatively large storage capacity. The code consists of black modules arranged in a square pattern on a white background. The information encoded can be made up of any kind of data (e.g., binary, alphanumeric, or Kanji symbols) Usage ===== From the command line, use the installed ``qr`` script:: qr "Some text" > test.png Or in Python, use the ``make`` shortcut function:: import qrcode img = qrcode.make('Some data here') Advanced Usage -------------- For more control, use the ``QRCode`` class. For example:: import qrcode qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=4, ) qr.add_data('Some data') qr.make(fit=True) img = qr.make_image() The ``version`` parameter is an integer from 1 to 40 that controls the size of the QR Code (the smallest, version 1, is a 21x21 matrix). Set to ``None`` and use the ``fit`` parameter when making the code to determine this automatically. The ``error_correction`` parameter controls the error correction used for the QR Code. The following four constants are made available on the ``qrcode`` package: ``ERROR_CORRECT_L`` About 7% or less errors can be corrected. ``ERROR_CORRECT_M`` (default) About 15% or less errors can be corrected. ``ERROR_CORRECT_Q`` About 25% or less errors can be corrected. ``ERROR_CORRECT_H``. About 30% or less errors can be corrected. The ``box_size`` parameter controls how many pixels each "box" of the QR code is. The ``border`` parameter controls how many boxes thick the border should be (the default is 4, which is the minimum according to the specs). Other image factories ===================== You can encode as SVG, or use a new pure Python image processor to encode to PNG images. The Python examples below use the ``make`` shortcut. The same ``image_factory`` keyword argument is a valid option for the ``QRCode`` class for more advanced usage. SVG --- On Python 2.6 must install lxml since the older xml.etree.ElementTree version can not be used to create SVG images. You can create the entire SVG or an SVG fragment. When building an entire SVG image, you can use the factory that combines as a path (recommended, and default for the script) or a factory that creates a simple set of rectangles. From your command line:: qr --factory=svg-path "Some text" > test.svg qr --factory=svg "Some text" > test.svg qr --factory=svg-fragment "Some text" > test.svg Or in Python:: import qrcode import qrcode.image.svg if method == 'basic': # Simple factory, just a set of rects. factory = qrcode.image.svg.SvgImage elif method == 'fragment': # Fragment factory (also just a set of rects) factory = qrcode.image.svg.SvgFragmentImage else: # Combined path factory, fixes white space that may occur when zooming factory = qrcode.image.svg.SvgPathImage img = qrcode.make('Some data here', image_factory=factory) Two other related factories are available that work the same, but also fill the background of the SVG with white:: qrcode.image.svg.SvgFillImage qrcode.image.svg.SvgPathFillImage Pure Python PNG --------------- Install the following two packages:: pip install git+git://github.com/ojii/pymaging.git#egg=pymaging pip install git+git://github.com/ojii/pymaging-png.git#egg=pymaging-png From your command line:: qr --factory=pymaging "Some text" > test.png Or in Python:: import qrcode from qrcode.image.pure import PymagingImage img = qrcode.make('Some data here', image_factory=PymagingImage) Platform: any Classifier: Development Status :: 5 - Production/Stable Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Intended Audience :: Developers Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2.5 Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3.3 Classifier: Topic :: Multimedia :: Graphics Classifier: Topic :: Software Development :: Libraries :: Python Modules qrcode-5.0.1/qrcode.egg-info/SOURCES.txt0000664000175000017500000000075612347745010020104 0ustar chrischris00000000000000CHANGES.rst LICENSE MANIFEST.in README.rst TESTING.rst setup.py doc/qr.1 qrcode/__init__.py qrcode/base.py qrcode/constants.py qrcode/exceptions.py qrcode/main.py qrcode/mecard.py qrcode/speedy.py qrcode/tests.py qrcode/util.py qrcode.egg-info/PKG-INFO qrcode.egg-info/SOURCES.txt qrcode.egg-info/dependency_links.txt qrcode.egg-info/requires.txt qrcode.egg-info/top_level.txt qrcode/image/__init__.py qrcode/image/base.py qrcode/image/pil.py qrcode/image/pure.py qrcode/image/svg.py scripts/qrqrcode-5.0.1/qrcode.egg-info/requires.txt0000644000175000001530000000000312347745010021114 0ustar chrisscanner00000000000000sixqrcode-5.0.1/qrcode.egg-info/top_level.txt0000664000175000017500000000000712347745010020737 0ustar chrischris00000000000000qrcode qrcode-5.0.1/qrcode.egg-info/dependency_links.txt0000664000175000017500000000000112347745010022256 0ustar chrischris00000000000000 qrcode-5.0.1/doc/0000775000175000017500000000000012347745010014006 5ustar chrischris00000000000000qrcode-5.0.1/doc/qr.10000644000175000001530000000217112347744232015033 0ustar chrisscanner00000000000000.\" Manpage for qr .TH QR 1 "25 Jun 2013" "5.0" "Python QR tool" .SH NAME qr \- script to create QR codes at the command line .SH SYNOPSIS qr [\-\-help] [\-\-factory=FACTORY] [\-\-optimize=OPTIMIZE] [data] .SH DESCRIPTION This script uses the python qrcode module. It can take data from stdin or from the commandline and generate a QR code. Normally it will output the QR code as ascii art to the terminal. If the output is piped to a file, it will output the image (default type of PNG). .SH OPTIONS .PP \fB\ \-h, \-\-help\fR .RS 4 Show a help message. .RE .PP \fB\ \-\-factory=FACTORY\fR .RS 4 Full python path to the image factory class to create the image with. You can use the following shortcuts to the built-in image factory classes: pil (default), pymaging, svg, svg-fragment, svg-path. .RE .PP \fB\ \-\-optimize=OPTIMIZE\fR .RS 4 Optimize the data by looking for chunks of at least this many characters that could use a more efficient encoding method. Use 0 to turn off chunk optimization. .RE .PP \fB\ data\fR .RS 4 The data from which the QR code will be generated. .RE .SH SEE ALSO https://github.com/lincolnloop/python-qrcode/ qrcode-5.0.1/scripts/0000775000175000017500000000000012347745010014730 5ustar chrischris00000000000000qrcode-5.0.1/scripts/qr0000775000175000017500000000374612336505167015317 0ustar chrischris00000000000000#!/usr/bin/env python """ qr - Convert stdin (or the first argument) to a QR Code. When stdout is a tty the QR Code is printed to the terminal and when stdout is a pipe to a file an image is written. The default image format is PNG. """ import sys import optparse import qrcode default_factories = { 'pil': 'qrcode.image.pil.PilImage', 'pymaging': 'qrcode.image.pure.PymagingImage', 'svg': 'qrcode.image.svg.SvgImage', 'svg-fragment': 'qrcode.image.svg.SvgFragmentImage', 'svg-path': 'qrcode.image.svg.SvgPathImage', } def main(*args): qr = qrcode.QRCode() parser = optparse.OptionParser(usage=__doc__.strip()) parser.add_option( "--factory", help="Full python path to the image factory class to " "create the image with. You can use the following shortcuts to the " "built-in image factory classes: {0}.".format( ", ".join(sorted(default_factories.keys())))) parser.add_option( "--optimize", type=int, help="Optimize the data by looking for chunks " "of at least this many characters that could use a more efficient " "encoding method. Use 0 to turn off chunk optimization.") opts, args = parser.parse_args(list(args)) if opts.factory: module = default_factories.get(opts.factory, opts.factory) if '.' not in module: parser.error("The image factory is not a full python path") module, name = module.rsplit('.', 1) imp = __import__(module, {}, [], [name]) image_factory = getattr(imp, name) else: image_factory = None if args: data = args[0] else: data = sys.stdin.read() if opts.optimize is None: qr.add_data(data) else: qr.add_data(data, optimize=opts.optimize) if image_factory is None and sys.stdout.isatty(): qr.print_ascii(tty=True) return img = qr.make_image(image_factory=image_factory) img.save(sys.stdout) if __name__ == "__main__": main(*sys.argv[1:]) qrcode-5.0.1/README.rst0000644000175000001530000001001212234024457015235 0ustar chrisscanner00000000000000============================= Pure python QR Code generator ============================= This module uses image libraries, Python Imaging Library (PIL) by default, to generate QR Codes. It is recommended to use the pillow_ fork rather than PIL itself. .. _pillow: https://pypi.python.org/pypi/Pillow What is a QR Code? ================== A Quick Response code is a two-dimensional pictographic code used for its fast readability and comparatively large storage capacity. The code consists of black modules arranged in a square pattern on a white background. The information encoded can be made up of any kind of data (e.g., binary, alphanumeric, or Kanji symbols) Usage ===== From the command line, use the installed ``qr`` script:: qr "Some text" > test.png Or in Python, use the ``make`` shortcut function:: import qrcode img = qrcode.make('Some data here') Advanced Usage -------------- For more control, use the ``QRCode`` class. For example:: import qrcode qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=4, ) qr.add_data('Some data') qr.make(fit=True) img = qr.make_image() The ``version`` parameter is an integer from 1 to 40 that controls the size of the QR Code (the smallest, version 1, is a 21x21 matrix). Set to ``None`` and use the ``fit`` parameter when making the code to determine this automatically. The ``error_correction`` parameter controls the error correction used for the QR Code. The following four constants are made available on the ``qrcode`` package: ``ERROR_CORRECT_L`` About 7% or less errors can be corrected. ``ERROR_CORRECT_M`` (default) About 15% or less errors can be corrected. ``ERROR_CORRECT_Q`` About 25% or less errors can be corrected. ``ERROR_CORRECT_H``. About 30% or less errors can be corrected. The ``box_size`` parameter controls how many pixels each "box" of the QR code is. The ``border`` parameter controls how many boxes thick the border should be (the default is 4, which is the minimum according to the specs). Other image factories ===================== You can encode as SVG, or use a new pure Python image processor to encode to PNG images. The Python examples below use the ``make`` shortcut. The same ``image_factory`` keyword argument is a valid option for the ``QRCode`` class for more advanced usage. SVG --- On Python 2.6 must install lxml since the older xml.etree.ElementTree version can not be used to create SVG images. You can create the entire SVG or an SVG fragment. When building an entire SVG image, you can use the factory that combines as a path (recommended, and default for the script) or a factory that creates a simple set of rectangles. From your command line:: qr --factory=svg-path "Some text" > test.svg qr --factory=svg "Some text" > test.svg qr --factory=svg-fragment "Some text" > test.svg Or in Python:: import qrcode import qrcode.image.svg if method == 'basic': # Simple factory, just a set of rects. factory = qrcode.image.svg.SvgImage elif method == 'fragment': # Fragment factory (also just a set of rects) factory = qrcode.image.svg.SvgFragmentImage else: # Combined path factory, fixes white space that may occur when zooming factory = qrcode.image.svg.SvgPathImage img = qrcode.make('Some data here', image_factory=factory) Two other related factories are available that work the same, but also fill the background of the SVG with white:: qrcode.image.svg.SvgFillImage qrcode.image.svg.SvgPathFillImage Pure Python PNG --------------- Install the following two packages:: pip install git+git://github.com/ojii/pymaging.git#egg=pymaging pip install git+git://github.com/ojii/pymaging-png.git#egg=pymaging-png From your command line:: qr --factory=pymaging "Some text" > test.png Or in Python:: import qrcode from qrcode.image.pure import PymagingImage img = qrcode.make('Some data here', image_factory=PymagingImage)