Skip to content

Commit c7ce1e3

Browse files
committed
Adding PDF Split application
1 parent ef03eb6 commit c7ce1e3

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed

code/pdf_split.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
from appJar import gui
2+
from PyPDF2 import PdfFileWriter, PdfFileReader
3+
from pathlib import Path
4+
5+
# Define all the functions needed to process the files
6+
7+
8+
def split_pages(input_file, page_range, out_file):
9+
""" Take a pdf file and copy a range of pages into a new pdf file
10+
11+
Args:
12+
input_file: The source PDF file
13+
page_range: A string containing a range of pages to copy: 1-3,4
14+
out_file: File name for the destination PDF
15+
"""
16+
output = PdfFileWriter()
17+
input_pdf = PdfFileReader(open(input_file, "rb"))
18+
output_file = open(out_file, "wb")
19+
20+
# https://stackoverflow.com/questions/5704931/parse-string-of-integer-sets-with-intervals-to-list
21+
page_ranges = (x.split("-") for x in page_range.split(","))
22+
range_list = [i for r in page_ranges for i in range(int(r[0]), int(r[-1]) + 1)]
23+
24+
for p in range_list:
25+
# Need to subtract 1 because pages are 0 indexed
26+
try:
27+
output.addPage(input_pdf.getPage(p - 1))
28+
except IndexError:
29+
# Alert the user and stop adding pages
30+
app.infoBox("Info", "Range exceeded number of pages in input.\nFile will still be saved.")
31+
break
32+
output.write(output_file)
33+
34+
if(app.questionBox("File Save", "Output PDF saved. Do you want to quit?")):
35+
app.stop()
36+
37+
38+
def validate_inputs(input_file, output_dir, range, file_name):
39+
""" Verify that the input values provided by the user are valid
40+
41+
Args:
42+
input_file: The source PDF file
43+
output_dir: Directory to store the completed file
44+
range: File A string containing a range of pages to copy: 1-3,4
45+
file_name: Output name for the resulting PDF
46+
47+
Returns:
48+
True if error and False otherwise
49+
List of error messages
50+
"""
51+
errors = False
52+
error_msgs = []
53+
54+
# Make sure a PDF is selected
55+
if Path(input_file).suffix.upper() != ".PDF":
56+
errors = True
57+
error_msgs.append("Please select a PDF input file")
58+
59+
# Make sure a range is selected
60+
if len(range) < 1:
61+
errors = True
62+
error_msgs.append("Please enter a valid page range")
63+
64+
# Check for a valid directory
65+
if not(Path(output_dir)).exists():
66+
errors = True
67+
error_msgs.append("Please Select a valid output directory")
68+
69+
# Check for a file name
70+
if len(file_name) < 1:
71+
errors = True
72+
error_msgs.append("Please enter a file name")
73+
74+
return(errors, error_msgs)
75+
76+
77+
def press(button):
78+
""" Process a button press
79+
80+
Args:
81+
button: The name of the button. Either Process of Quit
82+
"""
83+
if button == "Process":
84+
src_file = app.getEntry("Input_File")
85+
dest_dir = app.getEntry("Output_Directory")
86+
page_range = app.getEntry("Page_Ranges")
87+
out_file = app.getEntry("Output_name")
88+
errors, error_msg = validate_inputs(src_file, dest_dir, page_range, out_file)
89+
if errors:
90+
app.errorBox("Error", "\n".join(error_msg), parent=None)
91+
else:
92+
split_pages(src_file, page_range, Path(dest_dir, out_file))
93+
else:
94+
app.stop()
95+
96+
# Create the GUI Window
97+
app = gui("PDF Splitter", useTtk=True)
98+
app.setTtkTheme("clam")
99+
print(app.getTtkThemes())
100+
app.setSize(500, 200)
101+
102+
# Add the interactive components
103+
app.addLabel("Choose Source PDF File")
104+
app.addFileEntry("Input_File")
105+
106+
app.addLabel("Select Output Directory")
107+
app.addDirectoryEntry("Output_Directory")
108+
109+
app.addLabel("Output file name")
110+
app.addEntry("Output_name")
111+
112+
app.addLabel("Page Ranges: 1,3,4-10")
113+
app.addEntry("Page_Ranges")
114+
115+
# link the buttons to the function called press
116+
app.addButtons(["Process", "Quit"], press)
117+
118+
# start the GUI
119+
app.go()

0 commit comments

Comments
 (0)