PyPDFForm 1.4.12__tar.gz → 1.4.13__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of PyPDFForm might be problematic. Click here for more details.
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PKG-INFO +1 -1
- PyPDFForm-1.4.13/PyPDFForm/__init__.py +6 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm/constants.py +6 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm/filler.py +63 -3
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm/wrapper.py +36 -8
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm.egg-info/PKG-INFO +1 -1
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm.egg-info/SOURCES.txt +4 -0
- PyPDFForm-1.4.13/tests/test_dropdown_simple.py +148 -0
- PyPDFForm-1.4.13/tests/test_fill_max_length_text_field_simple.py +92 -0
- PyPDFForm-1.4.13/tests/test_functional_simple.py +115 -0
- PyPDFForm-1.4.13/tests/test_paragraph_simple.py +137 -0
- PyPDFForm-1.4.12/PyPDFForm/__init__.py +0 -6
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/LICENSE +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm/adapter.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm/coordinate.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm/font.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm/image.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm/middleware/__init__.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm/middleware/base.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm/middleware/checkbox.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm/middleware/dropdown.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm/middleware/radio.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm/middleware/signature.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm/middleware/text.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm/patterns.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm/template.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm/utils.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm/watermark.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm/widgets/__init__.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm/widgets/base.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm/widgets/checkbox.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm/widgets/text.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm.egg-info/dependency_links.txt +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm.egg-info/requires.txt +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/PyPDFForm.egg-info/top_level.txt +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/README.md +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/setup.cfg +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/setup.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/tests/test_create_widget.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/tests/test_dropdown.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/tests/test_fill_max_length_text_field.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/tests/test_functional.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/tests/test_paragraph.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/tests/test_preview.py +0 -0
- {PyPDFForm-1.4.12 → PyPDFForm-1.4.13}/tests/test_signature.py +0 -0
|
@@ -26,6 +26,7 @@ WIDGET_TYPES = Union[Text, Checkbox, Radio, Dropdown, Signature]
|
|
|
26
26
|
|
|
27
27
|
DEPRECATION_NOTICE = "{} will be deprecated soon. Use {} instead."
|
|
28
28
|
|
|
29
|
+
ANNOTATION_KEY = "/Annots"
|
|
29
30
|
ANNOTATION_FIELD_KEY = "/T"
|
|
30
31
|
ANNOTATION_RECTANGLE_KEY = "/Rect"
|
|
31
32
|
SUBTYPE_KEY = "/Subtype"
|
|
@@ -34,6 +35,8 @@ WIDGET_TYPE_KEY = "/FT"
|
|
|
34
35
|
PARENT_KEY = "/Parent"
|
|
35
36
|
FIELD_FLAG_KEY = "/Ff"
|
|
36
37
|
TEXT_FIELD_IDENTIFIER = "/Tx"
|
|
38
|
+
TEXT_VALUE_IDENTIFIER = "/V"
|
|
39
|
+
TEXT_VALUE_SHOW_UP_IDENTIFIER = "/AP"
|
|
37
40
|
SIGNATURE_FIELD_IDENTIFIER = "/Sig"
|
|
38
41
|
TEXT_FIELD_APPEARANCE_IDENTIFIER = "/DA"
|
|
39
42
|
SELECTABLE_IDENTIFIER = "/Btn"
|
|
@@ -43,6 +46,7 @@ CHOICE_FIELD_IDENTIFIER = "/Ch"
|
|
|
43
46
|
CHOICES_IDENTIFIER = "/Opt"
|
|
44
47
|
BUTTON_IDENTIFIER = "/MK"
|
|
45
48
|
BUTTON_STYLE_IDENTIFIER = "/CA"
|
|
49
|
+
SELECTED_IDENTIFIER = "/AS"
|
|
46
50
|
|
|
47
51
|
# Field flag bits
|
|
48
52
|
MULTILINE = 1 << 12
|
|
@@ -65,4 +69,6 @@ BUTTON_STYLES = {
|
|
|
65
69
|
"l": "\u25CF", # circle
|
|
66
70
|
}
|
|
67
71
|
|
|
72
|
+
CHECKBOX_SELECT = "/Yes"
|
|
73
|
+
|
|
68
74
|
COORDINATE_GRID_FONT_SIZE_MARGIN_RATIO = DEFAULT_FONT_SIZE / 100
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
"""Contains helpers for filling a PDF form."""
|
|
3
3
|
|
|
4
|
-
from
|
|
4
|
+
from io import BytesIO
|
|
5
|
+
from typing import Dict, cast
|
|
5
6
|
|
|
6
|
-
from
|
|
7
|
+
from pypdf import PdfReader, PdfWriter
|
|
8
|
+
from pypdf.generic import DictionaryObject, NameObject, TextStringObject
|
|
9
|
+
|
|
10
|
+
from .constants import (ANNOTATION_KEY, CHECKBOX_SELECT, SELECTED_IDENTIFIER,
|
|
11
|
+
TEXT_VALUE_IDENTIFIER, TEXT_VALUE_SHOW_UP_IDENTIFIER,
|
|
12
|
+
WIDGET_TYPES)
|
|
7
13
|
from .coordinate import (get_draw_checkbox_radio_coordinates,
|
|
8
14
|
get_draw_sig_coordinates_resolutions,
|
|
9
15
|
get_draw_text_coordinates,
|
|
@@ -11,10 +17,12 @@ from .coordinate import (get_draw_checkbox_radio_coordinates,
|
|
|
11
17
|
from .font import checkbox_radio_font_size
|
|
12
18
|
from .image import any_image_to_jpg
|
|
13
19
|
from .middleware.checkbox import Checkbox
|
|
20
|
+
from .middleware.dropdown import Dropdown
|
|
14
21
|
from .middleware.radio import Radio
|
|
15
22
|
from .middleware.signature import Signature
|
|
23
|
+
from .middleware.text import Text
|
|
16
24
|
from .template import get_widget_key, get_widgets_by_page
|
|
17
|
-
from .utils import checkbox_radio_to_draw
|
|
25
|
+
from .utils import checkbox_radio_to_draw, stream_to_io
|
|
18
26
|
from .watermark import create_watermarks_and_draw, merge_watermarks_with_pdf
|
|
19
27
|
|
|
20
28
|
|
|
@@ -117,3 +125,55 @@ def fill(
|
|
|
117
125
|
result = merge_watermarks_with_pdf(result, image_watermarks)
|
|
118
126
|
|
|
119
127
|
return result
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def simple_fill(
|
|
131
|
+
template: bytes,
|
|
132
|
+
widgets: Dict[str, WIDGET_TYPES],
|
|
133
|
+
) -> bytes:
|
|
134
|
+
"""Fills a PDF form in place."""
|
|
135
|
+
|
|
136
|
+
pdf = PdfReader(stream_to_io(template))
|
|
137
|
+
out = PdfWriter()
|
|
138
|
+
out.append(pdf)
|
|
139
|
+
|
|
140
|
+
radio_button_tracker = {}
|
|
141
|
+
|
|
142
|
+
for page in out.pages:
|
|
143
|
+
for annot in page.get(ANNOTATION_KEY, []): # noqa
|
|
144
|
+
annot = cast(DictionaryObject, annot.get_object())
|
|
145
|
+
key = get_widget_key(annot.get_object())
|
|
146
|
+
|
|
147
|
+
widget = widgets.get(key)
|
|
148
|
+
if widget is None:
|
|
149
|
+
continue
|
|
150
|
+
|
|
151
|
+
if isinstance(widget, Checkbox) and widget.value is True:
|
|
152
|
+
annot[NameObject(SELECTED_IDENTIFIER)] = NameObject(CHECKBOX_SELECT)
|
|
153
|
+
elif isinstance(widget, Radio):
|
|
154
|
+
if key not in radio_button_tracker:
|
|
155
|
+
radio_button_tracker[key] = 0
|
|
156
|
+
radio_button_tracker[key] += 1
|
|
157
|
+
if widget.value == radio_button_tracker[key] - 1:
|
|
158
|
+
annot[NameObject(SELECTED_IDENTIFIER)] = NameObject(
|
|
159
|
+
f"/{widget.value}"
|
|
160
|
+
)
|
|
161
|
+
elif isinstance(widget, Dropdown) and widget.value is not None:
|
|
162
|
+
annot[NameObject(TEXT_VALUE_IDENTIFIER)] = TextStringObject(
|
|
163
|
+
widget.choices[widget.value]
|
|
164
|
+
)
|
|
165
|
+
annot[NameObject(TEXT_VALUE_SHOW_UP_IDENTIFIER)] = TextStringObject(
|
|
166
|
+
widget.choices[widget.value]
|
|
167
|
+
)
|
|
168
|
+
elif isinstance(widget, Text) and widget.value:
|
|
169
|
+
annot[NameObject(TEXT_VALUE_IDENTIFIER)] = TextStringObject(
|
|
170
|
+
widget.value
|
|
171
|
+
)
|
|
172
|
+
annot[NameObject(TEXT_VALUE_SHOW_UP_IDENTIFIER)] = TextStringObject(
|
|
173
|
+
widget.value
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
with BytesIO() as f:
|
|
177
|
+
out.write(f)
|
|
178
|
+
f.seek(0)
|
|
179
|
+
return f.read()
|
|
@@ -11,7 +11,7 @@ from .constants import (DEFAULT_FONT, DEFAULT_FONT_COLOR, DEFAULT_FONT_SIZE,
|
|
|
11
11
|
DEPRECATION_NOTICE, VERSION_IDENTIFIER_PREFIX,
|
|
12
12
|
VERSION_IDENTIFIERS)
|
|
13
13
|
from .coordinate import generate_coordinate_grid
|
|
14
|
-
from .filler import fill
|
|
14
|
+
from .filler import fill, simple_fill
|
|
15
15
|
from .font import register_font
|
|
16
16
|
from .image import any_image_to_jpg, rotate_image
|
|
17
17
|
from .middleware.dropdown import Dropdown
|
|
@@ -26,7 +26,40 @@ from .widgets.checkbox import CheckBoxWidget
|
|
|
26
26
|
from .widgets.text import TextWidget
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
class
|
|
29
|
+
class FormWrapper:
|
|
30
|
+
"""A simple base wrapper for just filling a PDF form."""
|
|
31
|
+
|
|
32
|
+
def __init__(
|
|
33
|
+
self,
|
|
34
|
+
template: Union[bytes, str, BinaryIO] = b"",
|
|
35
|
+
) -> None:
|
|
36
|
+
"""Constructs all attributes for the object."""
|
|
37
|
+
|
|
38
|
+
self.stream = fp_or_f_obj_or_stream_to_stream(template)
|
|
39
|
+
|
|
40
|
+
def read(self) -> bytes:
|
|
41
|
+
"""Reads the file stream of a PDF form."""
|
|
42
|
+
|
|
43
|
+
return self.stream
|
|
44
|
+
|
|
45
|
+
def fill(
|
|
46
|
+
self,
|
|
47
|
+
data: Dict[str, Union[str, bool, int]],
|
|
48
|
+
) -> FormWrapper:
|
|
49
|
+
"""Fills a PDF form."""
|
|
50
|
+
|
|
51
|
+
widgets = build_widgets(self.stream) if self.stream else {}
|
|
52
|
+
|
|
53
|
+
for key, value in data.items():
|
|
54
|
+
if key in widgets:
|
|
55
|
+
widgets[key].value = value
|
|
56
|
+
|
|
57
|
+
self.stream = simple_fill(self.read(), widgets)
|
|
58
|
+
|
|
59
|
+
return self
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class PdfWrapper(FormWrapper):
|
|
30
63
|
"""A class to represent a PDF form."""
|
|
31
64
|
|
|
32
65
|
def __init__(
|
|
@@ -36,7 +69,7 @@ class PdfWrapper:
|
|
|
36
69
|
) -> None:
|
|
37
70
|
"""Constructs all attributes for the object."""
|
|
38
71
|
|
|
39
|
-
|
|
72
|
+
super().__init__(template)
|
|
40
73
|
self.widgets = build_widgets(self.stream) if self.stream else {}
|
|
41
74
|
|
|
42
75
|
self.global_font = kwargs.get("global_font")
|
|
@@ -49,11 +82,6 @@ class PdfWrapper:
|
|
|
49
82
|
each.font_size = self.global_font_size
|
|
50
83
|
each.font_color = self.global_font_color
|
|
51
84
|
|
|
52
|
-
def read(self) -> bytes:
|
|
53
|
-
"""Reads the file stream of a PDF form."""
|
|
54
|
-
|
|
55
|
-
return self.stream
|
|
56
|
-
|
|
57
85
|
@property
|
|
58
86
|
def elements(self) -> dict:
|
|
59
87
|
"""ToDo: deprecate this."""
|
|
@@ -31,8 +31,12 @@ PyPDFForm/widgets/checkbox.py
|
|
|
31
31
|
PyPDFForm/widgets/text.py
|
|
32
32
|
tests/test_create_widget.py
|
|
33
33
|
tests/test_dropdown.py
|
|
34
|
+
tests/test_dropdown_simple.py
|
|
34
35
|
tests/test_fill_max_length_text_field.py
|
|
36
|
+
tests/test_fill_max_length_text_field_simple.py
|
|
35
37
|
tests/test_functional.py
|
|
38
|
+
tests/test_functional_simple.py
|
|
36
39
|
tests/test_paragraph.py
|
|
40
|
+
tests/test_paragraph_simple.py
|
|
37
41
|
tests/test_preview.py
|
|
38
42
|
tests/test_signature.py
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
from PyPDFForm import FormWrapper
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_dropdown_not_specified(sample_template_with_dropdown):
|
|
9
|
+
assert (
|
|
10
|
+
FormWrapper(sample_template_with_dropdown)
|
|
11
|
+
.fill(
|
|
12
|
+
{
|
|
13
|
+
"test_1": "test_1",
|
|
14
|
+
"test_2": "test_2",
|
|
15
|
+
"test_3": "test_3",
|
|
16
|
+
"check_1": True,
|
|
17
|
+
"check_2": True,
|
|
18
|
+
"check_3": True,
|
|
19
|
+
"radio_1": 1,
|
|
20
|
+
}
|
|
21
|
+
)
|
|
22
|
+
.read()
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def test_dropdown_one(sample_template_with_dropdown, pdf_samples, request):
|
|
27
|
+
expected_path = os.path.join(pdf_samples, "simple", "dropdown", "dropdown_one.pdf")
|
|
28
|
+
with open(expected_path, "rb+") as f:
|
|
29
|
+
obj = FormWrapper(sample_template_with_dropdown).fill(
|
|
30
|
+
{
|
|
31
|
+
"test_1": "test_1",
|
|
32
|
+
"test_2": "test_2",
|
|
33
|
+
"test_3": "test_3",
|
|
34
|
+
"check_1": True,
|
|
35
|
+
"check_2": True,
|
|
36
|
+
"check_3": True,
|
|
37
|
+
"radio_1": 1,
|
|
38
|
+
"dropdown_1": 0,
|
|
39
|
+
},
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
request.config.results["expected_path"] = expected_path
|
|
43
|
+
request.config.results["stream"] = obj.read()
|
|
44
|
+
|
|
45
|
+
expected = f.read()
|
|
46
|
+
|
|
47
|
+
assert len(obj.read()) == len(expected)
|
|
48
|
+
assert obj.stream == expected
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_dropdown_two(sample_template_with_dropdown, pdf_samples, request):
|
|
52
|
+
expected_path = os.path.join(pdf_samples, "simple", "dropdown", "dropdown_two.pdf")
|
|
53
|
+
with open(expected_path, "rb+") as f:
|
|
54
|
+
obj = FormWrapper(sample_template_with_dropdown).fill(
|
|
55
|
+
{
|
|
56
|
+
"test_1": "test_1",
|
|
57
|
+
"test_2": "test_2",
|
|
58
|
+
"test_3": "test_3",
|
|
59
|
+
"check_1": True,
|
|
60
|
+
"check_2": True,
|
|
61
|
+
"check_3": True,
|
|
62
|
+
"radio_1": 1,
|
|
63
|
+
"dropdown_1": 1,
|
|
64
|
+
},
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
request.config.results["expected_path"] = expected_path
|
|
68
|
+
request.config.results["stream"] = obj.read()
|
|
69
|
+
|
|
70
|
+
expected = f.read()
|
|
71
|
+
|
|
72
|
+
assert len(obj.read()) == len(expected)
|
|
73
|
+
assert obj.stream == expected
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def test_dropdown_three(sample_template_with_dropdown, pdf_samples, request):
|
|
77
|
+
expected_path = os.path.join(
|
|
78
|
+
pdf_samples, "simple", "dropdown", "dropdown_three.pdf"
|
|
79
|
+
)
|
|
80
|
+
with open(expected_path, "rb+") as f:
|
|
81
|
+
obj = FormWrapper(sample_template_with_dropdown).fill(
|
|
82
|
+
{
|
|
83
|
+
"test_1": "test_1",
|
|
84
|
+
"test_2": "test_2",
|
|
85
|
+
"test_3": "test_3",
|
|
86
|
+
"check_1": True,
|
|
87
|
+
"check_2": True,
|
|
88
|
+
"check_3": True,
|
|
89
|
+
"radio_1": 1,
|
|
90
|
+
"dropdown_1": 2,
|
|
91
|
+
},
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
request.config.results["expected_path"] = expected_path
|
|
95
|
+
request.config.results["stream"] = obj.read()
|
|
96
|
+
|
|
97
|
+
expected = f.read()
|
|
98
|
+
|
|
99
|
+
assert len(obj.read()) == len(expected)
|
|
100
|
+
assert obj.stream == expected
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def test_dropdown_four(sample_template_with_dropdown, pdf_samples, request):
|
|
104
|
+
expected_path = os.path.join(pdf_samples, "simple", "dropdown", "dropdown_four.pdf")
|
|
105
|
+
with open(expected_path, "rb+") as f:
|
|
106
|
+
obj = FormWrapper(sample_template_with_dropdown).fill(
|
|
107
|
+
{
|
|
108
|
+
"test_1": "test_1",
|
|
109
|
+
"test_2": "test_2",
|
|
110
|
+
"test_3": "test_3",
|
|
111
|
+
"check_1": True,
|
|
112
|
+
"check_2": True,
|
|
113
|
+
"check_3": True,
|
|
114
|
+
"radio_1": 1,
|
|
115
|
+
"dropdown_1": 3,
|
|
116
|
+
},
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
request.config.results["expected_path"] = expected_path
|
|
120
|
+
request.config.results["stream"] = obj.read()
|
|
121
|
+
|
|
122
|
+
expected = f.read()
|
|
123
|
+
|
|
124
|
+
assert len(obj.read()) == len(expected)
|
|
125
|
+
assert obj.stream == expected
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def test_dropdown_alignment(dropdown_alignment, pdf_samples, request):
|
|
129
|
+
expected_path = os.path.join(
|
|
130
|
+
pdf_samples, "simple", "dropdown", "dropdown_alignment_expected.pdf"
|
|
131
|
+
)
|
|
132
|
+
with open(expected_path, "rb+") as f:
|
|
133
|
+
obj = FormWrapper(dropdown_alignment).fill(
|
|
134
|
+
{
|
|
135
|
+
"dropdown_left": 0,
|
|
136
|
+
"dropdown_center": 1,
|
|
137
|
+
"dropdown_right": 2,
|
|
138
|
+
},
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
request.config.results["expected_path"] = expected_path
|
|
142
|
+
request.config.results["stream"] = obj.read()
|
|
143
|
+
|
|
144
|
+
expected = f.read()
|
|
145
|
+
|
|
146
|
+
if os.name != "nt":
|
|
147
|
+
assert len(obj.read()) == len(expected)
|
|
148
|
+
assert obj.stream == expected
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
from PyPDFForm import FormWrapper
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_fill_max_length_text_field_all_chars(
|
|
9
|
+
sample_template_with_max_length_text_field, pdf_samples, request
|
|
10
|
+
):
|
|
11
|
+
expected_path = os.path.join(
|
|
12
|
+
pdf_samples,
|
|
13
|
+
"simple",
|
|
14
|
+
"max_length_text_field_related",
|
|
15
|
+
"max_length_text_field_all_chars.pdf",
|
|
16
|
+
)
|
|
17
|
+
with open(expected_path, "rb+") as f:
|
|
18
|
+
obj = FormWrapper(sample_template_with_max_length_text_field).fill(
|
|
19
|
+
{
|
|
20
|
+
"FirstName": "John",
|
|
21
|
+
"MiddleName": "Joe",
|
|
22
|
+
"LastName": "XXXXXXXXXX",
|
|
23
|
+
"Awesomeness": True,
|
|
24
|
+
"Gender": 0,
|
|
25
|
+
}
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
request.config.results["expected_path"] = expected_path
|
|
29
|
+
request.config.results["stream"] = obj.read()
|
|
30
|
+
|
|
31
|
+
expected = f.read()
|
|
32
|
+
|
|
33
|
+
assert len(obj.stream) == len(expected)
|
|
34
|
+
assert obj.stream == expected
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def test_fill_max_length_text_field_odd_chars(
|
|
38
|
+
sample_template_with_max_length_text_field, pdf_samples, request
|
|
39
|
+
):
|
|
40
|
+
expected_path = os.path.join(
|
|
41
|
+
pdf_samples,
|
|
42
|
+
"simple",
|
|
43
|
+
"max_length_text_field_related",
|
|
44
|
+
"max_length_text_field_odd_chars.pdf",
|
|
45
|
+
)
|
|
46
|
+
with open(expected_path, "rb+") as f:
|
|
47
|
+
obj = FormWrapper(sample_template_with_max_length_text_field).fill(
|
|
48
|
+
{
|
|
49
|
+
"FirstName": "John",
|
|
50
|
+
"MiddleName": "Joe",
|
|
51
|
+
"LastName": "XXX",
|
|
52
|
+
"Awesomeness": True,
|
|
53
|
+
"Gender": 0,
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
request.config.results["expected_path"] = expected_path
|
|
58
|
+
request.config.results["stream"] = obj.read()
|
|
59
|
+
|
|
60
|
+
expected = f.read()
|
|
61
|
+
|
|
62
|
+
assert len(obj.stream) == len(expected)
|
|
63
|
+
assert obj.stream == expected
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_fill_max_length_text_field_even_chars(
|
|
67
|
+
sample_template_with_max_length_text_field, pdf_samples, request
|
|
68
|
+
):
|
|
69
|
+
expected_path = os.path.join(
|
|
70
|
+
pdf_samples,
|
|
71
|
+
"simple",
|
|
72
|
+
"max_length_text_field_related",
|
|
73
|
+
"max_length_text_field_even_chars.pdf",
|
|
74
|
+
)
|
|
75
|
+
with open(expected_path, "rb+") as f:
|
|
76
|
+
obj = FormWrapper(sample_template_with_max_length_text_field).fill(
|
|
77
|
+
{
|
|
78
|
+
"FirstName": "John",
|
|
79
|
+
"MiddleName": "Joe",
|
|
80
|
+
"LastName": "XXXX",
|
|
81
|
+
"Awesomeness": True,
|
|
82
|
+
"Gender": 0,
|
|
83
|
+
}
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
request.config.results["expected_path"] = expected_path
|
|
87
|
+
request.config.results["stream"] = obj.read()
|
|
88
|
+
|
|
89
|
+
expected = f.read()
|
|
90
|
+
|
|
91
|
+
assert len(obj.stream) == len(expected)
|
|
92
|
+
assert obj.stream == expected
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
from PyPDFForm import FormWrapper
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_fill(template_stream, pdf_samples, data_dict, request):
|
|
9
|
+
expected_path = os.path.join(pdf_samples, "simple", "sample_filled.pdf")
|
|
10
|
+
with open(expected_path, "rb+") as f:
|
|
11
|
+
obj = FormWrapper(template_stream).fill(data_dict)
|
|
12
|
+
|
|
13
|
+
request.config.results["expected_path"] = expected_path
|
|
14
|
+
request.config.results["stream"] = obj.read()
|
|
15
|
+
|
|
16
|
+
expected = f.read()
|
|
17
|
+
|
|
18
|
+
assert len(obj.stream) == len(expected)
|
|
19
|
+
assert obj.stream == expected
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def test_fill_radiobutton(pdf_samples, template_with_radiobutton_stream, request):
|
|
23
|
+
expected_path = os.path.join(pdf_samples, "simple", "sample_filled_radiobutton.pdf")
|
|
24
|
+
with open(expected_path, "rb+") as f:
|
|
25
|
+
obj = FormWrapper(template_with_radiobutton_stream).fill(
|
|
26
|
+
{
|
|
27
|
+
"radio_1": 0,
|
|
28
|
+
"radio_2": 1,
|
|
29
|
+
"radio_3": 2,
|
|
30
|
+
},
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
request.config.results["expected_path"] = expected_path
|
|
34
|
+
request.config.results["stream"] = obj.read()
|
|
35
|
+
|
|
36
|
+
expected = f.read()
|
|
37
|
+
|
|
38
|
+
assert len(obj.read()) == len(expected)
|
|
39
|
+
assert obj.stream == expected
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_fill_right_aligned(
|
|
43
|
+
sample_template_with_right_aligned_text_field, pdf_samples, request
|
|
44
|
+
):
|
|
45
|
+
expected_path = os.path.join(
|
|
46
|
+
pdf_samples, "simple", "sample_filled_right_aligned.pdf"
|
|
47
|
+
)
|
|
48
|
+
with open(expected_path, "rb+") as f:
|
|
49
|
+
obj = FormWrapper(sample_template_with_right_aligned_text_field).fill(
|
|
50
|
+
{
|
|
51
|
+
"name": "Hans Mustermann",
|
|
52
|
+
"fulladdress": "Musterstr. 12, 82903 Musterdorf, Musterland",
|
|
53
|
+
"advisorname": "Karl Test",
|
|
54
|
+
},
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
request.config.results["expected_path"] = expected_path
|
|
58
|
+
request.config.results["stream"] = obj.read()
|
|
59
|
+
|
|
60
|
+
expected = f.read()
|
|
61
|
+
|
|
62
|
+
assert len(obj.read()) == len(expected)
|
|
63
|
+
assert obj.stream == expected
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_fill_font_color(sample_template_with_font_colors, pdf_samples, request):
|
|
67
|
+
expected_path = os.path.join(pdf_samples, "simple", "test_fill_font_color.pdf")
|
|
68
|
+
with open(expected_path, "rb+") as f:
|
|
69
|
+
obj = FormWrapper(sample_template_with_font_colors).fill(
|
|
70
|
+
{
|
|
71
|
+
"red_12": "red",
|
|
72
|
+
"green_14": "green",
|
|
73
|
+
"blue_16": "blue",
|
|
74
|
+
"mixed_auto": "mixed",
|
|
75
|
+
},
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
request.config.results["expected_path"] = expected_path
|
|
79
|
+
request.config.results["stream"] = obj.read()
|
|
80
|
+
|
|
81
|
+
expected = f.read()
|
|
82
|
+
|
|
83
|
+
if os.name != "nt":
|
|
84
|
+
assert len(obj.read()) == len(expected)
|
|
85
|
+
assert obj.stream == expected
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def test_fill_complex_fonts(sample_template_with_complex_fonts, pdf_samples, request):
|
|
89
|
+
expected_path = os.path.join(pdf_samples, "simple", "test_fill_complex_fonts.pdf")
|
|
90
|
+
with open(expected_path, "rb+") as f:
|
|
91
|
+
obj = FormWrapper(sample_template_with_complex_fonts).fill(
|
|
92
|
+
{
|
|
93
|
+
"Courier": "Test",
|
|
94
|
+
"Courier-Bold": "Test",
|
|
95
|
+
"Courier-BoldOblique": "Test",
|
|
96
|
+
"Courier-Oblique": "Test",
|
|
97
|
+
"Helvetica": "Test",
|
|
98
|
+
"Helvetica-Bold": "Test",
|
|
99
|
+
"Helvetica-BoldOblique": "Test",
|
|
100
|
+
"Helvetica-Oblique": "Test",
|
|
101
|
+
"Times-Bold": "Test",
|
|
102
|
+
"Times-BoldItalic": "Test",
|
|
103
|
+
"Times-Italic": "Test",
|
|
104
|
+
"Times-Roman": "Test",
|
|
105
|
+
},
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
request.config.results["expected_path"] = expected_path
|
|
109
|
+
request.config.results["stream"] = obj.read()
|
|
110
|
+
|
|
111
|
+
expected = f.read()
|
|
112
|
+
|
|
113
|
+
if os.name != "nt":
|
|
114
|
+
assert len(obj.read()) == len(expected)
|
|
115
|
+
assert obj.stream == expected
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# pylint: disable=line-too-long
|
|
3
|
+
|
|
4
|
+
import os
|
|
5
|
+
|
|
6
|
+
from PyPDFForm import FormWrapper
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def test_paragraph_y_coordinate(sample_template_with_paragraph, pdf_samples, request):
|
|
10
|
+
expected_path = os.path.join(
|
|
11
|
+
pdf_samples, "simple", "paragraph", "test_paragraph_y_coordinate.pdf"
|
|
12
|
+
)
|
|
13
|
+
with open(expected_path, "rb+") as f:
|
|
14
|
+
obj = FormWrapper(sample_template_with_paragraph).fill(
|
|
15
|
+
{"paragraph_1": "test paragraph"}
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
request.config.results["expected_path"] = expected_path
|
|
19
|
+
request.config.results["stream"] = obj.read()
|
|
20
|
+
|
|
21
|
+
expected = f.read()
|
|
22
|
+
|
|
23
|
+
assert len(obj.read()) == len(expected)
|
|
24
|
+
assert obj.stream == expected
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def test_paragraph_auto_wrap(sample_template_with_paragraph, pdf_samples, request):
|
|
28
|
+
expected_path = os.path.join(
|
|
29
|
+
pdf_samples, "simple", "paragraph", "test_paragraph_auto_wrap.pdf"
|
|
30
|
+
)
|
|
31
|
+
with open(expected_path, "rb+") as f:
|
|
32
|
+
obj = FormWrapper(sample_template_with_paragraph).fill(
|
|
33
|
+
{
|
|
34
|
+
"paragraph_1": "t xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx t"
|
|
35
|
+
}
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
request.config.results["expected_path"] = expected_path
|
|
39
|
+
request.config.results["stream"] = obj.read()
|
|
40
|
+
|
|
41
|
+
expected = f.read()
|
|
42
|
+
|
|
43
|
+
assert len(obj.read()) == len(expected)
|
|
44
|
+
assert obj.stream == expected
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def test_paragraph_auto_font(
|
|
48
|
+
sample_template_with_paragraph_auto_font, pdf_samples, request
|
|
49
|
+
):
|
|
50
|
+
expected_path = os.path.join(
|
|
51
|
+
pdf_samples, "simple", "paragraph", "test_paragraph_auto_font.pdf"
|
|
52
|
+
)
|
|
53
|
+
with open(expected_path, "rb+") as f:
|
|
54
|
+
obj = FormWrapper(sample_template_with_paragraph_auto_font).fill(
|
|
55
|
+
{"paragraph": "test paragraph"}
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
request.config.results["expected_path"] = expected_path
|
|
59
|
+
request.config.results["stream"] = obj.read()
|
|
60
|
+
|
|
61
|
+
expected = f.read()
|
|
62
|
+
|
|
63
|
+
if os.name != "nt":
|
|
64
|
+
assert len(obj.read()) == len(expected)
|
|
65
|
+
assert obj.stream == expected
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def test_paragraph_auto_font_auto_wrap(
|
|
69
|
+
sample_template_with_paragraph_auto_font, pdf_samples, request
|
|
70
|
+
):
|
|
71
|
+
expected_path = os.path.join(
|
|
72
|
+
pdf_samples, "simple", "paragraph", "test_paragraph_auto_font_auto_wrap.pdf"
|
|
73
|
+
)
|
|
74
|
+
with open(expected_path, "rb+") as f:
|
|
75
|
+
obj = FormWrapper(sample_template_with_paragraph_auto_font).fill(
|
|
76
|
+
{
|
|
77
|
+
"paragraph": "t xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx t"
|
|
78
|
+
}
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
request.config.results["expected_path"] = expected_path
|
|
82
|
+
request.config.results["stream"] = obj.read()
|
|
83
|
+
|
|
84
|
+
expected = f.read()
|
|
85
|
+
|
|
86
|
+
if os.name != "nt":
|
|
87
|
+
assert len(obj.read()) == len(expected)
|
|
88
|
+
assert obj.stream == expected
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def test_paragraph_complex(sample_template_paragraph_complex, pdf_samples, request):
|
|
92
|
+
expected_path = os.path.join(
|
|
93
|
+
pdf_samples, "simple", "paragraph", "test_paragraph_complex.pdf"
|
|
94
|
+
)
|
|
95
|
+
with open(expected_path, "rb+") as f:
|
|
96
|
+
obj = FormWrapper(sample_template_paragraph_complex).fill(
|
|
97
|
+
{
|
|
98
|
+
"paragraph_font_auto_left": "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
|
|
99
|
+
"paragraph_font_auto_right": "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
|
|
100
|
+
"paragraph_font_auto_center": "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
|
|
101
|
+
"paragraph_font_ten_left": "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
|
|
102
|
+
"paragraph_font_ten_right": "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
|
|
103
|
+
"paragraph_font_ten_center": "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
|
|
104
|
+
}
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
request.config.results["expected_path"] = expected_path
|
|
108
|
+
request.config.results["stream"] = obj.read()
|
|
109
|
+
|
|
110
|
+
expected = f.read()
|
|
111
|
+
|
|
112
|
+
if os.name != "nt":
|
|
113
|
+
assert len(obj.read()) == len(expected)
|
|
114
|
+
assert obj.stream == expected
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def test_paragraph_max_length(
|
|
118
|
+
sample_template_with_paragraph_max_length, pdf_samples, request
|
|
119
|
+
):
|
|
120
|
+
expected_path = os.path.join(
|
|
121
|
+
pdf_samples, "simple", "paragraph", "test_paragraph_max_length.pdf"
|
|
122
|
+
)
|
|
123
|
+
with open(expected_path, "rb+") as f:
|
|
124
|
+
obj = FormWrapper(sample_template_with_paragraph_max_length).fill(
|
|
125
|
+
{
|
|
126
|
+
"paragraph": "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
|
|
127
|
+
}
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
request.config.results["expected_path"] = expected_path
|
|
131
|
+
request.config.results["stream"] = obj.read()
|
|
132
|
+
|
|
133
|
+
expected = f.read()
|
|
134
|
+
|
|
135
|
+
if os.name != "nt":
|
|
136
|
+
assert len(obj.read()) == len(expected)
|
|
137
|
+
assert obj.stream == expected
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|