Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic support for MSI / Plessey #191

Open
wants to merge 32 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
46d61ed
MSI barcodes, with bytes/strings encoding
Dec 9, 2022
037bf5b
typo + better docstrings
Dec 10, 2022
ce27899
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 10, 2022
92e90d5
fixed silly mistake, more sensible defaults
Dec 10, 2022
2d56b80
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 10, 2022
7505382
removed code-can-be-string, added type hints
Dec 10, 2022
201c07d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 10, 2022
bac523d
use regular sphinx format
Dec 10, 2022
f5118db
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 10, 2022
03dbda8
depressed keyboard
Dec 10, 2022
3b26a75
fixes for failed test
Dec 10, 2022
e38637c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 10, 2022
079d2b5
NoneType is... not a type
Dec 10, 2022
fe993d7
stilly very new to this...
Dec 10, 2022
523d2cd
this is annoying
Dec 10, 2022
71d3fe1
import
Dec 10, 2022
4bc63a6
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 10, 2022
097591f
more errors
Dec 10, 2022
51e1a79
don't know how to do that
Dec 10, 2022
ba6ce09
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 10, 2022
59f0776
more explicit
Dec 10, 2022
84881a4
this is getting ridiculous.
Dec 10, 2022
1428670
whatever.
Dec 10, 2022
a3e3aec
removed stupid try/except
Dec 11, 2022
4a822b1
setting label when code is int
Dec 11, 2022
47f557c
background can be omitted
Dec 11, 2022
854a1ff
just found out about 'text' argument to save()
Dec 11, 2022
02c5f44
just found out about 'text' argument to save()
Dec 11, 2022
aed1d4b
meeh. doing label a bit more "right"
Dec 11, 2022
2cfaad4
background can be omitted
Dec 11, 2022
eebc2c5
meeh. doing label a bit more "right"
Dec 11, 2022
943acae
Merge branch 'MSI'
Dec 11, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions barcode/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""This package provides a simple way to create standard barcodes.
It needs no external packages to be installed, the barcodes are
"""This package provides a simple way to create standard barcodes. It needs no
external packages to be installed (exception: 'luhn' for MSI), the barcodes are
created as SVG objects. If Pillow is installed, the barcodes can also be
rendered as images (all formats supported by Pillow).
"""
Expand All @@ -9,6 +9,7 @@
from typing import Union

from barcode.codabar import CODABAR
from barcode.codex import MSI
from barcode.codex import PZN
from barcode.codex import Code39
from barcode.codex import Code128
Expand Down Expand Up @@ -50,6 +51,7 @@
"gs1_128": Gs1_128,
"codabar": CODABAR,
"nw-7": CODABAR,
"msi": MSI,
}

PROVIDED_BARCODES = list(__BARCODE_MAP)
Expand Down
89 changes: 80 additions & 9 deletions barcode/codex.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Module: barcode.codex

:Provided barcodes: Code 39, Code 128, PZN
:Provided barcodes: Code 39, Code 128, PZN, MSI
"""
from barcode.base import Barcode
from barcode.charsets import code39
Expand Down Expand Up @@ -77,11 +77,10 @@ def render(self, writer_options=None, text=None):
class PZN7(Code39):
"""Initializes new German number for pharmaceutical products.

:parameters:
pzn : String
Code to render.
writer : barcode.writer Instance
The writer to render the barcode (default: SVGWriter).
:param pzn: String
Code to render.
:param writer: barcode.writer Instance
The writer to render the barcode (default: SVGWriter).
"""

name = "Pharmazentralnummer"
Expand Down Expand Up @@ -122,10 +121,9 @@ class Code128(Barcode):
"""Initializes a new Code128 instance. The checksum is added automatically
when building the bars.

:parameters:
code : String
:param code: String
Code 128 string without checksum (added automatically).
writer : barcode.writer Instance
:param writer: barcode.writer Instance
The writer to render the barcode (default: SVGWriter).
"""

Expand Down Expand Up @@ -271,5 +269,78 @@ def get_fullcode(self):
return super().get_fullcode()[1:]


class MSI(Barcode):
"""Initializes a new MSI (Modified Plessey) instance. The checksum is added
automatically when building the bars.

:parameters:
:param code: int or bytes
Code MSI int without checksum (added automatically).
Code bytes without checksum. requires byteorder (WARNING: non-standard use)
:param writer: barcode.writer Instance
The writer to render the barcode (default: SVGWriter).
:param byteorder: string
'big' or 'little' ; to convert bytes to int
:param encoding: string
if set, convert bytes to string and use this as a label. defaults to utf-8
if unset, use integer value as label
Note: for convenience ; label can also be set when calling save() with param
'text'

limitations:
- only one check digit (Luhn Mod10)
- only standard prefix/suffix

"""

name = "MSI/Modified Plessey"

def __init__(
self,
code,
writer=None,
byteorder=None,
encoding="utf-8",
):
self.writer = writer or self.default_writer()
self._buffer = ""

if type(code) is int:
self.label = self.code = str(code)
elif type(code) is bytes:
self.code = str(int.from_bytes(code, byteorder))
if encoding is not None:
self.label = code.decode(encoding)
else:
self.label = self.code if label is None else label
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no variable named label in this scope.


def __str__(self):
return self.label

@property
def encoded(self):
return self._build()

def get_fullcode(self):
return self.label

def _build(self):
"""
check digit is computed with https://pypi.org/project/luhn/
"""
from luhn import append as luhn_check_append

bcd = "".join([f"{bin(int(n))[2:]:0>4}" for n in luhn_check_append(self.code)])

conv = {
"0": "100",
"1": "110",
}
return ["110" + "".join([conv[i] for i in bcd]) + "1001"]

def build(self):
return self.encoded


# For pre 0.8 compatibility
PZN = PZN7
17 changes: 9 additions & 8 deletions barcode/writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,14 +322,15 @@ def _init(self, code):
attributes = {"id": "barcode_group"}
_set_attributes(group, **attributes)
self._group = self._root.appendChild(group)
background = self._document.createElement("rect")
attributes = {
"width": "100%",
"height": "100%",
"style": f"fill:{self.background}",
}
_set_attributes(background, **attributes)
self._group.appendChild(background)
if self.background:
background = self._document.createElement("rect")
attributes = {
"width": "100%",
"height": "100%",
"style": f"fill:{self.background}",
}
_set_attributes(background, **attributes)
self._group.appendChild(background)

def _create_module(self, xpos, ypos, width, color):
# Background rect has been provided already, so skipping "spaces"
Expand Down