PyPDFForm 1.4.31__py3-none-any.whl → 1.4.33__py3-none-any.whl

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/__init__.py CHANGED
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """Contains any object users might need."""
3
3
 
4
- __version__ = "1.4.31"
4
+ __version__ = "1.4.33"
5
5
 
6
6
  from .wrapper import FormWrapper, PdfWrapper
7
7
 
PyPDFForm/image.py CHANGED
@@ -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")
PyPDFForm/patterns.py CHANGED
@@ -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, Parent, Q, Sig,
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
@@ -158,3 +158,24 @@ def simple_flatten_generic(annot: DictionaryObject) -> None:
158
158
  annot[NameObject(Ff)] = NumberObject(
159
159
  int(annot.get(NameObject(Ff), 0)) | READ_ONLY # noqa
160
160
  )
161
+
162
+
163
+ def update_created_text_field_alignment(annot: DictionaryObject, val: int) -> None:
164
+ """Patterns to update text alignment for text annotations created by the library."""
165
+
166
+ annot[NameObject(Q)] = NumberObject(val)
167
+
168
+
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
+ }
PyPDFForm/widgets/base.py CHANGED
@@ -2,12 +2,16 @@
2
2
  """Contains base class for all widgets to create."""
3
3
 
4
4
  from io import BytesIO
5
- from typing import List
5
+ from typing import List, cast
6
6
 
7
- from pypdf import PdfReader
7
+ from pypdf import PdfReader, PdfWriter
8
+ from pypdf.generic import DictionaryObject
8
9
  from reportlab.lib.colors import Color
9
10
  from reportlab.pdfgen.canvas import Canvas
10
11
 
12
+ from ..constants import Annots
13
+ from ..patterns import NON_ACRO_FORM_PARAM_TO_FUNC
14
+ from ..template import get_widget_key
11
15
  from ..utils import stream_to_io
12
16
 
13
17
 
@@ -16,6 +20,7 @@ class Widget:
16
20
 
17
21
  USER_PARAMS = []
18
22
  COLOR_PARAMS = []
23
+ ALLOWED_NON_ACRO_FORM_PARAMS = []
19
24
  NONE_DEFAULTS = []
20
25
  ACRO_FORM_FUNC = ""
21
26
 
@@ -36,6 +41,7 @@ class Widget:
36
41
  "x": x,
37
42
  "y": y,
38
43
  }
44
+ self.non_acro_form_params = []
39
45
 
40
46
  for each in self.USER_PARAMS:
41
47
  user_input, param = each
@@ -51,6 +57,12 @@ class Widget:
51
57
  elif user_input in self.NONE_DEFAULTS:
52
58
  self.acro_form_params[param] = None
53
59
 
60
+ for each in self.ALLOWED_NON_ACRO_FORM_PARAMS:
61
+ if each in kwargs:
62
+ self.non_acro_form_params.append(
63
+ ((type(self).__name__, each), kwargs.get(each))
64
+ )
65
+
54
66
  def watermarks(self, stream: bytes) -> List[bytes]:
55
67
  """Returns a list of watermarks after creating the widget."""
56
68
 
@@ -76,3 +88,26 @@ class Widget:
76
88
  watermark.read() if i == self.page_number - 1 else b""
77
89
  for i in range(page_count)
78
90
  ]
91
+
92
+
93
+ def handle_non_acro_form_params(pdf: bytes, key: str, params: list) -> bytes:
94
+ """Handles non acro form parameters when creating a widget."""
95
+
96
+ pdf_file = PdfReader(stream_to_io(pdf))
97
+ out = PdfWriter()
98
+ out.append(pdf_file)
99
+
100
+ for page in out.pages:
101
+ for annot in page.get(Annots, []): # noqa
102
+ annot = cast(DictionaryObject, annot.get_object())
103
+ _key = get_widget_key(annot.get_object())
104
+
105
+ if _key == key:
106
+ for param in params:
107
+ if param[0] in NON_ACRO_FORM_PARAM_TO_FUNC:
108
+ NON_ACRO_FORM_PARAM_TO_FUNC[param[0]](annot, param[1])
109
+
110
+ with BytesIO() as f:
111
+ out.write(f)
112
+ f.seek(0)
113
+ return f.read()
PyPDFForm/widgets/text.py CHANGED
@@ -19,5 +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", "multiline"]
22
23
  NONE_DEFAULTS = ["max_length"]
23
24
  ACRO_FORM_FUNC = "textfield"
PyPDFForm/wrapper.py CHANGED
@@ -22,6 +22,7 @@ from .template import (build_widgets, dropdown_to_text,
22
22
  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
+ from .widgets.base import handle_non_acro_form_params
25
26
  from .widgets.checkbox import CheckBoxWidget
26
27
  from .widgets.dropdown import DropdownWidget
27
28
  from .widgets.text import TextWidget
@@ -213,11 +214,15 @@ class PdfWrapper(FormWrapper):
213
214
  if _class is None:
214
215
  return self
215
216
 
216
- watermarks = _class(
217
- name=name, page_number=page_number, x=x, y=y, **kwargs
218
- ).watermarks(self.read())
217
+ obj = _class(name=name, page_number=page_number, x=x, y=y, **kwargs)
218
+ watermarks = obj.watermarks(self.read())
219
219
 
220
220
  self.stream = merge_watermarks_with_pdf(self.read(), watermarks)
221
+ if obj.non_acro_form_params:
222
+ self.stream = handle_non_acro_form_params(
223
+ self.stream, name, obj.non_acro_form_params
224
+ )
225
+
221
226
  new_widgets = build_widgets(self.read())
222
227
  for k, v in self.widgets.items():
223
228
  if k in new_widgets:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyPDFForm
3
- Version: 1.4.31
3
+ Version: 1.4.33
4
4
  Summary: The Python library for PDF forms.
5
5
  Home-page: https://github.com/chinapandaman/PyPDFForm
6
6
  Author: Jinge Li
@@ -1,15 +1,15 @@
1
- PyPDFForm/__init__.py,sha256=pRovsD1TN9FVIkHD1qURZWnJ9SMefn8yY8jivZI5Tzs,179
1
+ PyPDFForm/__init__.py,sha256=nGB4hFyhtEP1Yax2cCeP4M9Pj6qTiF2ENvyTcwe_MTA,179
2
2
  PyPDFForm/adapter.py,sha256=WFP-r8FLeKa-D9mFO9AphOcuXgyeAI1Ak0d-YsqxsK4,861
3
3
  PyPDFForm/constants.py,sha256=FMsdOvnYpchEfki3gf_Y2Wj1SThUxMzsPbOx12_S1GA,1738
4
4
  PyPDFForm/coordinate.py,sha256=V_ZZQ1pXtVPAyfMJCX7fKoEimK7XwX6bU3VQ0nKOhQA,7314
5
5
  PyPDFForm/filler.py,sha256=pgMA7EC8axKUganmbk7X1uDdsb4OQQFoiI85td3pOO4,7486
6
6
  PyPDFForm/font.py,sha256=TbFLY4G72d7cQ3VG2g4HaYKROzQPQUmh6-8ynN6hzXY,5713
7
- PyPDFForm/image.py,sha256=0GV8PFgY5oLJFHmhPD1fG-_5SBEO7jVLLtxCc_Uodfo,1143
8
- PyPDFForm/patterns.py,sha256=p33mDZKxQN2h8GgVnZGXNolWPzofky1llIpstjnL3eI,4318
7
+ PyPDFForm/image.py,sha256=sjXPg9fjenNFj12a321xHX6JvuJs6PJRGLzpSNw5mVU,1180
8
+ PyPDFForm/patterns.py,sha256=9DFI-2cVZxzJKWmWBjK-dRSeAMNQr7ovHmw1YevrkiQ,5028
9
9
  PyPDFForm/template.py,sha256=a9rDzhHHfnYFo8cDnHnRE9UriUykXvrsyFKVGq9DYd0,13166
10
10
  PyPDFForm/utils.py,sha256=9omR-oT3OdZqioxpiGqA9_P0GSFC6mg4Y1xrLvWOzkk,4309
11
11
  PyPDFForm/watermark.py,sha256=L4LfzjjyJ6TDq9ad2dbtQYheBOic1_oZ7smhFFekNog,4725
12
- PyPDFForm/wrapper.py,sha256=Rrb7PhbAWEWOwOX3Z5m-TEfTZfCnEY4AsWg7ashPe7c,9498
12
+ PyPDFForm/wrapper.py,sha256=EC5ugli6Nj1q0un8je3f5xtRIfIxDSf9YrG50QipTPk,9715
13
13
  PyPDFForm/middleware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  PyPDFForm/middleware/base.py,sha256=p-3XsZJ6d7ai2JFLF7LisMWi9yzM3pN7CsFECxtEoI0,751
15
15
  PyPDFForm/middleware/checkbox.py,sha256=3-9CMhhtyO9U6lLXDciW-59ng8uS4m6_clPB02mzV9c,1317
@@ -19,12 +19,12 @@ PyPDFForm/middleware/radio.py,sha256=ehaJoehEzZqxDVb5A6fJkYludeBmtV2Z5GZUPPfUWng
19
19
  PyPDFForm/middleware/signature.py,sha256=m7tNvGZ7fQ0yuVKzSlLbNQ2IILo1GDnjzMDzMnYCKVM,1104
20
20
  PyPDFForm/middleware/text.py,sha256=LNY_9Y2tq3uQEneKoL4vgrJtFTva0KSYzuuzDb5METM,1055
21
21
  PyPDFForm/widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
- PyPDFForm/widgets/base.py,sha256=mb8pKLu9d80pr-175T8f0FI1kWo2IOJ5am2_zRQKUl0,2075
22
+ PyPDFForm/widgets/base.py,sha256=Re251Gxk22hvPE-jIlM3UMalcVGfP_nVJK3WAPYne78,3288
23
23
  PyPDFForm/widgets/checkbox.py,sha256=MGB6NGI-XMBz4j2erykgYOCd1pswvthuQ6UFowQOd4o,503
24
24
  PyPDFForm/widgets/dropdown.py,sha256=2_R5xcLUWAL0G4raVgWWtE7TJdiWJITay-Gtl8YI2QI,705
25
- PyPDFForm/widgets/text.py,sha256=x8EglZLYoI9osN9wORLRYoR7lebrpj-wx38QiRH7H1A,629
26
- PyPDFForm-1.4.31.dist-info/LICENSE,sha256=43awmYkI6opyTpg19me731iO1WfXZwViqb67oWtCsFY,1065
27
- PyPDFForm-1.4.31.dist-info/METADATA,sha256=gnvLbIDdwFs1FaYpgGx2rgjTMEA1KeFHngG72BH-CtU,4151
28
- PyPDFForm-1.4.31.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
29
- PyPDFForm-1.4.31.dist-info/top_level.txt,sha256=GQQKuWqPUjT9YZqwK95NlAQzxjwoQrsxQ8ureM8lWOY,10
30
- PyPDFForm-1.4.31.dist-info/RECORD,,
25
+ PyPDFForm/widgets/text.py,sha256=sCB8CQAjh30QOGr8FTIDSk3X6dXSHJztOz6YkKEBDss,691
26
+ PyPDFForm-1.4.33.dist-info/LICENSE,sha256=43awmYkI6opyTpg19me731iO1WfXZwViqb67oWtCsFY,1065
27
+ PyPDFForm-1.4.33.dist-info/METADATA,sha256=AfmRvobo1vnrBt5wic57TLhpDxoXlz3MOvNQws7vGKQ,4151
28
+ PyPDFForm-1.4.33.dist-info/WHEEL,sha256=Mdi9PDNwEZptOjTlUcAth7XJDFtKrHYaQMPulZeBCiQ,91
29
+ PyPDFForm-1.4.33.dist-info/top_level.txt,sha256=GQQKuWqPUjT9YZqwK95NlAQzxjwoQrsxQ8ureM8lWOY,10
30
+ PyPDFForm-1.4.33.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (70.3.0)
2
+ Generator: setuptools (73.0.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5