diff options
Diffstat (limited to '')
-rw-r--r-- | share/extensions/barcode/Upce.py | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/share/extensions/barcode/Upce.py b/share/extensions/barcode/Upce.py new file mode 100644 index 0000000..9404ca2 --- /dev/null +++ b/share/extensions/barcode/Upce.py @@ -0,0 +1,112 @@ +# coding=utf-8 +# +# Copyright (C) 2010 Martin Owens +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA. +# +""" +Python barcode renderer for UPCE barcodes. Designed for use with Inkscape. +""" + +from .BaseEan import EanBarcode +from inkex.localization import inkex_gettext as _ + +# This is almost exactly the same as the standard FAMILIES +# But flipped around and with the first 111000 instead of 000000. +FAMS = [ + "111000", + "110100", + "110010", + "110001", + "101100", + "100110", + "100011", + "101010", + "101001", + "100101", +] + + +class Upce(EanBarcode): + """Generate EAN6/UPC-E barcode generator""" + + name = "upce" + font_size = 10 + lengths = [6, 11] + checks = [7, 12] + center_bar = "020" + + def _encode(self, num, guide=False): + """Generate a UPC-E Barcode""" + self.text = EanBarcode.space(["0"], 2, num[:6], 2, num[-1]) + code = EanBarcode.encode_interleaved(num[-1], num[:6], FAMS) + return self.enclose(code) + + def append_checksum(self, number): + """Generate a UPCE Checksum""" + if len(number) == 6: + number = Upce.convert_e2a(number) + result = self.get_checksum(number) + return Upce.convert_a2e(number) + result + + @staticmethod + def convert_a2e(number): + """Converting UPC-A to UPC-E, may cause errors.""" + # All UPC-E Numbers use number system 0 + if number[0] != "0" or len(number) != 11: + # If not then the code is invalid + raise ValueError(_("Invalid UPC Number")) + + # Most of the conversions deal + # with the specific code parts + maker = number[1:6] + product = number[6:11] + + # There are 4 cases to convert: + if maker[2:] == "000" or maker[2:] == "100" or maker[2:] == "200": + # Maximum number product code digits can be encoded + if product[:2] == "00": + return maker[:2] + product[2:] + maker[2] + elif maker[3:5] == "00": + # Now only 2 product code digits can be used + if product[:3] == "000": + return maker[:3] + product[3:] + "3" + elif maker[4] == "0": + # With even more maker code we have less room for product code + if product[:4] == "0000": + return maker[0:4] + product[4] + "4" + elif product[:4] == "0000" and int(product[4]) > 4: + # The last recorse is to try and squeeze it in the last 5 numbers + # so long as the product is 00005-00009 so as not to conflict with + # the 0-4 used above. + return maker + product[4] + # Invalid UPC-A Numbe + raise ValueError(_("Invalid UPC Number")) + + @staticmethod + def convert_e2a(number): + """Convert UPC-E to UPC-A by padding with zeros""" + # It's more likly to convert this without fault + # But we still must be mindful of the 4 conversions + if len(number) != 6: + return None + + if number[5] in ["0", "1", "2"]: + return "0" + number[:2] + number[5] + "0000" + number[2:5] + if number[5] == "3": + return "0" + number[:3] + "00000" + number[3:5] + if number[5] == "4": + return "0" + number[:4] + "00000" + number[4] + return "0" + number[:5] + "0000" + number[5] |