-
-
Notifications
You must be signed in to change notification settings - Fork 134
Expand file tree
/
Copy pathbase.py
More file actions
executable file
·127 lines (100 loc) · 3.7 KB
/
base.py
File metadata and controls
executable file
·127 lines (100 loc) · 3.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
"""barcode.base"""
from __future__ import annotations
from typing import TYPE_CHECKING
from typing import ClassVar
from typing import Generic
from typing import TypeVar
from barcode.writer import BaseWriter
from barcode.writer import SVGWriter
from barcode.writer import T_Output
if TYPE_CHECKING:
from typing import BinaryIO
W = TypeVar("W", bound=BaseWriter[object])
class Barcode(Generic[W, T_Output]):
name = ""
digits = 0
default_writer = SVGWriter
default_writer_options: ClassVar[dict] = {
"module_width": 0.2,
"module_height": 15.0,
"quiet_zone": 6.5,
"font_size": 10,
"text_distance": 5.0,
"background": "white",
"foreground": "black",
"write_text": True,
"text": "",
}
writer: W
def __init__(self, code: str, writer: W | None = None, **options) -> None:
raise NotImplementedError
def to_ascii(self) -> str:
code_list = self.build()
if not len(code_list) == 1:
raise RuntimeError("Code list must contain a single element.")
code = code_list[0]
return code.replace("1", "X").replace("0", " ")
def __repr__(self) -> str:
return f"<{self.__class__.__name__}({self.get_fullcode()!r})>"
def build(self) -> list[str]:
"""Return a single-element list with a string encoding the barcode.
Typically the string consists of 1s and 0s, although it can contain
other characters such as G for guard lines (e.g. in EAN13)."""
raise NotImplementedError
def get_fullcode(self):
"""Returns the full code, encoded in the barcode.
:returns: Full human readable code.
:rtype: String
"""
raise NotImplementedError
def save(
self,
filename: str,
options: dict | None = None,
text: str | None = None,
) -> str:
"""Renders the barcode and saves it in `filename`.
:param filename: Filename to save the barcode in (without filename extension).
:param options: The same as in `self.render`.
:param text: Text to render under the barcode.
:returns: The full filename with extension.
"""
output: T_Output = self.render(options, text) if text else self.render(options)
return self.writer.save(filename, output)
def write(
self,
fp: BinaryIO,
options: dict | None = None,
text: str | None = None,
) -> None:
"""Renders the barcode and writes it to the file like object
`fp`.
:param fp: Object to write the raw data in.
:param options: The same as in `self.render`.
:param text: Text to render under the barcode.
"""
output = self.render(options, text)
self.writer.write(output, fp)
def render(
self,
writer_options: dict | None = None,
text: str | None = None,
) -> T_Output:
"""Renders the barcode using `self.writer`.
:param writer_options: Options for `self.writer`, see writer docs for details.
:param text: Text to render under the barcode.
:returns: Output of the writers render method.
"""
options = self.default_writer_options.copy()
options.update(writer_options or {})
if options["write_text"] or text is not None:
if text is not None:
options["text"] = text
else:
options["text"] = self.get_fullcode()
self.writer.set_options(options)
code_list = self.build()
if not len(code_list) == 1:
raise RuntimeError("Code list must contain a single element.")
code = code_list[0]
return self.writer.render([code])