Skip to content

Commit 52b6892

Browse files
Merge pull request #201 from chinapandaman/PPF-200
PPF-200: deprecate image fill
2 parents e7b901d + 7f7e7e2 commit 52b6892

19 files changed

+77
-830
lines changed

PyPDFForm/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
PyPDFForm = Wrapper
66

7-
__version__ = "0.3.4"
7+
__version__ = "0.3.5"

PyPDFForm/core/filler.py

+51-122
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,15 @@ def fill(template_stream: bytes, elements: Dict[str, "ElementMiddleware"]) -> by
2424
template_pdf = pdfrw.PdfReader(fdata=template_stream)
2525

2626
texts_to_draw = {}
27-
images_to_draw = {}
2827
text_watermarks = []
29-
image_watermarks = []
3028

3129
radio_button_tracker = {}
3230

3331
for page, _elements in (
3432
TemplateCore().get_elements_by_page(template_pdf).items()
3533
):
3634
texts_to_draw[page] = []
37-
images_to_draw[page] = []
3835
text_watermarks.append(b"")
39-
image_watermarks.append(b"")
4036
for _element in _elements:
4137
key = TemplateCore().get_element_key(_element)
4238

@@ -77,17 +73,6 @@ def fill(template_stream: bytes, elements: Dict[str, "ElementMiddleware"]) -> by
7773
)
7874
)
7975
continue
80-
elif elements[key].type == ElementType.image:
81-
if elements[key].value is not None:
82-
images_to_draw[page].append(
83-
[
84-
elements[key].value,
85-
TemplateCore().get_draw_image_coordinates(_element)[0],
86-
TemplateCore().get_draw_image_coordinates(_element)[1],
87-
TemplateCore().get_draw_image_resolutions(_element)[0],
88-
TemplateCore().get_draw_image_resolutions(_element)[1],
89-
]
90-
)
9176
else:
9277
texts_to_draw[page].append(
9378
[
@@ -106,134 +91,78 @@ def fill(template_stream: bytes, elements: Dict[str, "ElementMiddleware"]) -> by
10691
if watermark:
10792
text_watermarks[i] = watermark
10893

109-
result = WatermarkCore().merge_watermarks_with_pdf(
94+
return WatermarkCore().merge_watermarks_with_pdf(
11095
Utils().generate_stream(template_pdf), text_watermarks
11196
)
11297

113-
for page, images in images_to_draw.items():
114-
if images:
115-
_watermarks = WatermarkCore().create_watermarks_and_draw(
116-
result, page, "image", images
117-
)
118-
for i, watermark in enumerate(_watermarks):
119-
if watermark:
120-
image_watermarks[i] = watermark
121-
122-
result = WatermarkCore().merge_watermarks_with_pdf(result, image_watermarks)
123-
124-
return result
125-
12698
@staticmethod
12799
def simple_fill(
128100
template_stream: bytes,
129-
data: Dict[str, Union[str, bool, bytes, int]],
101+
data: Dict[str, Union[str, bool, int]],
130102
editable: bool,
131103
) -> bytes:
132104
"""Fills a PDF form in simple mode."""
133105

134106
template_pdf = pdfrw.PdfReader(fdata=template_stream)
135107
data = Utils().bool_to_checkboxes(data)
136108

137-
images_to_draw = {}
138-
image_watermarks = []
139-
140109
radio_button_tracker = {}
141110

142-
for page, elements in TemplateCore().get_elements_by_page(template_pdf).items():
143-
images_to_draw[page] = []
144-
image_watermarks.append(b"")
145-
for element in elements:
146-
key = TemplateCore().get_element_key(element)
147-
148-
if key in data.keys():
149-
update_dict = {}
150-
if data[key] in [
151-
pdfrw.PdfName.Yes,
152-
pdfrw.PdfName.Off,
153-
]:
154-
update_dict = {
155-
TemplateConstants().checkbox_field_value_key.replace(
156-
"/", ""
157-
): data[key]
158-
}
159-
elif isinstance(data[key], int):
160-
if key not in radio_button_tracker:
161-
radio_button_tracker[key] = 0
162-
radio_button_tracker[key] += 1
163-
164-
if data[key] == radio_button_tracker[key] - 1:
165-
element.update(
166-
pdfrw.PdfDict(
167-
**{
168-
TemplateConstants().checkbox_field_value_key.replace(
169-
"/", ""
170-
): BasePdfName(
171-
"/" + str(data[key]), False
172-
),
173-
}
174-
)
175-
)
111+
for element in TemplateCore().iterate_elements(template_pdf):
112+
key = TemplateCore().get_element_key(element)
113+
114+
if key in data.keys():
115+
update_dict = {}
116+
if data[key] in [
117+
pdfrw.PdfName.Yes,
118+
pdfrw.PdfName.Off,
119+
]:
120+
update_dict = {
121+
TemplateConstants().checkbox_field_value_key.replace(
122+
"/", ""
123+
): data[key]
124+
}
125+
elif isinstance(data[key], int):
126+
if key not in radio_button_tracker:
127+
radio_button_tracker[key] = 0
128+
radio_button_tracker[key] += 1
176129

177-
if not editable:
178-
element[
179-
TemplateConstants().radio_button_group_key
180-
].update(
181-
pdfrw.PdfDict(
182-
**{
183-
TemplateConstants().field_editable_key.replace(
184-
"/", ""
185-
): pdfrw.PdfObject(
186-
1
187-
)
188-
}
189-
)
190-
)
191-
continue
192-
elif isinstance(data[key], bytes):
193-
images_to_draw[page].append(
194-
[
195-
data[key],
196-
TemplateCore().get_draw_image_coordinates(element)[0],
197-
TemplateCore().get_draw_image_coordinates(element)[1],
198-
TemplateCore().get_draw_image_resolutions(element)[0],
199-
TemplateCore().get_draw_image_resolutions(element)[1],
200-
]
201-
)
130+
if data[key] == radio_button_tracker[key] - 1:
202131
element.update(
203132
pdfrw.PdfDict(
204133
**{
205-
TemplateConstants().field_editable_key.replace(
134+
TemplateConstants().checkbox_field_value_key.replace(
206135
"/", ""
207-
): pdfrw.PdfObject(1)
136+
): BasePdfName(
137+
"/" + str(data[key]), False
138+
),
208139
}
209140
)
210141
)
142+
143+
if not editable:
144+
element[TemplateConstants().radio_button_group_key].update(
145+
pdfrw.PdfDict(
146+
**{
147+
TemplateConstants().field_editable_key.replace(
148+
"/", ""
149+
): pdfrw.PdfObject(1)
150+
}
151+
)
152+
)
211153
continue
212-
else:
213-
update_dict = {
214-
TemplateConstants().text_field_value_key.replace(
215-
"/", ""
216-
): data[key]
217-
}
218-
219-
if not editable:
220-
update_dict[
221-
TemplateConstants().field_editable_key.replace("/", "")
222-
] = pdfrw.PdfObject(1)
223-
224-
element.update(pdfrw.PdfDict(**update_dict))
225-
226-
result = Utils().generate_stream(template_pdf)
227-
228-
for page, images in images_to_draw.items():
229-
if images:
230-
_watermarks = WatermarkCore().create_watermarks_and_draw(
231-
result, page, "image", images
232-
)
233-
for i, watermark in enumerate(_watermarks):
234-
if watermark:
235-
image_watermarks[i] = watermark
236-
237-
result = WatermarkCore().merge_watermarks_with_pdf(result, image_watermarks)
238-
239-
return result
154+
else:
155+
update_dict = {
156+
TemplateConstants().text_field_value_key.replace("/", ""): data[
157+
key
158+
]
159+
}
160+
161+
if not editable:
162+
update_dict[
163+
TemplateConstants().field_editable_key.replace("/", "")
164+
] = pdfrw.PdfObject(1)
165+
166+
element.update(pdfrw.PdfDict(**update_dict))
167+
168+
return Utils().generate_stream(template_pdf)

PyPDFForm/core/template.py

+1-30
Original file line numberDiff line numberDiff line change
@@ -88,19 +88,14 @@ def get_element_type(element: "pdfrw.PdfDict") -> Union["ElementType", None]:
8888
"""Returns its annotated type given a PDF form element."""
8989

9090
element_type_mapping = {
91-
"/Btn": "MULTIPLE",
91+
"/Btn": ElementType.checkbox,
9292
"/Tx": ElementType.text,
9393
}
9494

9595
result = element_type_mapping.get(
9696
str(element[TemplateCoreConstants().element_type_key])
9797
)
9898

99-
if result == "MULTIPLE":
100-
if element[TemplateCoreConstants().checkbox_field_value_key]:
101-
return ElementType.checkbox
102-
return ElementType.image
103-
10499
if not result and element[TemplateCoreConstants().radio_button_group_key]:
105100
return ElementType.radio
106101

@@ -122,30 +117,6 @@ def get_draw_text_coordinates(
122117
- 2,
123118
)
124119

125-
@staticmethod
126-
def get_draw_image_coordinates(
127-
element: "pdfrw.PdfDict",
128-
) -> Tuple[Union[float, int], Union[float, int]]:
129-
"""Returns coordinates to draw image at given a PDF form image element."""
130-
131-
return (
132-
float(element[TemplateCoreConstants().annotation_rectangle_key][0]),
133-
float(element[TemplateCoreConstants().annotation_rectangle_key][1]),
134-
)
135-
136-
@staticmethod
137-
def get_draw_image_resolutions(
138-
element: "pdfrw.PdfDict",
139-
) -> Tuple[Union[float, int], Union[float, int]]:
140-
"""Returns width and height of the image given a PDF form image element."""
141-
142-
return (
143-
float(element[TemplateCoreConstants().annotation_rectangle_key][2])
144-
- float(element[TemplateCoreConstants().annotation_rectangle_key][0]),
145-
float(element[TemplateCoreConstants().annotation_rectangle_key][3])
146-
- float(element[TemplateCoreConstants().annotation_rectangle_key][1]),
147-
)
148-
149120
def assign_uuid(self, pdf: bytes) -> bytes:
150121
"""Appends a separator and uuid after each element's annotated name."""
151122

PyPDFForm/core/utils.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def generate_stream(pdf: "pdfrw.PdfReader") -> bytes:
2727

2828
@staticmethod
2929
def bool_to_checkboxes(
30-
data: Dict[str, Union[str, bool, bytes, int]]
30+
data: Dict[str, Union[str, bool, int]]
3131
) -> Dict[str, Union[str, "pdfrw.PdfName"]]:
3232
"""Converts all boolean values in input data dictionary into PDF checkbox objects."""
3333

PyPDFForm/middleware/element.py

+3-40
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@
22
"""Contains element middleware."""
33

44
from enum import Enum
5-
from typing import BinaryIO, Union
5+
from typing import Union
66

77
from ..core.font import Font as FontCore
8-
from ..core.image import Image as ImageCore
9-
from .adapter import FileAdapter
108
from .exceptions.element import (InvalidElementNameError,
119
InvalidElementTypeError,
1210
InvalidElementValueError,
@@ -20,7 +18,6 @@ class ElementType(Enum):
2018

2119
text = "text"
2220
checkbox = "checkbox"
23-
image = "image"
2421
radio = "radio"
2522

2623

@@ -31,21 +28,13 @@ def __init__(
3128
self,
3229
element_name: str,
3330
element_type: "ElementType",
34-
element_value: Union[str, bool, bytes, int, BinaryIO] = None,
31+
element_value: Union[str, bool, int] = None,
3532
) -> None:
3633
"""Constructs all attributes for the Element object."""
3734

38-
if element_type == ElementType.image and (
39-
isinstance(element_value, (bytes, str))
40-
or FileAdapter().readable(element_value)
41-
):
42-
adapted = FileAdapter().fp_or_f_obj_or_stream_to_stream(element_value)
43-
if adapted is not None:
44-
element_value = adapted
45-
4635
self._name = element_name
4736
self._type = element_type
48-
self._value = element_value
37+
self.value = element_value
4938

5039
if element_type == ElementType.text:
5140
self.font = None
@@ -55,25 +44,6 @@ def __init__(
5544
self.text_y_offset = None
5645
self.text_wrap_length = None
5746

58-
@property
59-
def value(self) -> Union[str, bool, bytes, int, BinaryIO]:
60-
"""Value of the element."""
61-
62-
return self._value
63-
64-
@value.setter
65-
def value(self, v) -> None:
66-
"""Insures the value gets converted to bytes when set to fp or f object."""
67-
68-
if self._type == ElementType.image and (
69-
isinstance(v, (bytes, str)) or FileAdapter().readable(v)
70-
):
71-
adapted = FileAdapter().fp_or_f_obj_or_stream_to_stream(v)
72-
if adapted is not None:
73-
v = adapted
74-
75-
self._value = v
76-
7747
@property
7848
def name(self) -> str:
7949
"""Name of the element."""
@@ -106,13 +76,6 @@ def validate_value(self) -> None:
10676
if self.value is not None and not isinstance(self.value, bool):
10777
raise InvalidElementValueError
10878

109-
if self._type == ElementType.image:
110-
if self.value is not None:
111-
if not isinstance(self.value, bytes):
112-
raise InvalidElementValueError
113-
if not ImageCore().is_image(self.value):
114-
raise InvalidElementValueError
115-
11679
if self._type == ElementType.radio:
11780
if self.value is not None and not isinstance(self.value, int):
11881
raise InvalidElementValueError

0 commit comments

Comments
 (0)