Bayhaqy commited on
Commit
1c827ff
1 Parent(s): ec10d58

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +26 -47
app.py CHANGED
@@ -28,18 +28,11 @@ st.caption("Created by Bayhaqy")
28
  st.markdown("This is tools for join and split file PDF")
29
 
30
  # Make folder for storing user uploads
31
- destination_folder = Path("downloads")
32
  destination_folder.mkdir(exist_ok=True, parents=True)
33
 
34
  # Defines what options are in the form
35
  class PDFMergeRequest(BaseModel):
36
- """
37
- This code snippet defines a class called PDFMergeRequest that inherits from BaseModel.
38
- It has a property called pdf_uploads which is an optional list of FileContent objects.
39
- The Field function is used to specify additional information about this property, such as its default value,
40
- alias, and description. In this case, the alias is set to "PDF File to Split" and the description is set
41
- to "PDF that needs to be split".
42
- """
43
  pdf_uploads: Optional[List[FileContent]] = Field(
44
  None,
45
  alias="PDF File to Split",
@@ -47,12 +40,6 @@ class PDFMergeRequest(BaseModel):
47
  )
48
 
49
  class PDFSplitRequest(BaseModel):
50
- """
51
- This code snippet defines a PDFSplitRequest class that inherits from BaseModel.
52
- It has two attributes: pages_per_pdf and pdf_upload. pages_per_pdf is an integer field with a default value of 1.
53
- pdf_upload is an optional field that can accept a FileContent object or None as its value.
54
- Both attributes have aliases and descriptions that provide additional information about their purpose.
55
- """
56
  pages_per_pdf: int = Field(
57
  1,
58
  alias="Pages per Split",
@@ -65,17 +52,9 @@ class PDFSplitRequest(BaseModel):
65
  )
66
 
67
  def stack_images(images):
68
- """
69
- Generate a stacked image by vertically stacking a list of input images.
70
-
71
- Parameters:
72
- - images (List[Image]): A list of input images to stack vertically.
73
-
74
- Returns:
75
- - output_image (Image): The output stacked image, with each input image vertically stacked on top of each other.
76
- """
77
  first_image = images[0]
78
- output_image = Image.new("RGB", (first_image.width, sum((image.height for image in images))))
79
  output_image.paste(first_image, (0, 0))
80
  starting_y_value = first_image.height
81
  for image in images[1:]:
@@ -84,23 +63,23 @@ def stack_images(images):
84
  return output_image
85
 
86
  # Radio buttons for selecting the file type
87
- pdf_output = ".pdf"
88
- jpg_output = ".jpg"
89
- png_output = ".png"
90
- #output_suffix = st.radio("Output File Type", [pdf_output, jpg_output, png_output], key="output_format")
91
  output_suffix = (pdf_output)
92
 
93
  # Add a heading
94
  st.markdown("### PDF Manipulation Options")
95
 
96
  # Radio buttons for selecting the function
97
- view_choice = st.radio("Select a PDF Function", ("Merge Multiple PDFs into One", "Split One PDF into Multiple"))
98
 
99
  # Display relevant instructions
100
- if view_choice == "Merge Multiple PDFs into One":
101
  st.markdown("**Upload multiple PDFs**")
102
 
103
- # Get the data from the form, stop running if user hasn"t submitted pdfs yet
104
  data = sp.pydantic_form(key="pdf_merge_form", model=PDFMergeRequest)
105
  if data is None or data.pdf_uploads is None or len(data.pdf_uploads) < 2:
106
  st.warning("Upload at least 2 PDFs and press Submit")
@@ -109,7 +88,7 @@ if view_choice == "Merge Multiple PDFs into One":
109
  # Save Uploaded PDFs
110
  uploaded_paths = []
111
  for pdf_data in data.pdf_uploads:
112
- input_pdf_path = destination_folder / f"input_{datetime.now().strftime("%Y_%m_%d_%H_%M_%S_%f")}.pdf"
113
  input_pdf_path.write_bytes(pdf_data.as_bytes())
114
  uploaded_paths.append(input_pdf_path)
115
 
@@ -117,13 +96,12 @@ if view_choice == "Merge Multiple PDFs into One":
117
  for path in uploaded_paths:
118
  pdf_reader = PdfFileReader(str(path))
119
  for page in range(pdf_reader.getNumPages()):
120
-
121
  # Add each page to the writer object
122
  pdf_writer.addPage(pdf_reader.getPage(page))
123
 
124
  # Write out the merged PDF
125
- output_pdf_path = destination_folder / f"output_{datetime.now().strftime("%Y_%m_%d_%H_%M_%S_%f")}.pdf"
126
- with open(str(output_pdf_path), "wb") as out:
127
  pdf_writer.write(out)
128
  output_path = output_pdf_path
129
 
@@ -131,19 +109,20 @@ if view_choice == "Merge Multiple PDFs into One":
131
  if output_suffix in (png_output, jpg_output):
132
  images = convert_from_path(output_pdf_path)
133
  stacked_image = stack_images(images)
134
- output_path = destination_folder / f"output_{datetime.now().strftime("%Y_%m_%d_%H_%M_%S_%f")}{output_suffix}"
135
  stacked_image.save(output_path) # format inferred
136
 
137
  # Allow download
138
  if output_suffix == pdf_output:
139
- output_mime = "application/pdf"
140
  elif output_suffix == jpg_output:
141
- output_mime = "image/jpeg"
142
  elif output_suffix == png_output:
143
- output_mime = "image/png"
144
 
145
  # Create a download button with a custom label
146
- st.download_button("Download Merged Document", output_path.read_bytes(), f"output_{datetime.now().strftime("%Y_%m_%d_%H_%M_%S_%f")}{output_suffix}", mime=output_mime)
 
147
 
148
  # Delete temporary files
149
  for path in uploaded_paths:
@@ -154,17 +133,17 @@ if view_choice == "Merge Multiple PDFs into One":
154
  # Delete the output file after download
155
  os.remove(output_path)
156
 
157
- elif view_choice == "Split One PDF into Multiple":
158
  st.markdown("**Upload a single PDF to split**")
159
 
160
- # Get the data from the form, stop running if user hasn"t submitted pdf yet
161
  data = sp.pydantic_form(key="pdf_split_form", model=PDFSplitRequest)
162
  if data is None or data.pdf_upload is None:
163
  st.warning("Upload a PDF and press Submit")
164
  st.stop()
165
 
166
  # Save Uploaded PDF
167
- input_pdf_path = destination_folder / f"input_{datetime.now().strftime("%Y_%m_%d_%H_%M_%S_%f")}.pdf"
168
  input_pdf_path.write_bytes(data.pdf_upload.as_bytes())
169
 
170
  # Get PDF Reader
@@ -178,7 +157,7 @@ elif view_choice == "Split One PDF into Multiple":
178
  downloads = []
179
  for letter_start in range(0, pdf.numPages, data.pages_per_pdf):
180
  output = PdfFileWriter()
181
- output_path = input_pdf_path.with_name(f"output_{datetime.now().strftime("%Y_%m_%d_%H_%M_%S_%f")}.pdf")
182
  for letter_page in range(data.pages_per_pdf):
183
  output.addPage(pdf.getPage(letter_start + letter_page))
184
 
@@ -189,21 +168,21 @@ elif view_choice == "Split One PDF into Multiple":
189
  if output_suffix in (png_output, jpg_output):
190
  images = convert_from_path(output_path)
191
  stacked_image = stack_images(images)
192
- output_path = destination_folder / f"output_{datetime.now().strftime("%Y_%m_%d_%H_%M_%S_%f")}{output_suffix}"
193
  stacked_image.save(output_path) # format inferred
194
 
195
  downloads.append(output_path)
196
  st.success(f"Saved file {str(output_path)} (original start page {letter_start + 1 } / {pdf.numPages})")
197
 
198
  # Make zip file of all split pdfs
199
- zip_path = destination_folder / f"output_{datetime.now().strftime("%Y_%m_%d_%H_%M_%S_%f")}.zip"
200
  output_zip = ZipFile(str(zip_path), "w")
201
  for download_path in downloads:
202
  output_zip.write(str(download_path), arcname=download_path.name)
203
  output_zip.close()
204
 
205
  # Provide download button of the zip of split pdfs
206
- st.download_button(f"Download {str(zip_path)}", zip_path.read_bytes(), str(zip_path), mime="application/zip", key=str(zip_path))
207
 
208
  # Delete temporary files
209
  for download_path in downloads:
 
28
  st.markdown("This is tools for join and split file PDF")
29
 
30
  # Make folder for storing user uploads
31
+ destination_folder = Path('downloads')
32
  destination_folder.mkdir(exist_ok=True, parents=True)
33
 
34
  # Defines what options are in the form
35
  class PDFMergeRequest(BaseModel):
 
 
 
 
 
 
 
36
  pdf_uploads: Optional[List[FileContent]] = Field(
37
  None,
38
  alias="PDF File to Split",
 
40
  )
41
 
42
  class PDFSplitRequest(BaseModel):
 
 
 
 
 
 
43
  pages_per_pdf: int = Field(
44
  1,
45
  alias="Pages per Split",
 
52
  )
53
 
54
  def stack_images(images):
55
+ """adapted from: https://note.nkmk.me/en/python-pillow-concat-images/"""
 
 
 
 
 
 
 
 
56
  first_image = images[0]
57
+ output_image = Image.new('RGB', (first_image.width, sum((image.height for image in images))))
58
  output_image.paste(first_image, (0, 0))
59
  starting_y_value = first_image.height
60
  for image in images[1:]:
 
63
  return output_image
64
 
65
  # Radio buttons for selecting the file type
66
+ pdf_output = '.pdf'
67
+ jpg_output = '.jpg'
68
+ png_output = '.png'
69
+ #output_suffix = st.radio('Output File Type', [pdf_output, jpg_output, png_output], key='output_format')
70
  output_suffix = (pdf_output)
71
 
72
  # Add a heading
73
  st.markdown("### PDF Manipulation Options")
74
 
75
  # Radio buttons for selecting the function
76
+ view_choice = st.radio('Select a PDF Function', ('Merge Multiple PDFs into One', 'Split One PDF into Multiple'))
77
 
78
  # Display relevant instructions
79
+ if view_choice == 'Merge Multiple PDFs into One':
80
  st.markdown("**Upload multiple PDFs**")
81
 
82
+ # Get the data from the form, stop running if user hasn't submitted pdfs yet
83
  data = sp.pydantic_form(key="pdf_merge_form", model=PDFMergeRequest)
84
  if data is None or data.pdf_uploads is None or len(data.pdf_uploads) < 2:
85
  st.warning("Upload at least 2 PDFs and press Submit")
 
88
  # Save Uploaded PDFs
89
  uploaded_paths = []
90
  for pdf_data in data.pdf_uploads:
91
+ input_pdf_path = destination_folder / f"input_{datetime.now().strftime('%Y_%m_%d_%H_%M_%S_%f')}.pdf"
92
  input_pdf_path.write_bytes(pdf_data.as_bytes())
93
  uploaded_paths.append(input_pdf_path)
94
 
 
96
  for path in uploaded_paths:
97
  pdf_reader = PdfFileReader(str(path))
98
  for page in range(pdf_reader.getNumPages()):
 
99
  # Add each page to the writer object
100
  pdf_writer.addPage(pdf_reader.getPage(page))
101
 
102
  # Write out the merged PDF
103
+ output_pdf_path = destination_folder / f"output_{datetime.now().strftime('%Y_%m_%d_%H_%M_%S_%f')}.pdf"
104
+ with open(str(output_pdf_path), 'wb') as out:
105
  pdf_writer.write(out)
106
  output_path = output_pdf_path
107
 
 
109
  if output_suffix in (png_output, jpg_output):
110
  images = convert_from_path(output_pdf_path)
111
  stacked_image = stack_images(images)
112
+ output_path = destination_folder / f"output_{datetime.now().strftime('%Y_%m_%d_%H_%M_%S_%f')}{output_suffix}"
113
  stacked_image.save(output_path) # format inferred
114
 
115
  # Allow download
116
  if output_suffix == pdf_output:
117
+ output_mime = 'application/pdf'
118
  elif output_suffix == jpg_output:
119
+ output_mime = 'image/jpeg'
120
  elif output_suffix == png_output:
121
+ output_mime = 'image/png'
122
 
123
  # Create a download button with a custom label
124
+ # if st.button("Download Merged PDF"):
125
+ st.download_button('Download Merged Document', output_path.read_bytes(), f"output_{datetime.now().strftime('%Y_%m_%d_%H_%M_%S_%f')}{output_suffix}", mime=output_mime)
126
 
127
  # Delete temporary files
128
  for path in uploaded_paths:
 
133
  # Delete the output file after download
134
  os.remove(output_path)
135
 
136
+ elif view_choice == 'Split One PDF into Multiple':
137
  st.markdown("**Upload a single PDF to split**")
138
 
139
+ # Get the data from the form, stop running if user hasn't submitted pdf yet
140
  data = sp.pydantic_form(key="pdf_split_form", model=PDFSplitRequest)
141
  if data is None or data.pdf_upload is None:
142
  st.warning("Upload a PDF and press Submit")
143
  st.stop()
144
 
145
  # Save Uploaded PDF
146
+ input_pdf_path = destination_folder / f"input_{datetime.now().strftime('%Y_%m_%d_%H_%M_%S_%f')}.pdf"
147
  input_pdf_path.write_bytes(data.pdf_upload.as_bytes())
148
 
149
  # Get PDF Reader
 
157
  downloads = []
158
  for letter_start in range(0, pdf.numPages, data.pages_per_pdf):
159
  output = PdfFileWriter()
160
+ output_path = input_pdf_path.with_name(f"output_{datetime.now().strftime('%Y_%m_%d_%H_%M_%S_%f')}.pdf")
161
  for letter_page in range(data.pages_per_pdf):
162
  output.addPage(pdf.getPage(letter_start + letter_page))
163
 
 
168
  if output_suffix in (png_output, jpg_output):
169
  images = convert_from_path(output_path)
170
  stacked_image = stack_images(images)
171
+ output_path = destination_folder / f"output_{datetime.now().strftime('%Y_%m_%d_%H_%M_%S_%f')}{output_suffix}"
172
  stacked_image.save(output_path) # format inferred
173
 
174
  downloads.append(output_path)
175
  st.success(f"Saved file {str(output_path)} (original start page {letter_start + 1 } / {pdf.numPages})")
176
 
177
  # Make zip file of all split pdfs
178
+ zip_path = destination_folder / f"output_{datetime.now().strftime('%Y_%m_%d_%H_%M_%S_%f')}.zip"
179
  output_zip = ZipFile(str(zip_path), "w")
180
  for download_path in downloads:
181
  output_zip.write(str(download_path), arcname=download_path.name)
182
  output_zip.close()
183
 
184
  # Provide download button of the zip of split pdfs
185
+ st.download_button(f"Download {str(zip_path)}", zip_path.read_bytes(), str(zip_path), mime='application/zip', key=str(zip_path))
186
 
187
  # Delete temporary files
188
  for download_path in downloads: