Abhisksks commited on
Commit
4cf1b61
Β·
verified Β·
1 Parent(s): 927a79b

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +182 -38
src/streamlit_app.py CHANGED
@@ -1,40 +1,184 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
  import streamlit as st
 
 
 
5
 
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
+ from pypdf import PdfWriter, PdfReader
3
+ from PIL import Image
4
+ import io
5
 
6
+ # --- PAGE CONFIGURATION ---
7
+ st.set_page_config(
8
+ page_title="PDF & Image Toolkit",
9
+ page_icon="πŸ“„",
10
+ layout="centered",
11
+ )
12
+
13
+ # --- HELPER FUNCTIONS ---
14
+ def merge_pdfs(uploaded_files):
15
+ """Merges multiple PDF files into one."""
16
+ merger = PdfWriter()
17
+ for pdf_file in uploaded_files:
18
+ # pypdf needs a file object, so we wrap the uploaded bytes in BytesIO
19
+ merger.append(io.BytesIO(pdf_file.getvalue()))
20
+
21
+ # Write the merged PDF to a BytesIO object in memory
22
+ output_buffer = io.BytesIO()
23
+ merger.write(output_buffer)
24
+ merger.close()
25
+ return output_buffer.getvalue()
26
+
27
+ def compress_pdf(uploaded_file):
28
+ """Performs basic compression on a PDF file."""
29
+ reader = PdfReader(io.BytesIO(uploaded_file.getvalue()))
30
+ writer = PdfWriter()
31
+
32
+ for page in reader.pages:
33
+ # This is a basic form of compression
34
+ page.compress_content_streams()
35
+ writer.add_page(page)
36
+
37
+ # Write the compressed PDF to a BytesIO object
38
+ output_buffer = io.BytesIO()
39
+ writer.write(output_buffer)
40
+ writer.close()
41
+ return output_buffer.getvalue()
42
+
43
+ def images_to_pdf(uploaded_files):
44
+ """Converts a list of images to a single PDF."""
45
+ images = []
46
+ for img_file in uploaded_files:
47
+ img = Image.open(io.BytesIO(img_file.getvalue()))
48
+ # Convert to RGB to avoid issues with different image modes (e.g., RGBA, P)
49
+ if img.mode == 'RGBA' or img.mode == 'P':
50
+ img = img.convert('RGB')
51
+ images.append(img)
52
+
53
+ if not images:
54
+ return None
55
+
56
+ # Save the images as a PDF to a BytesIO object
57
+ output_buffer = io.BytesIO()
58
+ images[0].save(
59
+ output_buffer,
60
+ "PDF" ,
61
+ resolution=100.0,
62
+ save_all=True,
63
+ append_images=images[1:]
64
+ )
65
+ return output_buffer.getvalue()
66
+
67
+
68
+ # --- STREAMLIT UI ---
69
+
70
+ st.title("πŸ“„ PDF & Image Toolkit")
71
+ st.write("A simple web app to manage your documents. All processing is done in your browser and on the server, and your files are not saved.")
72
+
73
+ # --- SIDEBAR FOR TOOL SELECTION ---
74
+ with st.sidebar:
75
+ st.header("Tools")
76
+ tool_choice = st.radio(
77
+ "Select a tool:",
78
+ ("Merge PDFs", "Compress PDF", "Convert Images to PDF")
79
+ )
80
+
81
+ # --- MAIN PAGE CONTENT ---
82
+
83
+ if tool_choice == "Merge PDFs":
84
+ st.subheader("Merge Multiple PDF Files")
85
+ st.write("Upload two or more PDF files to combine them into a single document.")
86
+
87
+ uploaded_pdfs = st.file_uploader(
88
+ "Upload PDF files",
89
+ type="pdf",
90
+ accept_multiple_files=True,
91
+ key="pdf_merger"
92
+ )
93
+
94
+ if st.button("Merge PDFs") and uploaded_pdfs:
95
+ if len(uploaded_pdfs) < 2:
96
+ st.warning("Please upload at least two PDF files to merge.")
97
+ else:
98
+ with st.spinner("Merging..."):
99
+ merged_pdf_bytes = merge_pdfs(uploaded_pdfs)
100
+ st.success("PDFs merged successfully!")
101
+ st.download_button(
102
+ label="Download Merged PDF",
103
+ data=merged_pdf_bytes,
104
+ file_name="merged_document.pdf",
105
+ mime="application/pdf",
106
+ )
107
+
108
+ elif tool_choice == "Compress PDF":
109
+ st.subheader("Compress a PDF File")
110
+ st.info("This tool performs basic optimization. It may not significantly reduce the size of all PDFs, especially those that are already optimized or text-heavy.")
111
+
112
+ uploaded_pdf = st.file_uploader(
113
+ "Upload a PDF file",
114
+ type="pdf",
115
+ accept_multiple_files=False,
116
+ key="pdf_compressor"
117
+ )
118
+
119
+ if st.button("Compress PDF") and uploaded_pdf:
120
+ with st.spinner("Compressing..."):
121
+ compressed_pdf_bytes = compress_pdf(uploaded_pdf)
122
+ original_size = uploaded_pdf.size
123
+ compressed_size = len(compressed_pdf_bytes)
124
+ reduction = ((original_size - compressed_size) / original_size) * 100
125
+
126
+ st.success(f"Compression complete! Size reduced by {reduction:.2f}%.")
127
+ st.download_button(
128
+ label="Download Compressed PDF",
129
+ data=compressed_pdf_bytes,
130
+ file_name="compressed_document.pdf",
131
+ mime="application/pdf",
132
+ )
133
+
134
+
135
+ elif tool_choice == "Convert Images to PDF":
136
+ st.subheader("Convert Images to a Single PDF")
137
+ st.write("Upload one or more images (JPG, PNG) to combine them into a PDF.")
138
+
139
+ uploaded_images = st.file_uploader(
140
+ "Upload image files",
141
+ type=["png", "jpg", "jpeg"],
142
+ accept_multiple_files=True,
143
+ key="img_converter"
144
+ )
145
+
146
+ if st.button("Convert to PDF") and uploaded_images:
147
+ with st.spinner("Converting..."):
148
+ pdf_from_images_bytes = images_to_pdf(uploaded_images)
149
+ st.success("Images converted to PDF successfully!")
150
+ st.download_button(
151
+ label="Download PDF",
152
+ data=pdf_from_images_bytes,
153
+ file_name="images_converted.pdf",
154
+ mime="application/pdf",
155
+ )
156
+
157
+ st.sidebar.markdown("---")
158
+ st.sidebar.info("App built with [Streamlit](https://streamlit.io) and hosted on [Hugging Face Spaces](https://huggingface.co/spaces).")
159
+
160
+ ---
161
+
162
+ ### How to Deploy on Hugging Face Spaces (in 5 steps)
163
+
164
+ 1. **Create a Hugging Face Account:** If you don't have one, sign up at [huggingface.co](https://huggingface.co).
165
+ 2. **Create a New Space:**
166
+ * Click on your profile picture and select "New Space".
167
+ * Give it a **Space name** (e.g., `pdf-toolkit`).
168
+ * Choose a license (e.g., `mit`).
169
+ * Select **Streamlit** as the Space SDK.
170
+ * Click "Create Space".
171
+
172
+ 3. **Add the Files:**
173
+ * You will be taken to your new Space repository. Click on the **"Files"** tab.
174
+ * Click "Add file" -> "Create new file".
175
+ * Name the file `requirements.txt`. Paste the content for `requirements.txt` from above and commit the new file.
176
+ * You will see an `app.py` file was already created for you. Click on it, then click the pencil icon to **edit** it.
177
+ * **Delete the existing placeholder content** and paste the entire `app.py` code from above. Commit your changes.
178
+
179
+ 4. **Wait for it to Build:**
180
+ * Go back to the "App" tab. You will see a "Building" status. Hugging Face is now installing Streamlit, PyPDF, and Pillow based on your `requirements.txt` file.
181
+ * This usually takes 1-2 minutes.
182
+
183
+ 5. **Use Your App!**
184
+ * Once it's finished building, your application will be live and ready to use at its public URL (e.g., `https://huggingface.co/spaces/Abhisksks/Pdf_editor`).