115 lines
2.8 KiB
Python
115 lines
2.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
from __future__ import unicode_literals
|
|
|
|
from barcode.base import Barcode
|
|
from barcode.charsets import upc as _upc
|
|
from barcode.errors import *
|
|
|
|
try:
|
|
reduce
|
|
except NameError:
|
|
from functools import reduce
|
|
|
|
"""Module: barcode.upc
|
|
|
|
:Provided barcodes: UPC-A
|
|
"""
|
|
__docformat__ = 'restructuredtext en'
|
|
|
|
|
|
class UniversalProductCodeA(Barcode):
|
|
"""Initializes new UPC-A barcode.
|
|
|
|
:parameters:
|
|
upc : String
|
|
The upc number as string.
|
|
writer : barcode.writer Instance
|
|
The writer to render the barcode (default: SVGWriter).
|
|
make_ean: boolean
|
|
"""
|
|
|
|
name = 'UPC-A'
|
|
|
|
digits = 11
|
|
|
|
def __init__(self, upc, writer=None, make_ean=False):
|
|
self.ean = make_ean
|
|
upc = upc[:self.digits]
|
|
if not upc.isdigit():
|
|
raise IllegalCharacterError('UPC code can only contain numbers.')
|
|
if len(upc) != self.digits:
|
|
raise NumberOfDigitsError('UPC must have {0} digits, not '
|
|
'{1}.'.format(self.digits, len(upc)))
|
|
self.upc = upc
|
|
self.upc = '{}{}'.format(upc, self.calculate_checksum())
|
|
self.writer = writer or Barcode.default_writer()
|
|
|
|
def __unicode__(self):
|
|
if self.ean:
|
|
return '0' + self.upc
|
|
else:
|
|
return self.upc
|
|
|
|
__str__ = __unicode__
|
|
|
|
def get_fullcode(self):
|
|
if self.ean:
|
|
return '0' + self.upc
|
|
else:
|
|
return self.upc
|
|
|
|
def calculate_checksum(self):
|
|
"""Calculates the checksum for UPCA/UPC codes
|
|
|
|
:return: The checksum for 'self.upc'
|
|
:rtype: Integer
|
|
"""
|
|
def sum_(x, y): return int(x) + int(y)
|
|
upc = self.upc[0:self.digits]
|
|
oddsum = reduce(sum_, upc[::2])
|
|
evensum = reduce(sum_, upc[1::2])
|
|
check = (evensum + oddsum * 3) % 10
|
|
if check == 0:
|
|
return 0
|
|
else:
|
|
return 10 - check
|
|
|
|
def build(self):
|
|
"""Builds the barcode pattern from 'self.upc'
|
|
|
|
:return: The pattern as string
|
|
:rtype: String
|
|
"""
|
|
code = _upc.EDGE[:]
|
|
|
|
for i, number in enumerate(self.upc[0:6]):
|
|
code += _upc.CODES['L'][int(number)]
|
|
|
|
code += _upc.MIDDLE
|
|
|
|
for number in self.upc[6:]:
|
|
code += _upc.CODES['R'][int(number)]
|
|
|
|
code += _upc.EDGE
|
|
|
|
return [code]
|
|
|
|
def to_ascii(self):
|
|
"""Returns an ascii representation of the barcode.
|
|
|
|
:rtype: String
|
|
"""
|
|
|
|
code = self.build()
|
|
for i, line in enumerate(code):
|
|
code[i] = line.replace('1', '|').replace('0', '_')
|
|
return '\n'.join(code)
|
|
|
|
def render(self, writer_options=None, text=None):
|
|
options = dict(module_width=0.33)
|
|
options.update(writer_options or {})
|
|
return Barcode.render(self, options, text)
|
|
|
|
UPCA = UniversalProductCodeA
|