summaryrefslogtreecommitdiffstats
path: root/share/extensions/barcode/Upce.py
diff options
context:
space:
mode:
Diffstat (limited to 'share/extensions/barcode/Upce.py')
-rw-r--r--share/extensions/barcode/Upce.py112
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]