shellscripts 0.23.1__py3-none-any.whl → 0.24.0__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.
- shell_scripts/__init__.py +1 -1
- shell_scripts/commands/pdf_split_by_format.py +44 -1
- shell_scripts/commands/pdf_split_by_toc.py +44 -1
- {shellscripts-0.23.1.dist-info → shellscripts-0.24.0.dist-info}/METADATA +2 -2
- {shellscripts-0.23.1.dist-info → shellscripts-0.24.0.dist-info}/RECORD +9 -9
- {shellscripts-0.23.1.dist-info → shellscripts-0.24.0.dist-info}/WHEEL +0 -0
- {shellscripts-0.23.1.dist-info → shellscripts-0.24.0.dist-info}/entry_points.txt +0 -0
- {shellscripts-0.23.1.dist-info → shellscripts-0.24.0.dist-info}/licenses/LICENSE +0 -0
- {shellscripts-0.23.1.dist-info → shellscripts-0.24.0.dist-info}/top_level.txt +0 -0
shell_scripts/__init__.py
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
+
import errno
|
|
2
3
|
import os
|
|
3
4
|
import re
|
|
5
|
+
import shutil
|
|
4
6
|
import subprocess
|
|
5
7
|
import tempfile
|
|
6
8
|
|
|
@@ -102,7 +104,48 @@ def _extract_toc_for_range(data_file, start, end):
|
|
|
102
104
|
return "\n".join(result)
|
|
103
105
|
|
|
104
106
|
|
|
107
|
+
def _promote_temp_output(temp_output, output_file):
|
|
108
|
+
"""
|
|
109
|
+
@brief Promote one pdftk-produced temporary artifact onto the final output path.
|
|
110
|
+
@details Attempts same-device atomic replacement via `os.replace`. On
|
|
111
|
+
`OSError` with `errno.EXDEV` (temporary directory and output directory
|
|
112
|
+
located on different filesystems), falls back to `shutil.move`, which
|
|
113
|
+
copies the artifact content and removes the temporary source. All other
|
|
114
|
+
`OSError` values propagate unchanged to preserve pre-existing failure
|
|
115
|
+
semantics. Time complexity O(1) for same-device renames, O(n) over file
|
|
116
|
+
size for the cross-device copy fallback.
|
|
117
|
+
@param temp_output {str} Temporary artifact path produced by the external tool chain.
|
|
118
|
+
@param output_file {str} Final chunk path that must receive the artifact content.
|
|
119
|
+
@return {None} Applies destination filesystem mutation.
|
|
120
|
+
@throws {OSError} Propagated for non-EXDEV replacement failures.
|
|
121
|
+
@satisfies REQ-031, REQ-032
|
|
122
|
+
"""
|
|
123
|
+
try:
|
|
124
|
+
os.replace(temp_output, output_file)
|
|
125
|
+
except OSError as error:
|
|
126
|
+
if error.errno != errno.EXDEV:
|
|
127
|
+
raise
|
|
128
|
+
shutil.move(temp_output, output_file)
|
|
129
|
+
|
|
130
|
+
|
|
105
131
|
def _apply_toc(output_file, toc_content):
|
|
132
|
+
"""
|
|
133
|
+
@brief Reapply in-range TOC data to one generated chunk file.
|
|
134
|
+
@details Writes `toc_content` into a temporary `.info` payload, prepares
|
|
135
|
+
temporary PDF artifacts, strips object streams from `output_file` via
|
|
136
|
+
`qpdf`, rebuilds the chunk with TOC metadata via `pdftk update_info`,
|
|
137
|
+
and promotes the artifact onto `output_file` through
|
|
138
|
+
`_promote_temp_output` so a temporary directory on a different
|
|
139
|
+
filesystem cannot silently drop the chunk TOC. Tool-chain failures are
|
|
140
|
+
contained without aborting the split loop. Time complexity O(m) over
|
|
141
|
+
TOC content size plus external process latency.
|
|
142
|
+
@param output_file {str} Generated chunk path receiving the TOC metadata.
|
|
143
|
+
@param toc_content {str} Range-filtered pdftk dump-data bookmark payload.
|
|
144
|
+
@return {None} Mutates `output_file` content on success.
|
|
145
|
+
@throws {OSError} Propagated when temporary payload creation, unlink, or
|
|
146
|
+
non-EXDEV promotion fails.
|
|
147
|
+
@satisfies REQ-032
|
|
148
|
+
"""
|
|
106
149
|
if not toc_content.strip():
|
|
107
150
|
return
|
|
108
151
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".info", delete=False) as f:
|
|
@@ -124,7 +167,7 @@ def _apply_toc(output_file, toc_content):
|
|
|
124
167
|
capture_output=True,
|
|
125
168
|
)
|
|
126
169
|
if r2.returncode == 0:
|
|
127
|
-
|
|
170
|
+
_promote_temp_output(with_toc, output_file)
|
|
128
171
|
else:
|
|
129
172
|
os.unlink(with_toc)
|
|
130
173
|
print(f" [!] Warning: unable to update TOC for '{output_file}'.")
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
+
import errno
|
|
2
3
|
import os
|
|
3
4
|
import re
|
|
5
|
+
import shutil
|
|
4
6
|
import subprocess
|
|
5
7
|
import tempfile
|
|
6
8
|
|
|
@@ -76,7 +78,48 @@ def _sanitize_title(title):
|
|
|
76
78
|
return safe.strip("-")
|
|
77
79
|
|
|
78
80
|
|
|
81
|
+
def _promote_temp_output(temp_output, output_file):
|
|
82
|
+
"""
|
|
83
|
+
@brief Promote one pdftk-produced temporary artifact onto the final output path.
|
|
84
|
+
@details Attempts same-device atomic replacement via `os.replace`. On
|
|
85
|
+
`OSError` with `errno.EXDEV` (temporary directory and output directory
|
|
86
|
+
located on different filesystems), falls back to `shutil.move`, which
|
|
87
|
+
copies the artifact content and removes the temporary source. All other
|
|
88
|
+
`OSError` values propagate unchanged to preserve pre-existing failure
|
|
89
|
+
semantics. Time complexity O(1) for same-device renames, O(n) over file
|
|
90
|
+
size for the cross-device copy fallback.
|
|
91
|
+
@param temp_output {str} Temporary artifact path produced by the external tool chain.
|
|
92
|
+
@param output_file {str} Final chunk path that must receive the artifact content.
|
|
93
|
+
@return {None} Applies destination filesystem mutation.
|
|
94
|
+
@throws {OSError} Propagated for non-EXDEV replacement failures.
|
|
95
|
+
@satisfies REQ-031, REQ-032
|
|
96
|
+
"""
|
|
97
|
+
try:
|
|
98
|
+
os.replace(temp_output, output_file)
|
|
99
|
+
except OSError as error:
|
|
100
|
+
if error.errno != errno.EXDEV:
|
|
101
|
+
raise
|
|
102
|
+
shutil.move(temp_output, output_file)
|
|
103
|
+
|
|
104
|
+
|
|
79
105
|
def _apply_toc_to_file(output_file, toc_content):
|
|
106
|
+
"""
|
|
107
|
+
@brief Reapply rebased TOC data to one generated chunk file.
|
|
108
|
+
@details Writes `toc_content` into a temporary `.info` payload, strips
|
|
109
|
+
object streams from `output_file` via `qpdf`, rebuilds the chunk with
|
|
110
|
+
TOC metadata via `pdftk update_info`, and promotes the artifact onto
|
|
111
|
+
`output_file` through `_promote_temp_output` so a temporary directory
|
|
112
|
+
on a different filesystem cannot crash chunk generation. Emits a
|
|
113
|
+
warning and keeps the original chunk when the tool chain fails.
|
|
114
|
+
Time complexity O(m) over TOC content size plus external process
|
|
115
|
+
latency.
|
|
116
|
+
@param output_file {str} Generated chunk path receiving the TOC metadata.
|
|
117
|
+
@param toc_content {str} Rebased pdftk dump-data bookmark payload.
|
|
118
|
+
@return {None} Mutates `output_file` content on success.
|
|
119
|
+
@throws {OSError} Propagated when temporary payload creation, unlink, or
|
|
120
|
+
non-EXDEV promotion fails.
|
|
121
|
+
@satisfies REQ-031
|
|
122
|
+
"""
|
|
80
123
|
if not toc_content.strip():
|
|
81
124
|
return
|
|
82
125
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".info", delete=False) as f:
|
|
@@ -95,7 +138,7 @@ def _apply_toc_to_file(output_file, toc_content):
|
|
|
95
138
|
capture_output=True,
|
|
96
139
|
)
|
|
97
140
|
if r2.returncode == 0:
|
|
98
|
-
|
|
141
|
+
_promote_temp_output(with_toc, output_file)
|
|
99
142
|
else:
|
|
100
143
|
if os.path.exists(with_toc):
|
|
101
144
|
os.unlink(with_toc)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: shellscripts
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.24.0
|
|
4
4
|
Summary: Execute useful shell scripts via an uvx-compatible CLI interface.
|
|
5
5
|
Author: Francesco Rolando
|
|
6
6
|
License-Expression: GPL-3.0-only
|
|
@@ -31,7 +31,7 @@ Dynamic: license-file
|
|
|
31
31
|
> * **No Support or Feature Requests:** Please **do not** open issues, bug reports, or feature requests. They will not be addressed or accepted at this stage of development.
|
|
32
32
|
> * **No Warranty:** This software is provided **"AS IS"**, without warranty of any kind, express or implied. You may use it strictly for **testing and evaluation purposes** at your own sole risk.
|
|
33
33
|
|
|
34
|
-
# s/shellScripts (0.
|
|
34
|
+
# s/shellScripts (0.24.0)
|
|
35
35
|
|
|
36
36
|
<p align="center">
|
|
37
37
|
<img src="https://img.shields.io/badge/python-3.11%2B-3776AB?style=flat-square&logo=python&logoColor=white" alt="Python 3.11+">
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
shell_scripts/__init__.py,sha256=
|
|
1
|
+
shell_scripts/__init__.py,sha256=a6rN3qPobydw-A4eFoUNo6Srdf1OtkoPSloLLg3Yuic,96
|
|
2
2
|
shell_scripts/__main__.py,sha256=-wEmwKTfeY5TphAH82E38XRPoB4KT5QDLDgRZz84PTs,83
|
|
3
3
|
shell_scripts/config.py,sha256=YUs8QWsZ31lJPrMpFqvn7YLQdseQnlaiu7OXcXsKdEw,12640
|
|
4
4
|
shell_scripts/core.py,sha256=rhgy9xduzkujsjD4NRL2AYvtNI3yTVnPThzEAzyMWUM,11204
|
|
@@ -22,8 +22,8 @@ shell_scripts/commands/kiro.py,sha256=NuD2Zx76azDQAWbJ8YcewshEogLmrd-Avu9feisqHy
|
|
|
22
22
|
shell_scripts/commands/opencode.py,sha256=64I3IHrliAZ7C4jTU4WLxQcJHJohJcKex09yhegWUoc,1900
|
|
23
23
|
shell_scripts/commands/pdf_crop.py,sha256=VliRAMHMjnSQK9mZhNoghftZAVGZeJG6xhrihcuuawQ,15135
|
|
24
24
|
shell_scripts/commands/pdf_merge.py,sha256=vTTlUv8oVYUo9U45b4yUpK4x0unIwctgXV7g5exvihc,5996
|
|
25
|
-
shell_scripts/commands/pdf_split_by_format.py,sha256=
|
|
26
|
-
shell_scripts/commands/pdf_split_by_toc.py,sha256=
|
|
25
|
+
shell_scripts/commands/pdf_split_by_format.py,sha256=yG4Vbv1oPaHEElMK-TUqDVoqM6G1O3UY0nVcO5RsqMY,9789
|
|
26
|
+
shell_scripts/commands/pdf_split_by_toc.py,sha256=Q9VNqBoPQQOd4Dm14dm2S8W2JPc3I3WuhQYMxXKX55Q,8848
|
|
27
27
|
shell_scripts/commands/pdf_tiler_090.py,sha256=1eLCw9rqGN8LELB5lBvx6xfaTYc4Kci5YDK2EvnHG6E,1781
|
|
28
28
|
shell_scripts/commands/pdf_tiler_100.py,sha256=U-DlX_PJPHL2P2p0wvWMzb-XkxVYn5-Jb1vqlBzIAqA,1805
|
|
29
29
|
shell_scripts/commands/pdf_toc_clean.py,sha256=7GroNjVbOoh184AbYoqXSVdK_RHqA3y5urjkZ4lcJbw,5907
|
|
@@ -37,9 +37,9 @@ shell_scripts/commands/video2h265.py,sha256=Sr_UWGz_V77x4anmuy8kiWZv5I_AOFlV0WDn
|
|
|
37
37
|
shell_scripts/commands/view_cmd.py,sha256=qHEivQHZpZCTE3VSFP1ay2SuqgancQlEKxJcKtyeqNA,1827
|
|
38
38
|
shell_scripts/commands/vscode_cmd.py,sha256=Rkcjt5A1HMzqJoh2Yz9VRGoLP-L3qpRO5hkcSrzOmvA,1461
|
|
39
39
|
shell_scripts/commands/vsinsider_cmd.py,sha256=KTTv1cVpJO-u1ktxOE0W_o4AAmz20pAvkDtyhpU9XBg,1548
|
|
40
|
-
shellscripts-0.
|
|
41
|
-
shellscripts-0.
|
|
42
|
-
shellscripts-0.
|
|
43
|
-
shellscripts-0.
|
|
44
|
-
shellscripts-0.
|
|
45
|
-
shellscripts-0.
|
|
40
|
+
shellscripts-0.24.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
41
|
+
shellscripts-0.24.0.dist-info/METADATA,sha256=93w8nhYX9LfkcAQxSMCwdBYXNnkYdwjUgTjCG4HNIoo,10985
|
|
42
|
+
shellscripts-0.24.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
|
|
43
|
+
shellscripts-0.24.0.dist-info/entry_points.txt,sha256=9ICAgH87fxHBzi3f6JXIVcsPWzAKsCh4_1xS8JThQ0M,85
|
|
44
|
+
shellscripts-0.24.0.dist-info/top_level.txt,sha256=7bDVqjcR5CfCCArCP4X4e9gYJ-ua8z-GfQeHbAo8rCY,14
|
|
45
|
+
shellscripts-0.24.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|