Code

2065cfae91d76045cfbaeccf162d7c1df069deda
[inkscape.git] / share / extensions / Barcode / UPCE.py
1 #!/usr/bin/env python
2 '''
3 Copyright (C) 2007 Martin Owens
5 Thanks to Lineaire Chez of Inkbar ( www.inkbar.lineaire.net )
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 '''
22 import EAN13
23 from EAN13 import mapLeftFaimly, guardBar, centerBar
24 import sys
26 mapFamily  = [ '000111','001011','001101','001110','010011','011001','011100','010101','010110','011010' ]
28 class Object(EAN13.Object):
29         def encode(self, number):
30                 result = ''
32                 l = len(number)
34                 if (l != 6 and l != 7  and l != 11 and l != 12) or not number.isdigit():
35                         sys.stderr.write("Can not encode '" + number + "' into UPC-E Barcode, Size must be 6 numbers only, and 1 check digit (optional)\nOr a convertable 11 digit UPC-A number with 1 check digit (also optional).\n")
36                         return
38                 echeck = None
39                 if l==7 or l==12:
40                         echeck = number[-1]
41                         number = number[:-1]
42                         sys.stderr.write("CHECKSUM FOUND!")
43                         l -= 1
45                 if l==6:
46                         number = self.ConvertEtoA(number)
48                 if not echeck:
49                         echeck = self.getChecksum(number)
50                 else:
51                         if not self.verifyChecksum(number + echeck):
52                                 sys.stderr.write("UPC-E Checksum not correct for this barcode, omit last character to generate new checksum.\n")
53                                 return
55                 number = self.ConvertAtoE(number)
56                 if not number:
57                         sys.stderr.write("UPC-A code could not be converted into a UPC-E barcode, please follow the UPC guide or enter a 6 digit UPC-E number..\n")
58                         return
60                 number = number
62                 result = result + guardBar
63                 # The check digit isn't stored as bars but as a mirroring system. :-(
64                 family = mapFamily[int(echeck)]
66                 i = 0
67                 for i in range(0,6):
68                         result += mapLeftFaimly[int(family[i])-1][int(number[i])]
70                 result = result + centerBar + '2';
72                 self.label    = '0  ' + number[:6] + '  ' + echeck
73                 self.inclabel = self.label
74                 return result;
76         def fontSize(self):
77                 return '10'
79         def ConvertAtoE(self, number):
80                 # Converting UPC-A to UPC-E
82                 # All UPC-E Numbers use number system 0
83                 if number[0] != '0' or len(number)!=11:
84                         # If not then the code is invalid
85                         return None
87                 # Most of the conversions deal
88                 # with the specific code parts
89                 manufacturer = number[1:6]
90                 product = number[6:11]
92                 # There are 4 cases to convert:
93                 if manufacturer[2:] == '000' or manufacturer[2:] == '100' or manufacturer[2:] == '200':
94                         # Maxium number product code digits can be encoded
95                         if product[:2]=='00':
96                                 return manufacturer[:2] + product[2:] + manufacturer[2]
97                 elif manufacturer[3:5] == '00':
98                         # Now only 2 product code digits can be used
99                         if product[:3]=='000':
100                                 return manufacturer[:3] + product[3:] + '3'
101                 elif manufacturer[4] == '0':
102                         # With even more manufacturer code we have less room for product code
103                         if product[:4]=='0000':
104                                 return manufacturer[0:4] + product[4] + '4'
105                 elif product[:4]=='0000' and int(product[4]) > 4:
106                         # The last recorse is to try and squeeze it in the last 5 numbers
107                         # so long as the product is 00005-00009 so as not to conflict with
108                         # the 0-4 used above.
109                         return manufacturer + product[4]
110                 else:
111                         # Invalid UPC-A Numbe
112                         return None
114         def ConvertEtoA(self, number):
115                 # Convert UPC-E to UPC-A
117                 # It's more likly to convert this without fault
118                 # But we still must be mindful of the 4 conversions
119                 if len(number)!=6:
120                         return None
122                 if number[5]=='0' or number[5]=='1' or number[5]=='2':
123                         return '0' + number[:2] + number[5] + '0000' + number[2:5]
124                 elif number[5]=='3':
125                         return '0' + number[:3] + '00000' + number[3:5]
126                 elif number[5]=='4':
127                         return '0' + number[:4] + '00000' + number[4]
128                 else:
129                         return '0' + number[:5] + '0000' + number[5]