PyPDFForm 1.4.32__tar.gz → 1.4.34__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.32 → pypdfform-1.4.34}/PKG-INFO +1 -1
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/__init__.py +1 -1
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/image.py +1 -1
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/middleware/dropdown.py +1 -1
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/middleware/radio.py +1 -1
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/middleware/text.py +3 -1
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/patterns.py +15 -3
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/widgets/base.py +3 -1
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/widgets/text.py +1 -1
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm.egg-info/PKG-INFO +1 -1
- {pypdfform-1.4.32 → pypdfform-1.4.34}/tests/test_create_widget.py +24 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/tests/test_dropdown.py +4 -2
- {pypdfform-1.4.32 → pypdfform-1.4.34}/tests/test_functional.py +11 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/LICENSE +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/adapter.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/constants.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/coordinate.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/filler.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/font.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/middleware/__init__.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/middleware/base.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/middleware/checkbox.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/middleware/image.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/middleware/signature.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/template.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/utils.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/watermark.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/widgets/__init__.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/widgets/checkbox.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/widgets/dropdown.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm/wrapper.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm.egg-info/SOURCES.txt +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm.egg-info/dependency_links.txt +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm.egg-info/requires.txt +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/PyPDFForm.egg-info/top_level.txt +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/README.md +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/setup.cfg +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/setup.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/tests/test_adobe_mode.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/tests/test_dropdown_simple.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/tests/test_fill_max_length_text_field.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/tests/test_fill_max_length_text_field_simple.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/tests/test_functional_simple.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/tests/test_paragraph.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/tests/test_paragraph_simple.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/tests/test_preview.py +0 -0
- {pypdfform-1.4.32 → pypdfform-1.4.34}/tests/test_signature.py +0 -0
|
@@ -42,7 +42,7 @@ def any_image_to_jpg(image_stream: bytes) -> bytes:
|
|
|
42
42
|
return image_stream
|
|
43
43
|
|
|
44
44
|
rgb_image = Image.new("RGB", image.size, (255, 255, 255))
|
|
45
|
-
rgb_image.paste(image, mask=image.split()[3])
|
|
45
|
+
rgb_image.paste(image, mask=image.split()[3] if len(image.split()) == 4 else None)
|
|
46
46
|
|
|
47
47
|
with BytesIO() as _file:
|
|
48
48
|
rgb_image.save(_file, format="JPEG")
|
|
@@ -5,8 +5,8 @@ from pypdf.generic import (DictionaryObject, NameObject, NumberObject,
|
|
|
5
5
|
TextStringObject)
|
|
6
6
|
|
|
7
7
|
from .constants import (AP, AS, CA, DA, DV, FT, IMAGE_FIELD_IDENTIFIER, JS, MK,
|
|
8
|
-
READ_ONLY, A, Btn, Ch, Ff, N, Off, Opt,
|
|
9
|
-
T, Tx, V, Yes)
|
|
8
|
+
MULTILINE, READ_ONLY, A, Btn, Ch, Ff, N, Off, Opt,
|
|
9
|
+
Parent, Q, Sig, T, Tx, V, Yes)
|
|
10
10
|
from .middleware.checkbox import Checkbox
|
|
11
11
|
from .middleware.dropdown import Dropdown
|
|
12
12
|
from .middleware.image import Image
|
|
@@ -166,4 +166,16 @@ def update_created_text_field_alignment(annot: DictionaryObject, val: int) -> No
|
|
|
166
166
|
annot[NameObject(Q)] = NumberObject(val)
|
|
167
167
|
|
|
168
168
|
|
|
169
|
-
|
|
169
|
+
def update_created_text_field_multiline(annot: DictionaryObject, val: bool) -> None:
|
|
170
|
+
"""Patterns to update to multiline for text annotations created by the library."""
|
|
171
|
+
|
|
172
|
+
if val:
|
|
173
|
+
annot[NameObject(Ff)] = NumberObject(
|
|
174
|
+
int(annot[NameObject(Ff)]) | MULTILINE # noqa
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
NON_ACRO_FORM_PARAM_TO_FUNC = {
|
|
179
|
+
("TextWidget", "alignment"): update_created_text_field_alignment,
|
|
180
|
+
("TextWidget", "multiline"): update_created_text_field_multiline,
|
|
181
|
+
}
|
|
@@ -59,7 +59,9 @@ class Widget:
|
|
|
59
59
|
|
|
60
60
|
for each in self.ALLOWED_NON_ACRO_FORM_PARAMS:
|
|
61
61
|
if each in kwargs:
|
|
62
|
-
self.non_acro_form_params.append(
|
|
62
|
+
self.non_acro_form_params.append(
|
|
63
|
+
((type(self).__name__, each), kwargs.get(each))
|
|
64
|
+
)
|
|
63
65
|
|
|
64
66
|
def watermarks(self, stream: bytes) -> List[bytes]:
|
|
65
67
|
"""Returns a list of watermarks after creating the widget."""
|
|
@@ -19,6 +19,6 @@ class TextWidget(Widget):
|
|
|
19
19
|
("max_length", "maxlen"),
|
|
20
20
|
]
|
|
21
21
|
COLOR_PARAMS = ["font_color", "bg_color", "border_color"]
|
|
22
|
-
ALLOWED_NON_ACRO_FORM_PARAMS = ["alignment"]
|
|
22
|
+
ALLOWED_NON_ACRO_FORM_PARAMS = ["alignment", "multiline"]
|
|
23
23
|
NONE_DEFAULTS = ["max_length"]
|
|
24
24
|
ACRO_FORM_FUNC = "textfield"
|
|
@@ -242,6 +242,30 @@ def test_create_text_align_right(template_stream, pdf_samples, request):
|
|
|
242
242
|
assert obj.stream == expected
|
|
243
243
|
|
|
244
244
|
|
|
245
|
+
def test_create_text_align_multiline(template_stream, pdf_samples, request):
|
|
246
|
+
expected_path = os.path.join(
|
|
247
|
+
pdf_samples, "widget", "create_text_align_multiline.pdf"
|
|
248
|
+
)
|
|
249
|
+
with open(expected_path, "rb+") as f:
|
|
250
|
+
obj = PdfWrapper(template_stream).create_widget(
|
|
251
|
+
"text",
|
|
252
|
+
"foo",
|
|
253
|
+
1,
|
|
254
|
+
100,
|
|
255
|
+
100,
|
|
256
|
+
multiline=True,
|
|
257
|
+
)
|
|
258
|
+
assert obj.schema["properties"]["foo"]["type"] == "string"
|
|
259
|
+
|
|
260
|
+
request.config.results["expected_path"] = expected_path
|
|
261
|
+
request.config.results["stream"] = obj.read()
|
|
262
|
+
|
|
263
|
+
expected = f.read()
|
|
264
|
+
|
|
265
|
+
assert len(obj.stream) == len(expected)
|
|
266
|
+
assert obj.stream == expected
|
|
267
|
+
|
|
268
|
+
|
|
245
269
|
def test_create_text_default_filled(template_stream, pdf_samples, request):
|
|
246
270
|
expected_path = os.path.join(
|
|
247
271
|
pdf_samples, "widget", "create_text_default_filled.pdf"
|
|
@@ -6,12 +6,14 @@ from PyPDFForm import PdfWrapper
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def test_schema(sample_template_with_dropdown):
|
|
9
|
-
|
|
9
|
+
obj = PdfWrapper(sample_template_with_dropdown)
|
|
10
10
|
|
|
11
|
-
for key, value in schema["properties"].items():
|
|
11
|
+
for key, value in obj.schema["properties"].items():
|
|
12
12
|
if key == "dropdown_1":
|
|
13
13
|
assert value["maximum"] == 3
|
|
14
14
|
|
|
15
|
+
assert obj.sample_data["dropdown_1"] == 3
|
|
16
|
+
|
|
15
17
|
|
|
16
18
|
def test_dropdown_not_specified(sample_template_with_dropdown):
|
|
17
19
|
assert (
|
|
@@ -406,6 +406,17 @@ def test_sample_data(sejda_template_complex):
|
|
|
406
406
|
pass
|
|
407
407
|
|
|
408
408
|
|
|
409
|
+
def test_sample_data_max_boundary(sample_template_with_comb_text_field):
|
|
410
|
+
obj = PdfWrapper(sample_template_with_comb_text_field)
|
|
411
|
+
try:
|
|
412
|
+
validate(instance=obj.sample_data, schema=obj.schema)
|
|
413
|
+
except ValidationError:
|
|
414
|
+
raise AssertionError from ValidationError
|
|
415
|
+
|
|
416
|
+
assert obj.sample_data["LastName"] == "LastNam"
|
|
417
|
+
assert obj.sample_data["Gender"] == 1
|
|
418
|
+
|
|
419
|
+
|
|
409
420
|
def test_fill_right_aligned(
|
|
410
421
|
sample_template_with_right_aligned_text_field, pdf_samples, request
|
|
411
422
|
):
|
|
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
|
|
File without changes
|