Skip to content

Commit 57d19fb

Browse files
Merge pull request #316 from chinapandaman/PPF-315
PPF-315: refactor wrapper v2
2 parents bf60048 + 3a92fa8 commit 57d19fb

File tree

6 files changed

+188
-171
lines changed

6 files changed

+188
-171
lines changed

.pylintrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
[MESSAGES CONTROL]
2-
disable=C0103, R0913, R0902, R0903, R0914, R0912, C0209, E1121
2+
disable=C0103, R0913, R0902, R0903, R0914, R0912, C0209, E1121, R0801

Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ build-all:
44
test-all:
55
bash ./scripts/test.sh
66

7-
check-test-imports:
8-
bash ./scripts/check_test_imports.sh
7+
check-imports:
8+
bash ./scripts/check_imports.sh

PyPDFForm/__init__.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
"""Contains v1 and v2 wrappers."""
33

44
from .middleware.wrapper import PyPDFForm as Wrapper
5-
from .middleware.wrapper import WrapperV2
5+
from .middleware.wrapper_v2 import WrapperV2
66

77
PyPDFForm = Wrapper
88
PyPDFForm2 = WrapperV2
99

10-
__version__ = "1.1.9"
10+
__version__ = "1.2.0"

PyPDFForm/middleware/wrapper.py

-166
Original file line numberDiff line numberDiff line change
@@ -292,169 +292,3 @@ def register_font(
292292
raise InvalidTTFFontError
293293

294294
return True
295-
296-
297-
class WrapperV2:
298-
"""A class to represent a PDF form."""
299-
300-
def __init__(
301-
self,
302-
template: Union[bytes, str, BinaryIO] = b"",
303-
**kwargs,
304-
) -> None:
305-
"""Constructs all attributes for the PyPDFForm object."""
306-
307-
self.stream = FileAdapter().fp_or_f_obj_or_stream_to_stream(template)
308-
self.elements = (
309-
TemplateMiddleware().build_elements_v2(self.stream) if self.stream else {}
310-
)
311-
312-
for each in self.elements.values():
313-
if each.type == ElementType.text:
314-
each.font = kwargs.get("global_font", TextConstants().global_font)
315-
each.font_size = kwargs.get(
316-
"global_font_size", TextConstants().global_font_size
317-
)
318-
each.font_color = kwargs.get(
319-
"global_font_color", TextConstants().global_font_color
320-
)
321-
each.text_x_offset = kwargs.get(
322-
"global_text_x_offset", TextConstants().global_text_x_offset
323-
)
324-
each.text_y_offset = kwargs.get(
325-
"global_text_y_offset", TextConstants().global_text_y_offset
326-
)
327-
each.text_wrap_length = kwargs.get(
328-
"global_text_wrap_length", TextConstants().global_text_wrap_length
329-
)
330-
331-
def read(self) -> bytes:
332-
"""Reads the file stream of a PDF form."""
333-
334-
return self.stream
335-
336-
def __add__(self, other: "WrapperV2") -> "WrapperV2":
337-
"""Overloaded addition operator to perform merging PDFs."""
338-
339-
if not self.stream:
340-
return other
341-
342-
if not other.stream:
343-
return self
344-
345-
new_obj = self.__class__()
346-
new_obj.stream = UtilsCore().merge_two_pdfs(self.stream, other.stream)
347-
348-
return new_obj
349-
350-
def fill(
351-
self,
352-
data: Dict[str, Union[str, bool, int]],
353-
) -> "WrapperV2":
354-
"""Fill a PDF form."""
355-
356-
for key, value in data.items():
357-
if key in self.elements:
358-
self.elements[key].value = value
359-
360-
if self.read():
361-
self.elements = TemplateMiddleware().set_character_x_paddings(
362-
self.stream, self.elements
363-
)
364-
365-
self.stream = TemplateCore().remove_all_elements(
366-
FillerCore().fill_v2(self.stream, self.elements)
367-
)
368-
369-
return self
370-
371-
def draw_text(
372-
self,
373-
text: str,
374-
page_number: int,
375-
x: Union[float, int],
376-
y: Union[float, int],
377-
**kwargs,
378-
) -> "WrapperV2":
379-
"""Draws a text on a PDF form."""
380-
381-
new_element = ElementMiddleware("new", ElementType.text)
382-
new_element.value = text
383-
new_element.font = kwargs.get("font", TextConstants().global_font)
384-
new_element.font_size = kwargs.get(
385-
"font_size", TextConstants().global_font_size
386-
)
387-
new_element.font_color = kwargs.get(
388-
"font_color", TextConstants().global_font_color
389-
)
390-
new_element.text_x_offset = kwargs.get(
391-
"text_x_offset", TextConstants().global_text_x_offset
392-
)
393-
new_element.text_y_offset = kwargs.get(
394-
"text_y_offset", TextConstants().global_text_y_offset
395-
)
396-
new_element.text_wrap_length = kwargs.get(
397-
"text_wrap_length", TextConstants().global_text_wrap_length
398-
)
399-
400-
watermarks = WatermarkCore().create_watermarks_and_draw(
401-
self.stream,
402-
page_number,
403-
"text",
404-
[
405-
[
406-
new_element,
407-
x,
408-
y,
409-
]
410-
],
411-
)
412-
413-
self.stream = WatermarkCore().merge_watermarks_with_pdf(self.stream, watermarks)
414-
415-
return self
416-
417-
def draw_image(
418-
self,
419-
image: Union[bytes, str, BinaryIO],
420-
page_number: int,
421-
x: Union[float, int],
422-
y: Union[float, int],
423-
width: Union[float, int],
424-
height: Union[float, int],
425-
rotation: Union[float, int] = 0,
426-
) -> "WrapperV2":
427-
"""Draws an image on a PDF form."""
428-
429-
image = FileAdapter().fp_or_f_obj_or_stream_to_stream(image)
430-
image = ImageCore().any_image_to_jpg(image)
431-
image = ImageCore().rotate_image(image, rotation)
432-
watermarks = WatermarkCore().create_watermarks_and_draw(
433-
self.stream, page_number, "image", [[image, x, y, width, height]]
434-
)
435-
436-
self.stream = WatermarkCore().merge_watermarks_with_pdf(self.stream, watermarks)
437-
438-
return self
439-
440-
def generate_schema(self) -> dict:
441-
"""Generates a json schema for the PDF form template."""
442-
443-
result = {
444-
"type": "object",
445-
"properties": {
446-
key: value.schema_definition for key, value in self.elements.items()
447-
},
448-
}
449-
450-
return result
451-
452-
@classmethod
453-
def register_font(
454-
cls, font_name: str, ttf_file: Union[bytes, str, BinaryIO]
455-
) -> bool:
456-
"""Registers a font from a ttf file."""
457-
458-
ttf_file = FileAdapter().fp_or_f_obj_or_stream_to_stream(ttf_file)
459-
460-
return FontCore().register_font(font_name, ttf_file)

PyPDFForm/middleware/wrapper_v2.py

+182
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
# -*- coding: utf-8 -*-
2+
"""Contains v2 user API for PyPDFForm."""
3+
4+
from typing import BinaryIO, Dict, Union
5+
6+
from ..core.filler import Filler as FillerCore
7+
from ..core.font import Font as FontCore
8+
from ..core.image import Image as ImageCore
9+
from ..core.template import Template as TemplateCore
10+
from ..core.utils import Utils as UtilsCore
11+
from ..core.watermark import Watermark as WatermarkCore
12+
from .adapter import FileAdapter
13+
from .constants import Text as TextConstants
14+
from .element import Element as ElementMiddleware
15+
from .element import ElementType
16+
from .template import Template as TemplateMiddleware
17+
18+
19+
class WrapperV2:
20+
"""A class to represent a PDF form."""
21+
22+
def __init__(
23+
self,
24+
template: Union[bytes, str, BinaryIO] = b"",
25+
**kwargs,
26+
) -> None:
27+
"""Constructs all attributes for the PyPDFForm object."""
28+
29+
self.stream = FileAdapter().fp_or_f_obj_or_stream_to_stream(template)
30+
self.elements = (
31+
TemplateMiddleware().build_elements_v2(self.stream) if self.stream else {}
32+
)
33+
34+
for each in self.elements.values():
35+
if each.type == ElementType.text:
36+
each.font = kwargs.get("global_font", TextConstants().global_font)
37+
each.font_size = kwargs.get(
38+
"global_font_size", TextConstants().global_font_size
39+
)
40+
each.font_color = kwargs.get(
41+
"global_font_color", TextConstants().global_font_color
42+
)
43+
each.text_x_offset = kwargs.get(
44+
"global_text_x_offset", TextConstants().global_text_x_offset
45+
)
46+
each.text_y_offset = kwargs.get(
47+
"global_text_y_offset", TextConstants().global_text_y_offset
48+
)
49+
each.text_wrap_length = kwargs.get(
50+
"global_text_wrap_length", TextConstants().global_text_wrap_length
51+
)
52+
53+
def read(self) -> bytes:
54+
"""Reads the file stream of a PDF form."""
55+
56+
return self.stream
57+
58+
def __add__(self, other: "WrapperV2") -> "WrapperV2":
59+
"""Overloaded addition operator to perform merging PDFs."""
60+
61+
if not self.stream:
62+
return other
63+
64+
if not other.stream:
65+
return self
66+
67+
new_obj = self.__class__()
68+
new_obj.stream = UtilsCore().merge_two_pdfs(self.stream, other.stream)
69+
70+
return new_obj
71+
72+
def fill(
73+
self,
74+
data: Dict[str, Union[str, bool, int]],
75+
) -> "WrapperV2":
76+
"""Fill a PDF form."""
77+
78+
for key, value in data.items():
79+
if key in self.elements:
80+
self.elements[key].value = value
81+
82+
if self.read():
83+
self.elements = TemplateMiddleware().set_character_x_paddings(
84+
self.stream, self.elements
85+
)
86+
87+
self.stream = TemplateCore().remove_all_elements(
88+
FillerCore().fill_v2(self.stream, self.elements)
89+
)
90+
91+
return self
92+
93+
def draw_text(
94+
self,
95+
text: str,
96+
page_number: int,
97+
x: Union[float, int],
98+
y: Union[float, int],
99+
**kwargs,
100+
) -> "WrapperV2":
101+
"""Draws a text on a PDF form."""
102+
103+
new_element = ElementMiddleware("new", ElementType.text)
104+
new_element.value = text
105+
new_element.font = kwargs.get("font", TextConstants().global_font)
106+
new_element.font_size = kwargs.get(
107+
"font_size", TextConstants().global_font_size
108+
)
109+
new_element.font_color = kwargs.get(
110+
"font_color", TextConstants().global_font_color
111+
)
112+
new_element.text_x_offset = kwargs.get(
113+
"text_x_offset", TextConstants().global_text_x_offset
114+
)
115+
new_element.text_y_offset = kwargs.get(
116+
"text_y_offset", TextConstants().global_text_y_offset
117+
)
118+
new_element.text_wrap_length = kwargs.get(
119+
"text_wrap_length", TextConstants().global_text_wrap_length
120+
)
121+
122+
watermarks = WatermarkCore().create_watermarks_and_draw(
123+
self.stream,
124+
page_number,
125+
"text",
126+
[
127+
[
128+
new_element,
129+
x,
130+
y,
131+
]
132+
],
133+
)
134+
135+
self.stream = WatermarkCore().merge_watermarks_with_pdf(self.stream, watermarks)
136+
137+
return self
138+
139+
def draw_image(
140+
self,
141+
image: Union[bytes, str, BinaryIO],
142+
page_number: int,
143+
x: Union[float, int],
144+
y: Union[float, int],
145+
width: Union[float, int],
146+
height: Union[float, int],
147+
rotation: Union[float, int] = 0,
148+
) -> "WrapperV2":
149+
"""Draws an image on a PDF form."""
150+
151+
image = FileAdapter().fp_or_f_obj_or_stream_to_stream(image)
152+
image = ImageCore().any_image_to_jpg(image)
153+
image = ImageCore().rotate_image(image, rotation)
154+
watermarks = WatermarkCore().create_watermarks_and_draw(
155+
self.stream, page_number, "image", [[image, x, y, width, height]]
156+
)
157+
158+
self.stream = WatermarkCore().merge_watermarks_with_pdf(self.stream, watermarks)
159+
160+
return self
161+
162+
def generate_schema(self) -> dict:
163+
"""Generates a json schema for the PDF form template."""
164+
165+
result = {
166+
"type": "object",
167+
"properties": {
168+
key: value.schema_definition for key, value in self.elements.items()
169+
},
170+
}
171+
172+
return result
173+
174+
@classmethod
175+
def register_font(
176+
cls, font_name: str, ttf_file: Union[bytes, str, BinaryIO]
177+
) -> bool:
178+
"""Registers a font from a ttf file."""
179+
180+
ttf_file = FileAdapter().fp_or_f_obj_or_stream_to_stream(ttf_file)
181+
182+
return FontCore().register_font(font_name, ttf_file)

scripts/check_test_imports.sh scripts/check_imports.sh

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ if [[ "$VIRTUAL_ENV" == "" ]]; then
33
fi
44

55
pylint ./tests | { grep "unused-import" || true; }
6+
pylint ./PyPDFForm | { grep "unused-import" || true; }

0 commit comments

Comments
 (0)