PyPDFForm 1.4.15__tar.gz → 1.4.17__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.15 → PyPDFForm-1.4.17}/PKG-INFO +1 -1
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm/__init__.py +1 -1
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm/constants.py +2 -2
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm/filler.py +1 -1
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm/patterns.py +35 -12
- PyPDFForm-1.4.17/PyPDFForm/widgets/dropdown.py +33 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm/wrapper.py +4 -1
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm.egg-info/PKG-INFO +1 -1
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm.egg-info/SOURCES.txt +1 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/tests/test_create_widget.py +31 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/tests/test_dropdown_simple.py +1 -1
- PyPDFForm-1.4.17/tests/test_fill_max_length_text_field_simple.py +208 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/tests/test_functional_simple.py +14 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/tests/test_paragraph_simple.py +109 -0
- PyPDFForm-1.4.15/tests/test_fill_max_length_text_field_simple.py +0 -92
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/LICENSE +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm/adapter.py +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm/coordinate.py +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm/font.py +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm/image.py +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm/middleware/__init__.py +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm/middleware/base.py +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm/middleware/checkbox.py +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm/middleware/dropdown.py +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm/middleware/radio.py +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm/middleware/signature.py +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm/middleware/text.py +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm/template.py +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm/utils.py +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm/watermark.py +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm/widgets/__init__.py +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm/widgets/base.py +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm/widgets/checkbox.py +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm/widgets/text.py +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm.egg-info/dependency_links.txt +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm.egg-info/requires.txt +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/PyPDFForm.egg-info/top_level.txt +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/README.md +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/setup.cfg +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/setup.py +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/tests/test_dropdown.py +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/tests/test_fill_max_length_text_field.py +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/tests/test_functional.py +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/tests/test_paragraph.py +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/tests/test_preview.py +0 -0
- {PyPDFForm-1.4.15 → PyPDFForm-1.4.17}/tests/test_signature.py +0 -0
|
@@ -37,6 +37,7 @@ Ff = "/Ff"
|
|
|
37
37
|
Tx = "/Tx"
|
|
38
38
|
V = "/V"
|
|
39
39
|
AP = "/AP"
|
|
40
|
+
D = "/D"
|
|
40
41
|
Sig = "/Sig"
|
|
41
42
|
DA = "/DA"
|
|
42
43
|
Btn = "/Btn"
|
|
@@ -47,6 +48,7 @@ Opt = "/Opt"
|
|
|
47
48
|
MK = "/MK"
|
|
48
49
|
CA = "/CA"
|
|
49
50
|
AS = "/AS"
|
|
51
|
+
Off = "/Off"
|
|
50
52
|
|
|
51
53
|
# Field flag bits
|
|
52
54
|
READ_ONLY = 1 << 0
|
|
@@ -70,6 +72,4 @@ BUTTON_STYLES = {
|
|
|
70
72
|
"l": "\u25CF", # circle
|
|
71
73
|
}
|
|
72
74
|
|
|
73
|
-
Yes = "/Yes"
|
|
74
|
-
|
|
75
75
|
COORDINATE_GRID_FONT_SIZE_MARGIN_RATIO = DEFAULT_FONT_SIZE / 100
|
|
@@ -158,7 +158,7 @@ def simple_fill(
|
|
|
158
158
|
radio_button_tracker[key] = 0
|
|
159
159
|
radio_button_tracker[key] += 1
|
|
160
160
|
if widget.value == radio_button_tracker[key] - 1:
|
|
161
|
-
simple_update_radio_value(annot
|
|
161
|
+
simple_update_radio_value(annot)
|
|
162
162
|
elif isinstance(widget, Dropdown) and widget.value is not None:
|
|
163
163
|
simple_update_dropdown_value(annot, widget)
|
|
164
164
|
elif isinstance(widget, Text) and widget.value:
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
from pypdf.generic import (DictionaryObject, NameObject, NumberObject,
|
|
5
5
|
TextStringObject)
|
|
6
6
|
|
|
7
|
-
from .constants import (AP, AS, CA, DA, FT, MK, READ_ONLY, Btn, Ch, Ff,
|
|
8
|
-
Parent, Q, Sig, Subtype, T, Tx, V, Widget
|
|
7
|
+
from .constants import (AP, AS, CA, DA, FT, MK, READ_ONLY, Btn, Ch, D, Ff, Off,
|
|
8
|
+
Opt, Parent, Q, Sig, Subtype, T, Tx, V, Widget)
|
|
9
9
|
from .middleware.checkbox import Checkbox
|
|
10
10
|
from .middleware.dropdown import Dropdown
|
|
11
11
|
from .middleware.radio import Radio
|
|
@@ -83,27 +83,45 @@ BUTTON_STYLE_PATTERNS = [
|
|
|
83
83
|
def simple_update_checkbox_value(annot: DictionaryObject) -> None:
|
|
84
84
|
"""Patterns to update values for checkbox annotations."""
|
|
85
85
|
|
|
86
|
-
annot[
|
|
86
|
+
for each in annot[AP][D]: # noqa
|
|
87
|
+
if str(each) != Off:
|
|
88
|
+
annot[NameObject(AS)] = NameObject(each)
|
|
89
|
+
break
|
|
87
90
|
|
|
88
91
|
|
|
89
|
-
def simple_update_radio_value(annot: DictionaryObject
|
|
92
|
+
def simple_update_radio_value(annot: DictionaryObject) -> None:
|
|
90
93
|
"""Patterns to update values for radio annotations."""
|
|
91
94
|
|
|
92
|
-
annot[
|
|
95
|
+
for each in annot[AP][D]: # noqa
|
|
96
|
+
if str(each) != Off:
|
|
97
|
+
annot[NameObject(AS)] = NameObject(each)
|
|
98
|
+
break
|
|
93
99
|
|
|
94
100
|
|
|
95
101
|
def simple_update_dropdown_value(annot: DictionaryObject, widget: Dropdown) -> None:
|
|
96
102
|
"""Patterns to update values for dropdown annotations."""
|
|
97
103
|
|
|
98
|
-
annot
|
|
99
|
-
|
|
104
|
+
if Parent in annot and T not in annot:
|
|
105
|
+
annot[NameObject(Parent)][NameObject(V)] = TextStringObject( # noqa
|
|
106
|
+
widget.choices[widget.value]
|
|
107
|
+
)
|
|
108
|
+
annot[NameObject(AP)] = TextStringObject(widget.choices[widget.value])
|
|
109
|
+
else:
|
|
110
|
+
annot[NameObject(V)] = TextStringObject(widget.choices[widget.value])
|
|
111
|
+
annot[NameObject(AP)] = TextStringObject(widget.choices[widget.value])
|
|
100
112
|
|
|
101
113
|
|
|
102
114
|
def simple_update_text_value(annot: DictionaryObject, widget: Text) -> None:
|
|
103
115
|
"""Patterns to update values for text annotations."""
|
|
104
116
|
|
|
105
|
-
annot
|
|
106
|
-
|
|
117
|
+
if Parent in annot and T not in annot:
|
|
118
|
+
annot[NameObject(Parent)][NameObject(V)] = TextStringObject( # noqa
|
|
119
|
+
widget.value
|
|
120
|
+
)
|
|
121
|
+
annot[NameObject(AP)] = TextStringObject(widget.value)
|
|
122
|
+
else:
|
|
123
|
+
annot[NameObject(V)] = TextStringObject(widget.value)
|
|
124
|
+
annot[NameObject(AP)] = TextStringObject(widget.value)
|
|
107
125
|
|
|
108
126
|
|
|
109
127
|
def simple_flatten_radio(annot: DictionaryObject) -> None:
|
|
@@ -117,6 +135,11 @@ def simple_flatten_radio(annot: DictionaryObject) -> None:
|
|
|
117
135
|
def simple_flatten_generic(annot: DictionaryObject) -> None:
|
|
118
136
|
"""Patterns to flatten generic annotations."""
|
|
119
137
|
|
|
120
|
-
annot
|
|
121
|
-
|
|
122
|
-
|
|
138
|
+
if Parent in annot and Ff not in annot:
|
|
139
|
+
annot[NameObject(Parent)][NameObject(Ff)] = NumberObject( # noqa
|
|
140
|
+
int(annot.get(NameObject(Ff), 0)) | READ_ONLY # noqa
|
|
141
|
+
)
|
|
142
|
+
else:
|
|
143
|
+
annot[NameObject(Ff)] = NumberObject(
|
|
144
|
+
int(annot.get(NameObject(Ff), 0)) | READ_ONLY # noqa
|
|
145
|
+
)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""Contains dropdown widget to create."""
|
|
3
|
+
|
|
4
|
+
from .base import Widget
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class DropdownWidget(Widget):
|
|
8
|
+
"""Dropdown widget to create."""
|
|
9
|
+
|
|
10
|
+
USER_PARAMS = [
|
|
11
|
+
("width", "width"),
|
|
12
|
+
("height", "height"),
|
|
13
|
+
("options", "options"),
|
|
14
|
+
("font", "fontName"),
|
|
15
|
+
("font_size", "fontSize"),
|
|
16
|
+
("font_color", "textColor"),
|
|
17
|
+
]
|
|
18
|
+
COLOR_PARAMS = ["font_color"]
|
|
19
|
+
ACRO_FORM_FUNC = "_textfield"
|
|
20
|
+
|
|
21
|
+
def __init__(
|
|
22
|
+
self,
|
|
23
|
+
name: str,
|
|
24
|
+
page_number: int,
|
|
25
|
+
x: float,
|
|
26
|
+
y: float,
|
|
27
|
+
**kwargs,
|
|
28
|
+
) -> None:
|
|
29
|
+
"""Sets acro form parameters."""
|
|
30
|
+
|
|
31
|
+
super().__init__(name, page_number, x, y, **kwargs)
|
|
32
|
+
self.acro_form_params["wkind"] = "choice"
|
|
33
|
+
self.acro_form_params["value"] = self.acro_form_params["options"][0]
|
|
@@ -23,6 +23,7 @@ from .utils import (get_page_streams, merge_two_pdfs, preview_widget_to_draw,
|
|
|
23
23
|
remove_all_widgets)
|
|
24
24
|
from .watermark import create_watermarks_and_draw, merge_watermarks_with_pdf
|
|
25
25
|
from .widgets.checkbox import CheckBoxWidget
|
|
26
|
+
from .widgets.dropdown import DropdownWidget
|
|
26
27
|
from .widgets.text import TextWidget
|
|
27
28
|
|
|
28
29
|
|
|
@@ -218,6 +219,8 @@ class PdfWrapper(FormWrapper):
|
|
|
218
219
|
_class = TextWidget
|
|
219
220
|
if widget_type == "checkbox":
|
|
220
221
|
_class = CheckBoxWidget
|
|
222
|
+
if widget_type == "dropdown":
|
|
223
|
+
_class = DropdownWidget
|
|
221
224
|
if _class is None:
|
|
222
225
|
return self
|
|
223
226
|
|
|
@@ -231,7 +234,7 @@ class PdfWrapper(FormWrapper):
|
|
|
231
234
|
if k in new_widgets:
|
|
232
235
|
new_widgets[k] = v
|
|
233
236
|
self.widgets = new_widgets
|
|
234
|
-
if widget_type
|
|
237
|
+
if widget_type in ("text", "dropdown"):
|
|
235
238
|
self.widgets[name].font = self.global_font
|
|
236
239
|
self.widgets[name].font_size = self.global_font_size
|
|
237
240
|
self.widgets[name].font_color = self.global_font_color
|
|
@@ -342,3 +342,34 @@ def test_create_widget_sejda_schema(sejda_template):
|
|
|
342
342
|
|
|
343
343
|
assert schema["properties"]["new_text_field_widget"]
|
|
344
344
|
assert len(schema["properties"]) == 1
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
def test_create_dropdown(template_stream, pdf_samples, request):
|
|
348
|
+
expected_path = os.path.join(pdf_samples, "widget", "create_dropdown.pdf")
|
|
349
|
+
with open(expected_path, "rb+") as f:
|
|
350
|
+
obj = PdfWrapper(template_stream).create_widget(
|
|
351
|
+
widget_type="dropdown",
|
|
352
|
+
name="new_dropdown_widget",
|
|
353
|
+
page_number=1,
|
|
354
|
+
x=57,
|
|
355
|
+
y=700,
|
|
356
|
+
options=[
|
|
357
|
+
"foo",
|
|
358
|
+
"bar",
|
|
359
|
+
"foobar",
|
|
360
|
+
],
|
|
361
|
+
width=120,
|
|
362
|
+
height=40,
|
|
363
|
+
font="Courier",
|
|
364
|
+
font_size=15,
|
|
365
|
+
font_color=(1, 0, 0),
|
|
366
|
+
)
|
|
367
|
+
assert obj.schema["properties"]["new_dropdown_widget"]["type"] == "integer"
|
|
368
|
+
|
|
369
|
+
request.config.results["expected_path"] = expected_path
|
|
370
|
+
request.config.results["stream"] = obj.read()
|
|
371
|
+
|
|
372
|
+
expected = f.read()
|
|
373
|
+
|
|
374
|
+
assert len(obj.stream) == len(expected)
|
|
375
|
+
assert obj.stream == expected
|
|
@@ -73,7 +73,7 @@ def test_dropdown_two(sample_template_with_dropdown, pdf_samples, request):
|
|
|
73
73
|
assert obj.stream == expected
|
|
74
74
|
|
|
75
75
|
|
|
76
|
-
def
|
|
76
|
+
def test_dropdown_two_flatten(sample_template_with_dropdown, pdf_samples, request):
|
|
77
77
|
expected_path = os.path.join(
|
|
78
78
|
pdf_samples, "simple", "dropdown", "dropdown_two_simple.pdf"
|
|
79
79
|
)
|
|
@@ -0,0 +1,208 @@
|
|
|
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
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def test_fill_comb_text_field_all_chars(
|
|
96
|
+
sample_template_with_comb_text_field, pdf_samples, request
|
|
97
|
+
):
|
|
98
|
+
expected_path = os.path.join(
|
|
99
|
+
pdf_samples,
|
|
100
|
+
"simple",
|
|
101
|
+
"max_length_text_field_related",
|
|
102
|
+
"comb_text_field_all_chars.pdf",
|
|
103
|
+
)
|
|
104
|
+
with open(expected_path, "rb+") as f:
|
|
105
|
+
obj = FormWrapper(sample_template_with_comb_text_field).fill(
|
|
106
|
+
{
|
|
107
|
+
"FirstName": "John",
|
|
108
|
+
"MiddleName": "Joe",
|
|
109
|
+
"LastName": "XXXXXXXXXX",
|
|
110
|
+
"Awesomeness": True,
|
|
111
|
+
"Gender": 0,
|
|
112
|
+
}
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
request.config.results["expected_path"] = expected_path
|
|
116
|
+
request.config.results["stream"] = obj.read()
|
|
117
|
+
|
|
118
|
+
expected = f.read()
|
|
119
|
+
|
|
120
|
+
assert len(obj.stream) == len(expected)
|
|
121
|
+
assert obj.stream == expected
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def test_fill_comb_text_field_odd_chars(
|
|
125
|
+
sample_template_with_comb_text_field, pdf_samples, request
|
|
126
|
+
):
|
|
127
|
+
expected_path = os.path.join(
|
|
128
|
+
pdf_samples,
|
|
129
|
+
"simple",
|
|
130
|
+
"max_length_text_field_related",
|
|
131
|
+
"comb_text_field_odd_chars.pdf",
|
|
132
|
+
)
|
|
133
|
+
with open(expected_path, "rb+") as f:
|
|
134
|
+
obj = FormWrapper(sample_template_with_comb_text_field).fill(
|
|
135
|
+
{
|
|
136
|
+
"FirstName": "John",
|
|
137
|
+
"MiddleName": "Joe",
|
|
138
|
+
"LastName": "XXX",
|
|
139
|
+
"Awesomeness": True,
|
|
140
|
+
"Gender": 0,
|
|
141
|
+
}
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
request.config.results["expected_path"] = expected_path
|
|
145
|
+
request.config.results["stream"] = obj.read()
|
|
146
|
+
|
|
147
|
+
expected = f.read()
|
|
148
|
+
|
|
149
|
+
assert len(obj.stream) == len(expected)
|
|
150
|
+
assert obj.stream == expected
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def test_fill_comb_text_field_even_chars(
|
|
154
|
+
sample_template_with_comb_text_field, pdf_samples, request
|
|
155
|
+
):
|
|
156
|
+
expected_path = os.path.join(
|
|
157
|
+
pdf_samples,
|
|
158
|
+
"simple",
|
|
159
|
+
"max_length_text_field_related",
|
|
160
|
+
"comb_text_field_even_chars.pdf",
|
|
161
|
+
)
|
|
162
|
+
with open(expected_path, "rb+") as f:
|
|
163
|
+
obj = FormWrapper(sample_template_with_comb_text_field).fill(
|
|
164
|
+
{
|
|
165
|
+
"FirstName": "John",
|
|
166
|
+
"MiddleName": "Joe",
|
|
167
|
+
"LastName": "XXXXXX",
|
|
168
|
+
"Awesomeness": True,
|
|
169
|
+
"Gender": 0,
|
|
170
|
+
}
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
request.config.results["expected_path"] = expected_path
|
|
174
|
+
request.config.results["stream"] = obj.read()
|
|
175
|
+
|
|
176
|
+
expected = f.read()
|
|
177
|
+
|
|
178
|
+
assert len(obj.stream) == len(expected)
|
|
179
|
+
assert obj.stream == expected
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def test_fill_comb_text_field_even_chars_right_aligned(
|
|
183
|
+
sample_template_with_comb_text_field_right_aligned, pdf_samples, request
|
|
184
|
+
):
|
|
185
|
+
expected_path = os.path.join(
|
|
186
|
+
pdf_samples,
|
|
187
|
+
"simple",
|
|
188
|
+
"max_length_text_field_related",
|
|
189
|
+
"comb_text_field_even_chars_right_aligned.pdf",
|
|
190
|
+
)
|
|
191
|
+
with open(expected_path, "rb+") as f:
|
|
192
|
+
obj = FormWrapper(sample_template_with_comb_text_field_right_aligned).fill(
|
|
193
|
+
{
|
|
194
|
+
"FirstName": "John",
|
|
195
|
+
"MiddleName": "Joe",
|
|
196
|
+
"LastName": "XXXXXX",
|
|
197
|
+
"Awesomeness": True,
|
|
198
|
+
"Gender": 0,
|
|
199
|
+
}
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
request.config.results["expected_path"] = expected_path
|
|
203
|
+
request.config.results["stream"] = obj.read()
|
|
204
|
+
|
|
205
|
+
expected = f.read()
|
|
206
|
+
|
|
207
|
+
assert len(obj.stream) == len(expected)
|
|
208
|
+
assert obj.stream == expected
|
|
@@ -39,6 +39,20 @@ def test_fill_radiobutton(pdf_samples, template_with_radiobutton_stream, request
|
|
|
39
39
|
assert obj.stream == expected
|
|
40
40
|
|
|
41
41
|
|
|
42
|
+
def test_fill_sejda_and_read(pdf_samples, sejda_template, sejda_data, request):
|
|
43
|
+
expected_path = os.path.join(pdf_samples, "simple", "sample_filled_sejda.pdf")
|
|
44
|
+
with open(expected_path, "rb+") as f:
|
|
45
|
+
obj = FormWrapper(sejda_template).fill(sejda_data)
|
|
46
|
+
|
|
47
|
+
request.config.results["expected_path"] = expected_path
|
|
48
|
+
request.config.results["stream"] = obj.read()
|
|
49
|
+
|
|
50
|
+
expected = f.read()
|
|
51
|
+
|
|
52
|
+
assert len(obj.read()) == len(expected)
|
|
53
|
+
assert obj.stream == expected
|
|
54
|
+
|
|
55
|
+
|
|
42
56
|
def test_fill_right_aligned(
|
|
43
57
|
sample_template_with_right_aligned_text_field, pdf_samples, request
|
|
44
58
|
):
|
|
@@ -88,6 +88,115 @@ def test_paragraph_auto_font_auto_wrap(
|
|
|
88
88
|
assert obj.stream == expected
|
|
89
89
|
|
|
90
90
|
|
|
91
|
+
def test_fill_sejda_complex(sejda_template_complex, pdf_samples, request):
|
|
92
|
+
expected_path = os.path.join(
|
|
93
|
+
pdf_samples, "simple", "paragraph", "sample_filled_sejda_complex.pdf"
|
|
94
|
+
)
|
|
95
|
+
with open(expected_path, "rb+") as f:
|
|
96
|
+
obj = FormWrapper(sejda_template_complex).fill(
|
|
97
|
+
{
|
|
98
|
+
"checkbox": True,
|
|
99
|
+
"radio": 0,
|
|
100
|
+
"dropdown_font_auto_left": 0,
|
|
101
|
+
"dropdown_font_auto_center": 1,
|
|
102
|
+
"dropdown_font_auto_right": 2,
|
|
103
|
+
"dropdown_font_ten_left": 0,
|
|
104
|
+
"dropdown_font_ten_center": 1,
|
|
105
|
+
"dropdown_font_ten_right": 2,
|
|
106
|
+
"paragraph_font_auto_left": "paragraph_font_auto_left",
|
|
107
|
+
"paragraph_font_auto_center": "paragraph_font_auto_center",
|
|
108
|
+
"paragraph_font_auto_right": "paragraph_font_auto_right",
|
|
109
|
+
"paragraph_font_ten_left": "paragraph_font_ten_left",
|
|
110
|
+
"paragraph_font_ten_center": "paragraph_font_ten_center",
|
|
111
|
+
"paragraph_font_ten_right": "paragraph_font_ten_right",
|
|
112
|
+
"text__font_auto_left": "test text",
|
|
113
|
+
"text_font_auto_center": "test text",
|
|
114
|
+
"text_font_auto_right": "test text",
|
|
115
|
+
"text_font_ten_left": "text_font_ten_left",
|
|
116
|
+
"text_font_ten_center": "text_font_ten_center",
|
|
117
|
+
"text_font_ten_right": "text_font_ten_right",
|
|
118
|
+
}
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
request.config.results["expected_path"] = expected_path
|
|
122
|
+
request.config.results["stream"] = obj.read()
|
|
123
|
+
|
|
124
|
+
expected = f.read()
|
|
125
|
+
|
|
126
|
+
assert len(obj.read()) == len(expected)
|
|
127
|
+
assert obj.stream == expected
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def test_fill_sejda_complex_flatten(sejda_template_complex, pdf_samples, request):
|
|
131
|
+
expected_path = os.path.join(
|
|
132
|
+
pdf_samples, "simple", "paragraph", "sample_filled_sejda_complex_flatten.pdf"
|
|
133
|
+
)
|
|
134
|
+
with open(expected_path, "rb+") as f:
|
|
135
|
+
obj = FormWrapper(sejda_template_complex).fill(
|
|
136
|
+
{
|
|
137
|
+
"checkbox": True,
|
|
138
|
+
"radio": 0,
|
|
139
|
+
"dropdown_font_auto_left": 0,
|
|
140
|
+
"dropdown_font_auto_center": 1,
|
|
141
|
+
"dropdown_font_auto_right": 2,
|
|
142
|
+
"dropdown_font_ten_left": 0,
|
|
143
|
+
"dropdown_font_ten_center": 1,
|
|
144
|
+
"dropdown_font_ten_right": 2,
|
|
145
|
+
"paragraph_font_auto_left": "paragraph_font_auto_left",
|
|
146
|
+
"paragraph_font_auto_center": "paragraph_font_auto_center",
|
|
147
|
+
"paragraph_font_auto_right": "paragraph_font_auto_right",
|
|
148
|
+
"paragraph_font_ten_left": "paragraph_font_ten_left",
|
|
149
|
+
"paragraph_font_ten_center": "paragraph_font_ten_center",
|
|
150
|
+
"paragraph_font_ten_right": "paragraph_font_ten_right",
|
|
151
|
+
"text__font_auto_left": "test text",
|
|
152
|
+
"text_font_auto_center": "test text",
|
|
153
|
+
"text_font_auto_right": "test text",
|
|
154
|
+
"text_font_ten_left": "text_font_ten_left",
|
|
155
|
+
"text_font_ten_center": "text_font_ten_center",
|
|
156
|
+
"text_font_ten_right": "text_font_ten_right",
|
|
157
|
+
},
|
|
158
|
+
flatten=True,
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
request.config.results["expected_path"] = expected_path
|
|
162
|
+
request.config.results["stream"] = obj.read()
|
|
163
|
+
|
|
164
|
+
expected = f.read()
|
|
165
|
+
|
|
166
|
+
assert len(obj.read()) == len(expected)
|
|
167
|
+
assert obj.stream == expected
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def test_sejda_complex_paragraph_multiple_line_alignment(
|
|
171
|
+
sejda_template_complex, pdf_samples, request
|
|
172
|
+
):
|
|
173
|
+
expected_path = os.path.join(
|
|
174
|
+
pdf_samples,
|
|
175
|
+
"simple",
|
|
176
|
+
"paragraph",
|
|
177
|
+
"sample_filled_sejda_complex_paragraph_multiple_line_alignment.pdf",
|
|
178
|
+
)
|
|
179
|
+
with open(expected_path, "rb+") as f:
|
|
180
|
+
obj = FormWrapper(sejda_template_complex).fill(
|
|
181
|
+
{
|
|
182
|
+
"paragraph_font_auto_left": "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
|
|
183
|
+
"paragraph_font_auto_right": "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
|
|
184
|
+
"paragraph_font_auto_center": "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
|
|
185
|
+
"paragraph_font_ten_left": "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
|
|
186
|
+
"paragraph_font_ten_right": "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
|
|
187
|
+
"paragraph_font_ten_center": "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
|
|
188
|
+
}
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
request.config.results["expected_path"] = expected_path
|
|
192
|
+
request.config.results["stream"] = obj.read()
|
|
193
|
+
|
|
194
|
+
expected = f.read()
|
|
195
|
+
|
|
196
|
+
assert len(obj.read()) == len(expected)
|
|
197
|
+
assert obj.stream == expected
|
|
198
|
+
|
|
199
|
+
|
|
91
200
|
def test_paragraph_complex(sample_template_paragraph_complex, pdf_samples, request):
|
|
92
201
|
expected_path = os.path.join(
|
|
93
202
|
pdf_samples, "simple", "paragraph", "test_paragraph_complex.pdf"
|
|
@@ -1,92 +0,0 @@
|
|
|
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
|
|
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
|