PyPDFForm 1.5.2__tar.gz → 1.5.3__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.

Files changed (51) hide show
  1. {pypdfform-1.5.2 → pypdfform-1.5.3}/PKG-INFO +1 -1
  2. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm/__init__.py +1 -1
  3. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm/coordinate.py +15 -0
  4. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm/filler.py +5 -2
  5. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm/image.py +13 -1
  6. pypdfform-1.5.3/PyPDFForm/middleware/image.py +21 -0
  7. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm/middleware/signature.py +2 -0
  8. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm.egg-info/PKG-INFO +1 -1
  9. pypdfform-1.5.3/tests/test_signature.py +180 -0
  10. pypdfform-1.5.2/PyPDFForm/middleware/image.py +0 -8
  11. pypdfform-1.5.2/tests/test_signature.py +0 -61
  12. {pypdfform-1.5.2 → pypdfform-1.5.3}/LICENSE +0 -0
  13. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm/adapter.py +0 -0
  14. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm/constants.py +0 -0
  15. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm/font.py +0 -0
  16. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm/middleware/__init__.py +0 -0
  17. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm/middleware/base.py +0 -0
  18. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm/middleware/checkbox.py +0 -0
  19. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm/middleware/dropdown.py +0 -0
  20. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm/middleware/radio.py +0 -0
  21. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm/middleware/text.py +0 -0
  22. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm/patterns.py +0 -0
  23. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm/template.py +0 -0
  24. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm/utils.py +0 -0
  25. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm/watermark.py +0 -0
  26. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm/widgets/__init__.py +0 -0
  27. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm/widgets/base.py +0 -0
  28. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm/widgets/checkbox.py +0 -0
  29. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm/widgets/dropdown.py +0 -0
  30. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm/widgets/text.py +0 -0
  31. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm/wrapper.py +0 -0
  32. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm.egg-info/SOURCES.txt +0 -0
  33. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm.egg-info/dependency_links.txt +0 -0
  34. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm.egg-info/requires.txt +0 -0
  35. {pypdfform-1.5.2 → pypdfform-1.5.3}/PyPDFForm.egg-info/top_level.txt +0 -0
  36. {pypdfform-1.5.2 → pypdfform-1.5.3}/README.md +0 -0
  37. {pypdfform-1.5.2 → pypdfform-1.5.3}/setup.cfg +0 -0
  38. {pypdfform-1.5.2 → pypdfform-1.5.3}/setup.py +0 -0
  39. {pypdfform-1.5.2 → pypdfform-1.5.3}/tests/test_adobe_mode.py +0 -0
  40. {pypdfform-1.5.2 → pypdfform-1.5.3}/tests/test_create_widget.py +0 -0
  41. {pypdfform-1.5.2 → pypdfform-1.5.3}/tests/test_dropdown.py +0 -0
  42. {pypdfform-1.5.2 → pypdfform-1.5.3}/tests/test_dropdown_simple.py +0 -0
  43. {pypdfform-1.5.2 → pypdfform-1.5.3}/tests/test_fill_max_length_text_field.py +0 -0
  44. {pypdfform-1.5.2 → pypdfform-1.5.3}/tests/test_fill_max_length_text_field_simple.py +0 -0
  45. {pypdfform-1.5.2 → pypdfform-1.5.3}/tests/test_fill_method.py +0 -0
  46. {pypdfform-1.5.2 → pypdfform-1.5.3}/tests/test_functional.py +0 -0
  47. {pypdfform-1.5.2 → pypdfform-1.5.3}/tests/test_functional_simple.py +0 -0
  48. {pypdfform-1.5.2 → pypdfform-1.5.3}/tests/test_paragraph.py +0 -0
  49. {pypdfform-1.5.2 → pypdfform-1.5.3}/tests/test_paragraph_simple.py +0 -0
  50. {pypdfform-1.5.2 → pypdfform-1.5.3}/tests/test_preview.py +0 -0
  51. {pypdfform-1.5.2 → pypdfform-1.5.3}/tests/test_use_full_widget_name.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: PyPDFForm
3
- Version: 1.5.2
3
+ Version: 1.5.3
4
4
  Summary: The Python library for PDF forms.
5
5
  Home-page: https://github.com/chinapandaman/PyPDFForm
6
6
  Author: Jinge Li
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """Contains any object users might need."""
3
3
 
4
- __version__ = "1.5.2"
4
+ __version__ = "1.5.3"
5
5
 
6
6
  from .wrapper import FormWrapper, PdfWrapper
7
7
 
@@ -40,6 +40,9 @@ def get_draw_checkbox_radio_coordinates(
40
40
 
41
41
  def get_draw_image_coordinates_resolutions(
42
42
  widget: dict,
43
+ preserve_aspect_ratio: bool,
44
+ image_width: float,
45
+ image_height: float,
43
46
  ) -> Tuple[float, float, float, float]:
44
47
  """
45
48
  Returns coordinates and resolutions to draw image at given a PDF form signature/image widget.
@@ -50,6 +53,18 @@ def get_draw_image_coordinates_resolutions(
50
53
  width = abs(float(widget[Rect][0]) - float(widget[Rect][2]))
51
54
  height = abs(float(widget[Rect][1]) - float(widget[Rect][3]))
52
55
 
56
+ if preserve_aspect_ratio:
57
+ ratio = max(image_width / width, image_height / height)
58
+
59
+ new_width = image_width / ratio
60
+ new_height = image_height / ratio
61
+
62
+ x += abs(new_width - width) / 2
63
+ y += abs(new_height - height) / 2
64
+
65
+ width = new_width
66
+ height = new_height
67
+
53
68
  return x, y, width, height
54
69
 
55
70
 
@@ -13,7 +13,7 @@ from .coordinate import (get_draw_checkbox_radio_coordinates,
13
13
  get_draw_text_coordinates,
14
14
  get_text_line_x_coordinates)
15
15
  from .font import checkbox_radio_font_size
16
- from .image import any_image_to_jpg
16
+ from .image import any_image_to_jpg, get_image_dimensions
17
17
  from .middleware.checkbox import Checkbox
18
18
  from .middleware.dropdown import Dropdown
19
19
  from .middleware.image import Image
@@ -62,7 +62,10 @@ def signature_image_handler(
62
62
  if stream is not None:
63
63
  any_image_to_draw = True
64
64
  stream = any_image_to_jpg(stream)
65
- x, y, width, height = get_draw_image_coordinates_resolutions(widget)
65
+ image_width, image_height = get_image_dimensions(stream)
66
+ x, y, width, height = get_draw_image_coordinates_resolutions(
67
+ widget, middleware.preserve_aspect_ratio, image_width, image_height
68
+ )
66
69
  images_to_draw.append(
67
70
  [
68
71
  stream,
@@ -2,7 +2,7 @@
2
2
  """Contains helpers for image."""
3
3
 
4
4
  from io import BytesIO
5
- from typing import Union
5
+ from typing import Tuple, Union
6
6
 
7
7
  from PIL import Image
8
8
 
@@ -28,6 +28,18 @@ def rotate_image(image_stream: bytes, rotation: Union[float, int]) -> bytes:
28
28
  return result
29
29
 
30
30
 
31
+ def get_image_dimensions(image_stream: bytes) -> Tuple[float, float]:
32
+ """Gets the width and height of an image."""
33
+
34
+ buff = BytesIO()
35
+ buff.write(image_stream)
36
+ buff.seek(0)
37
+
38
+ image = Image.open(buff)
39
+
40
+ return image.size
41
+
42
+
31
43
  def any_image_to_jpg(image_stream: bytes) -> bytes:
32
44
  """Converts an image of any type to jpg."""
33
45
 
@@ -0,0 +1,21 @@
1
+ # -*- coding: utf-8 -*-
2
+ """Contains image field middleware."""
3
+
4
+ from typing import BinaryIO, Union
5
+
6
+ from .signature import Signature
7
+
8
+
9
+ class Image(Signature):
10
+ """A class to represent an image field widget."""
11
+
12
+ def __init__(
13
+ self,
14
+ name: str,
15
+ value: Union[bytes, str, BinaryIO] = None,
16
+ ) -> None:
17
+ """Constructs all attributes for the image field."""
18
+
19
+ super().__init__(name, value)
20
+
21
+ self.preserve_aspect_ratio = False
@@ -20,6 +20,8 @@ class Signature(Widget):
20
20
 
21
21
  super().__init__(name, value)
22
22
 
23
+ self.preserve_aspect_ratio = True
24
+
23
25
  @property
24
26
  def schema_definition(self) -> dict:
25
27
  """Json schema definition of the signature field."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: PyPDFForm
3
- Version: 1.5.2
3
+ Version: 1.5.3
4
4
  Summary: The Python library for PDF forms.
5
5
  Home-page: https://github.com/chinapandaman/PyPDFForm
6
6
  Author: Jinge Li
@@ -0,0 +1,180 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ import os
4
+
5
+ from PyPDFForm import PdfWrapper
6
+
7
+
8
+ def test_fill_signature(pdf_samples, image_samples, request):
9
+ expected_path = os.path.join(pdf_samples, "signature", "test_fill_signature.pdf")
10
+ with open(expected_path, "rb+") as f:
11
+ obj = PdfWrapper(
12
+ os.path.join(pdf_samples, "signature", "sample_template_with_signature.pdf")
13
+ ).fill({"signature": os.path.join(image_samples, "sample_signature.png")})
14
+
15
+ request.config.results["expected_path"] = expected_path
16
+ request.config.results["stream"] = obj.read()
17
+
18
+ expected = f.read()
19
+
20
+ if os.name != "nt":
21
+ assert len(obj.read()) == len(expected)
22
+ assert obj.read() == expected
23
+
24
+
25
+ def test_signature_schema(pdf_samples):
26
+ obj = PdfWrapper(
27
+ os.path.join(pdf_samples, "signature", "sample_template_with_signature.pdf")
28
+ )
29
+
30
+ assert obj.widgets["signature"].schema_definition == {"type": "string"}
31
+
32
+
33
+ def test_signature_sample_value(pdf_samples):
34
+ obj = PdfWrapper(
35
+ os.path.join(pdf_samples, "signature", "sample_template_with_signature.pdf")
36
+ )
37
+
38
+ assert obj.widgets["signature"].sample_value == os.path.expanduser(
39
+ "~/Downloads/sample_image.jpg"
40
+ )
41
+
42
+
43
+ def test_fill_signature_overlap(pdf_samples, image_samples, request):
44
+ expected_path = os.path.join(
45
+ pdf_samples, "signature", "test_fill_signature_overlap.pdf"
46
+ )
47
+ with open(expected_path, "rb+") as f:
48
+ obj = PdfWrapper(
49
+ os.path.join(
50
+ pdf_samples, "signature", "sample_template_with_signature_overlap.pdf"
51
+ )
52
+ ).fill({"signature": os.path.join(image_samples, "sample_signature.png")})
53
+
54
+ request.config.results["expected_path"] = expected_path
55
+ request.config.results["stream"] = obj.read()
56
+
57
+ expected = f.read()
58
+
59
+ if os.name != "nt":
60
+ assert len(obj.read()) == len(expected)
61
+ assert obj.read() == expected
62
+
63
+
64
+ def test_fill_signature_overlap_not_preserve_aspect_ratio(
65
+ pdf_samples, image_samples, request
66
+ ):
67
+ expected_path = os.path.join(
68
+ pdf_samples,
69
+ "signature",
70
+ "test_fill_signature_overlap_not_preserve_aspect_ratio.pdf",
71
+ )
72
+ with open(expected_path, "rb+") as f:
73
+ obj = PdfWrapper(
74
+ os.path.join(
75
+ pdf_samples, "signature", "sample_template_with_signature_overlap.pdf"
76
+ )
77
+ )
78
+ obj.widgets["signature"].preserve_aspect_ratio = False
79
+ obj.fill({"signature": os.path.join(image_samples, "sample_signature.png")})
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.read() == expected
89
+
90
+
91
+ def test_fill_small_icon(pdf_samples, image_samples, request):
92
+ expected_path = os.path.join(pdf_samples, "signature", "test_fill_small_icon.pdf")
93
+ with open(expected_path, "rb+") as f:
94
+ obj = PdfWrapper(
95
+ os.path.join(
96
+ pdf_samples, "signature", "sample_template_with_signature_overlap.pdf"
97
+ )
98
+ )
99
+ obj.fill({"signature": os.path.join(image_samples, "small_icon.png")})
100
+
101
+ request.config.results["expected_path"] = expected_path
102
+ request.config.results["stream"] = obj.read()
103
+
104
+ expected = f.read()
105
+
106
+ if os.name != "nt":
107
+ assert len(obj.read()) == len(expected)
108
+ assert obj.read() == expected
109
+
110
+
111
+ def test_fill_small_icon_not_preserve_aspect_ratio(pdf_samples, image_samples, request):
112
+ expected_path = os.path.join(
113
+ pdf_samples, "signature", "test_fill_small_icon_not_preserve_aspect_ratio.pdf"
114
+ )
115
+ with open(expected_path, "rb+") as f:
116
+ obj = PdfWrapper(
117
+ os.path.join(
118
+ pdf_samples, "signature", "sample_template_with_signature_overlap.pdf"
119
+ )
120
+ )
121
+ obj.widgets["signature"].preserve_aspect_ratio = False
122
+ obj.fill({"signature": os.path.join(image_samples, "small_icon.png")})
123
+
124
+ request.config.results["expected_path"] = expected_path
125
+ request.config.results["stream"] = obj.read()
126
+
127
+ expected = f.read()
128
+
129
+ if os.name != "nt":
130
+ assert len(obj.read()) == len(expected)
131
+ assert obj.read() == expected
132
+
133
+
134
+ def test_fill_vertical_image(pdf_samples, image_samples, request):
135
+ expected_path = os.path.join(
136
+ pdf_samples, "signature", "test_fill_vertical_image.pdf"
137
+ )
138
+ with open(expected_path, "rb+") as f:
139
+ obj = PdfWrapper(
140
+ os.path.join(
141
+ pdf_samples, "signature", "sample_template_with_signature_overlap.pdf"
142
+ )
143
+ )
144
+ obj.fill({"signature": os.path.join(image_samples, "vertical_image.jpg")})
145
+
146
+ request.config.results["expected_path"] = expected_path
147
+ request.config.results["stream"] = obj.read()
148
+
149
+ expected = f.read()
150
+
151
+ if os.name != "nt":
152
+ assert len(obj.read()) == len(expected)
153
+ assert obj.read() == expected
154
+
155
+
156
+ def test_fill_vertical_image_not_preserve_aspect_ratio(
157
+ pdf_samples, image_samples, request
158
+ ):
159
+ expected_path = os.path.join(
160
+ pdf_samples,
161
+ "signature",
162
+ "test_fill_vertical_image_not_preserve_aspect_ratio.pdf",
163
+ )
164
+ with open(expected_path, "rb+") as f:
165
+ obj = PdfWrapper(
166
+ os.path.join(
167
+ pdf_samples, "signature", "sample_template_with_signature_overlap.pdf"
168
+ )
169
+ )
170
+ obj.widgets["signature"].preserve_aspect_ratio = False
171
+ obj.fill({"signature": os.path.join(image_samples, "vertical_image.jpg")})
172
+
173
+ request.config.results["expected_path"] = expected_path
174
+ request.config.results["stream"] = obj.read()
175
+
176
+ expected = f.read()
177
+
178
+ if os.name != "nt":
179
+ assert len(obj.read()) == len(expected)
180
+ assert obj.read() == expected
@@ -1,8 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- """Contains image field middleware."""
3
-
4
- from .signature import Signature
5
-
6
-
7
- class Image(Signature):
8
- """A class to represent an image field widget."""
@@ -1,61 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- import os
4
-
5
- from PyPDFForm import PdfWrapper
6
-
7
-
8
- def test_fill_signature(pdf_samples, image_samples, request):
9
- expected_path = os.path.join(pdf_samples, "signature", "test_fill_signature.pdf")
10
- with open(expected_path, "rb+") as f:
11
- obj = PdfWrapper(
12
- os.path.join(pdf_samples, "signature", "sample_template_with_signature.pdf")
13
- ).fill({"signature": os.path.join(image_samples, "sample_signature.png")})
14
-
15
- request.config.results["expected_path"] = expected_path
16
- request.config.results["stream"] = obj.read()
17
-
18
- expected = f.read()
19
-
20
- if os.name != "nt":
21
- assert len(obj.read()) == len(expected)
22
- assert obj.read() == expected
23
-
24
-
25
- def test_signature_schema(pdf_samples):
26
- obj = PdfWrapper(
27
- os.path.join(pdf_samples, "signature", "sample_template_with_signature.pdf")
28
- )
29
-
30
- assert obj.widgets["signature"].schema_definition == {"type": "string"}
31
-
32
-
33
- def test_signature_sample_value(pdf_samples):
34
- obj = PdfWrapper(
35
- os.path.join(pdf_samples, "signature", "sample_template_with_signature.pdf")
36
- )
37
-
38
- assert obj.widgets["signature"].sample_value == os.path.expanduser(
39
- "~/Downloads/sample_image.jpg"
40
- )
41
-
42
-
43
- def test_fill_signature_overlap(pdf_samples, image_samples, request):
44
- expected_path = os.path.join(
45
- pdf_samples, "signature", "test_fill_signature_overlap.pdf"
46
- )
47
- with open(expected_path, "rb+") as f:
48
- obj = PdfWrapper(
49
- os.path.join(
50
- pdf_samples, "signature", "sample_template_with_signature_overlap.pdf"
51
- )
52
- ).fill({"signature": os.path.join(image_samples, "sample_signature.png")})
53
-
54
- request.config.results["expected_path"] = expected_path
55
- request.config.results["stream"] = obj.read()
56
-
57
- expected = f.read()
58
-
59
- if os.name != "nt":
60
- assert len(obj.read()) == len(expected)
61
- assert obj.read() == expected
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes