|
8 | 8 | """ |
9 | 9 | __docformat__ = 'restructuredtext en' |
10 | 10 |
|
11 | | -from barcode.ean import EuropeanArticleNumber13 |
| 11 | +from barcode.base import Barcode |
| 12 | +from barcode.charsets import upc as _upc |
| 13 | +from barcode.errors import * |
12 | 14 |
|
13 | | - |
14 | | -class UniversalProductCodeA(EuropeanArticleNumber13): |
15 | | - """Initializes new UPC-A barcode. Can be rendered as EAN-13 by passing |
16 | | - `True` to the `make_ean` argument. |
| 15 | +class UniversalProductCodeA(Barcode): |
| 16 | + """Initializes new UPC-A barcode. |
17 | 17 |
|
18 | 18 | :parameters: |
19 | 19 | upc : String |
20 | 20 | The upc number as string. |
21 | 21 | writer : barcode.writer Instance |
22 | 22 | The writer to render the barcode (default: SVGWriter). |
23 | | - make_ean : Boolean |
24 | | - Render barcode as EAN-13 with leading 0 (default: False). |
25 | 23 | """ |
26 | 24 |
|
27 | 25 | name = 'UPC-A' |
28 | 26 |
|
29 | 27 | digits = 11 |
30 | 28 |
|
31 | | - def __init__(self, upc, writer=None, make_ean=False): |
32 | | - if make_ean: |
33 | | - UniversalProductCodeA.digits = 12 |
34 | | - upc = '0' + upc |
| 29 | + def __init__(self, upc, writer=None): |
| 30 | + upc = upc[:self.digits] |
| 31 | + if not upc.isdigit(): |
| 32 | + raise IllegalCharacterError('UPC code can only contain numbers.') |
| 33 | + if len(upc) != self.digits: |
| 34 | + raise NumberOfDigitsError('UPC must have {0} digits, not ' |
| 35 | + '{1}.'.format(self.digits, len(upc))) |
35 | 36 | self.upc = upc |
36 | | - EuropeanArticleNumber13.__init__(self, upc, writer) |
| 37 | + self.upc = '{}{}'.format(upc, self.calculate_checksum()) |
| 38 | + self.writer = writer or Barcode.default_writer() |
37 | 39 |
|
38 | 40 | def __unicode__(self): |
39 | 41 | return self.upc |
40 | 42 |
|
41 | 43 | __str__ = __unicode__ |
42 | 44 |
|
| 45 | + def get_fullcode(self): |
| 46 | + return self.upc |
| 47 | + |
| 48 | + def calculate_checksum(self): |
| 49 | + """Calculates the checksum for UPCA/UPC codes |
| 50 | +
|
| 51 | + :return: The checksum for 'self.upc' |
| 52 | + :rtype: Integer |
| 53 | + """ |
| 54 | + def sum_(x, y): return int(x) + int(y) |
| 55 | + upc = self.upc[0:self.digits] |
| 56 | + oddsum = reduce(sum_, upc[::2]) |
| 57 | + evensum = reduce(sum_, upc[1::2]) |
| 58 | + check = (evensum + oddsum * 3) % 10 |
| 59 | + if check == 0: |
| 60 | + return 0 |
| 61 | + else: |
| 62 | + return 10 - check |
| 63 | + |
| 64 | + |
| 65 | + def build(self): |
| 66 | + """Builds the barcode pattern from 'self.upc' |
| 67 | +
|
| 68 | + :return: The pattern as string |
| 69 | + :rtype: String |
| 70 | + """ |
| 71 | + print self.upc |
| 72 | + code = _upc.EDGE |
| 73 | + |
| 74 | + for i, number in enumerate(self.upc[0:6]): |
| 75 | + code += _upc.CODES['L'][int(number)] |
| 76 | + |
| 77 | + code += _upc.MIDDLE |
| 78 | + |
| 79 | + for number in self.upc[6:]: |
| 80 | + code += _upc.CODES['R'][int(number)] |
| 81 | + |
| 82 | + code += _upc.EDGE |
| 83 | + |
| 84 | + return [code] |
| 85 | + |
| 86 | + def to_ascii(self): |
| 87 | + """Returns an ascii representation of the barcode. |
| 88 | +
|
| 89 | + :rtype: String |
| 90 | + """ |
| 91 | + |
| 92 | + code = self.build() |
| 93 | + for i, line in enumerate(code): |
| 94 | + code[i] = line.replace('1', '|').replace('0', '_') |
| 95 | + return '\n'.join(code) |
| 96 | + |
| 97 | + def render(self, writer_options=None): |
| 98 | + options = dict(module_width=0.33) |
| 99 | + options.update(writer_options or {}) |
| 100 | + return Barcode.render(self, options) |
43 | 101 |
|
44 | 102 | UPCA = UniversalProductCodeA |
0 commit comments