PyPDFForm 5.5.0__tar.gz → 5.5.1__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.
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PKG-INFO +1 -1
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/__init__.py +1 -1
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/template.py +30 -4
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/wrapper.py +20 -19
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm.egg-info/PKG-INFO +1 -1
- {pypdfform-5.5.0 → pypdfform-5.5.1}/LICENSE +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/cli/__init__.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/cli/common.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/cli/create.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/cli/entry.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/cli/inspect.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/cli/remove.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/cli/root.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/cli/schemas/__init__.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/cli/schemas/create.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/cli/schemas/update.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/cli/update.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/__init__.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/adapter.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/annotations/__init__.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/annotations/base.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/annotations/link.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/annotations/stamp.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/annotations/text.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/annotations/text_markup.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/assets/__init__.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/assets/bedrock.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/assets/blank.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/constants.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/coordinate.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/deprecation.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/egress.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/filler.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/font.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/hooks.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/image.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/middleware/__init__.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/middleware/base.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/middleware/checkbox.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/middleware/dropdown.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/middleware/image.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/middleware/radio.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/middleware/signature.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/middleware/text.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/patterns.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/raw/__init__.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/raw/circle.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/raw/ellipse.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/raw/image.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/raw/line.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/raw/rect.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/raw/text.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/types.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/utils.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/watermark.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/widgets/__init__.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/widgets/base.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/widgets/checkbox.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/widgets/dropdown.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/widgets/image.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/widgets/radio.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/widgets/signature.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm/lib/widgets/text.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm.egg-info/SOURCES.txt +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm.egg-info/dependency_links.txt +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm.egg-info/entry_points.txt +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm.egg-info/requires.txt +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/PyPDFForm.egg-info/top_level.txt +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/README.md +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/pyproject.toml +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/setup.cfg +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/tests/test_bulk_create_fields.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/tests/test_create_widget.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/tests/test_draw_elements.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/tests/test_dropdown.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/tests/test_extract_middleware_attributes.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/tests/test_fill_max_length_text_field.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/tests/test_font_widths.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/tests/test_functional.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/tests/test_generate_appearance_streams.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/tests/test_js.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/tests/test_need_appearances.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/tests/test_paragraph.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/tests/test_signature.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/tests/test_use_full_widget_name.py +0 -0
- {pypdfform-5.5.0 → pypdfform-5.5.1}/tests/test_widget_attr_trigger.py +0 -0
|
@@ -64,11 +64,12 @@ def get_metadata(pdf: bytes) -> dict:
|
|
|
64
64
|
Returns:
|
|
65
65
|
dict: A dictionary containing the PDF's metadata.
|
|
66
66
|
"""
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
result = {}
|
|
68
|
+
if pdf:
|
|
69
|
+
reader = PdfReader(BytesIO(pdf))
|
|
70
|
+
result = reader.metadata or {}
|
|
69
71
|
|
|
70
|
-
|
|
71
|
-
return reader.metadata or {}
|
|
72
|
+
return result
|
|
72
73
|
|
|
73
74
|
|
|
74
75
|
def get_title(pdf: bytes) -> str | None:
|
|
@@ -84,6 +85,31 @@ def get_title(pdf: bytes) -> str | None:
|
|
|
84
85
|
return get_metadata(pdf).get(Title)
|
|
85
86
|
|
|
86
87
|
|
|
88
|
+
@lru_cache(maxsize=128)
|
|
89
|
+
def get_on_open_javascript(pdf: bytes) -> str | None:
|
|
90
|
+
"""
|
|
91
|
+
Retrieves the JavaScript configured to run when a PDF is opened.
|
|
92
|
+
|
|
93
|
+
Results are cached by PDF stream. Only a document-catalog `/OpenAction`
|
|
94
|
+
whose action type is JavaScript is returned.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
pdf (bytes): The PDF stream to inspect for a document-open action.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
str | None: The JavaScript source, or None when the stream is empty or
|
|
101
|
+
does not contain a JavaScript document-open action.
|
|
102
|
+
"""
|
|
103
|
+
result = None
|
|
104
|
+
if pdf:
|
|
105
|
+
reader = PdfReader(BytesIO(pdf))
|
|
106
|
+
root_object = reader.root_object
|
|
107
|
+
if OpenAction in root_object and root_object[OpenAction].get(S) == JavaScript:
|
|
108
|
+
result = root_object[OpenAction].get(JS)
|
|
109
|
+
|
|
110
|
+
return result
|
|
111
|
+
|
|
112
|
+
|
|
87
113
|
def set_metadata(pdf: bytes, metadata: dict) -> bytes:
|
|
88
114
|
"""
|
|
89
115
|
Merges metadata into a PDF's existing document metadata.
|
|
@@ -56,7 +56,7 @@ from .middleware.text import Text
|
|
|
56
56
|
from .template import (
|
|
57
57
|
build_widgets,
|
|
58
58
|
create_annotations,
|
|
59
|
-
|
|
59
|
+
get_on_open_javascript,
|
|
60
60
|
get_title,
|
|
61
61
|
remove_widgets_by_keys,
|
|
62
62
|
set_on_open_javascript,
|
|
@@ -110,7 +110,7 @@ class PdfWrapper:
|
|
|
110
110
|
- `need_appearances` (bool): Whether to set the `NeedAppearances` flag in the PDF's AcroForm dictionary.
|
|
111
111
|
- `generate_appearance_streams` (bool): Whether to explicitly generate appearance streams for all form fields using pikepdf.
|
|
112
112
|
- `preserve_metadata` (bool): Deprecated compatibility attribute;
|
|
113
|
-
input PDF metadata is
|
|
113
|
+
input PDF metadata is preserved automatically.
|
|
114
114
|
- `title` (str | None): The title stored in the PDF's document
|
|
115
115
|
metadata. A non-None value replaces the existing title; None
|
|
116
116
|
preserves it.
|
|
@@ -134,11 +134,12 @@ class PdfWrapper:
|
|
|
134
134
|
Constructor method for the `PdfWrapper` class.
|
|
135
135
|
|
|
136
136
|
Initializes a new `PdfWrapper` object with the given template PDF and optional keyword arguments.
|
|
137
|
-
The template is normalized to bytes
|
|
138
|
-
and the
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
137
|
+
The template is normalized to bytes and existing widgets are loaded immediately.
|
|
138
|
+
The title and document-open JavaScript remain in the PDF stream and are read
|
|
139
|
+
lazily when their properties are accessed. A non-None `title` keyword updates
|
|
140
|
+
the title in the PDF stream; None leaves the template's title unchanged. The
|
|
141
|
+
deprecated `preserve_metadata` keyword is accepted for backward compatibility
|
|
142
|
+
and emits a deprecation warning. Enabling
|
|
142
143
|
`generate_appearance_streams` also enables `need_appearances`.
|
|
143
144
|
|
|
144
145
|
Args:
|
|
@@ -158,9 +159,6 @@ class PdfWrapper:
|
|
|
158
159
|
self.widgets = {}
|
|
159
160
|
|
|
160
161
|
self._version = None
|
|
161
|
-
self._metadata = get_metadata(self._read())
|
|
162
|
-
self._title = get_title(self._read())
|
|
163
|
-
self._on_open_javascript = None
|
|
164
162
|
self._available_fonts = {} # for setting /F1
|
|
165
163
|
self._available_fonts_loaded = None # for lazy loading fonts
|
|
166
164
|
self._font_register_events = [] # for reregister
|
|
@@ -332,11 +330,15 @@ class PdfWrapper:
|
|
|
332
330
|
"""
|
|
333
331
|
Gets the title stored in the PDF's document metadata.
|
|
334
332
|
|
|
333
|
+
The title is read lazily from the current PDF stream. Metadata extraction
|
|
334
|
+
is cached for each distinct stream.
|
|
335
|
+
|
|
335
336
|
Returns:
|
|
336
337
|
str | None: The current document title, or None when no title exists.
|
|
337
338
|
"""
|
|
338
339
|
|
|
339
|
-
|
|
340
|
+
result = get_title(self._read())
|
|
341
|
+
return str(result) if result is not None else None
|
|
340
342
|
|
|
341
343
|
@title.setter
|
|
342
344
|
def title(self, value: str | None) -> None:
|
|
@@ -353,7 +355,6 @@ class PdfWrapper:
|
|
|
353
355
|
|
|
354
356
|
if value is not None:
|
|
355
357
|
self._stream = set_title(self._read(), value)
|
|
356
|
-
self._title = value
|
|
357
358
|
|
|
358
359
|
@property
|
|
359
360
|
def schema(self) -> dict:
|
|
@@ -468,17 +469,18 @@ class PdfWrapper:
|
|
|
468
469
|
@property
|
|
469
470
|
def on_open_javascript(self) -> str | None:
|
|
470
471
|
"""
|
|
471
|
-
|
|
472
|
+
Gets the JavaScript stored in the PDF's document-open action.
|
|
472
473
|
|
|
473
|
-
|
|
474
|
-
|
|
474
|
+
The script is read lazily from the current PDF stream, including an existing
|
|
475
|
+
JavaScript `/OpenAction` in the input template. Extraction is cached for each
|
|
476
|
+
distinct stream.
|
|
475
477
|
|
|
476
478
|
Returns:
|
|
477
|
-
str | None: The
|
|
478
|
-
|
|
479
|
+
str | None: The current document-open JavaScript, or None when the PDF
|
|
480
|
+
does not contain a JavaScript document-open action.
|
|
479
481
|
"""
|
|
480
482
|
|
|
481
|
-
return self.
|
|
483
|
+
return get_on_open_javascript(self._read())
|
|
482
484
|
|
|
483
485
|
@on_open_javascript.setter
|
|
484
486
|
def on_open_javascript(self, value: str | TextIO) -> None:
|
|
@@ -496,7 +498,6 @@ class PdfWrapper:
|
|
|
496
498
|
|
|
497
499
|
script = fp_or_f_obj_or_f_content_to_content(value)
|
|
498
500
|
self._stream = set_on_open_javascript(self._read(), script)
|
|
499
|
-
self._on_open_javascript = script
|
|
500
501
|
|
|
501
502
|
def read(self) -> bytes:
|
|
502
503
|
"""
|
|
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
|
|
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
|
|
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
|