Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
@@ -6,7 +6,7 @@ from threading import Thread
|
|
6 |
|
7 |
import dash
|
8 |
import dash_bootstrap_components as dbc
|
9 |
-
from dash import dcc, html, Input, Output, State, callback
|
10 |
from dash.exceptions import PreventUpdate
|
11 |
from PyPDF2 import PdfReader, PdfWriter
|
12 |
|
@@ -37,13 +37,17 @@ app.layout = dbc.Container([
|
|
37 |
html.Div(id='pdf-name'),
|
38 |
dbc.Card([
|
39 |
dbc.CardBody([
|
40 |
-
|
|
|
|
|
|
|
|
|
|
|
41 |
dbc.Button("Add Range", id='add-range', color="secondary", className="mt-2"),
|
42 |
-
html.Div(id='ranges-list'),
|
43 |
])
|
44 |
], className="my-3"),
|
45 |
dbc.Button("Split PDF", id='split-button', color="primary", className="mt-3", disabled=True),
|
46 |
-
dbc.Progress(id='progress-bar', className="my-3"),
|
47 |
dbc.Button("Download ZIP", id='download-button', color="success", className="mt-3", disabled=True),
|
48 |
dcc.Download(id="download-zip"),
|
49 |
], fluid=True)
|
@@ -60,16 +64,28 @@ def update_output(contents, filename):
|
|
60 |
return "No file selected", True
|
61 |
|
62 |
@callback(
|
63 |
-
Output('ranges-
|
64 |
Input('add-range', 'n_clicks'),
|
65 |
-
|
66 |
-
State('ranges-
|
|
|
67 |
)
|
68 |
-
def
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
|
74 |
def process_pdf(contents, filename, ranges):
|
75 |
global generated_file, progress
|
@@ -110,14 +126,14 @@ def process_pdf(contents, filename, ranges):
|
|
110 |
Input('split-button', 'n_clicks'),
|
111 |
State('upload-pdf', 'contents'),
|
112 |
State('upload-pdf', 'filename'),
|
113 |
-
State('
|
114 |
prevent_initial_call=True
|
115 |
)
|
116 |
def split_pdf(n_clicks, contents, filename, ranges):
|
117 |
if not contents or not ranges:
|
118 |
raise PreventUpdate
|
119 |
|
120 |
-
ranges = [r
|
121 |
thread = Thread(target=process_pdf, args=(contents, filename, ranges))
|
122 |
thread.start()
|
123 |
|
|
|
6 |
|
7 |
import dash
|
8 |
import dash_bootstrap_components as dbc
|
9 |
+
from dash import dcc, html, Input, Output, State, callback, MATCH, ALL
|
10 |
from dash.exceptions import PreventUpdate
|
11 |
from PyPDF2 import PdfReader, PdfWriter
|
12 |
|
|
|
37 |
html.Div(id='pdf-name'),
|
38 |
dbc.Card([
|
39 |
dbc.CardBody([
|
40 |
+
html.Div(id='ranges-container', children=[
|
41 |
+
dbc.Row([
|
42 |
+
dbc.Col(dbc.Input(id={'type': 'range-input', 'index': 0}, type='text', placeholder='Enter page range (e.g., 1-3)'), width=10),
|
43 |
+
dbc.Col(dbc.Button("Remove", id={'type': 'remove-range', 'index': 0}, color="danger", size="sm"), width=2),
|
44 |
+
], className="mb-2"),
|
45 |
+
]),
|
46 |
dbc.Button("Add Range", id='add-range', color="secondary", className="mt-2"),
|
|
|
47 |
])
|
48 |
], className="my-3"),
|
49 |
dbc.Button("Split PDF", id='split-button', color="primary", className="mt-3", disabled=True),
|
50 |
+
dbc.Progress(id='progress-bar', className="my-3"),
|
51 |
dbc.Button("Download ZIP", id='download-button', color="success", className="mt-3", disabled=True),
|
52 |
dcc.Download(id="download-zip"),
|
53 |
], fluid=True)
|
|
|
64 |
return "No file selected", True
|
65 |
|
66 |
@callback(
|
67 |
+
Output('ranges-container', 'children'),
|
68 |
Input('add-range', 'n_clicks'),
|
69 |
+
Input({'type': 'remove-range', 'index': ALL}, 'n_clicks'),
|
70 |
+
State('ranges-container', 'children'),
|
71 |
+
prevent_initial_call=True
|
72 |
)
|
73 |
+
def manage_ranges(add_clicks, remove_clicks, existing_ranges):
|
74 |
+
ctx = dash.callback_context
|
75 |
+
triggered_id = ctx.triggered[0]['prop_id'].split('.')[0]
|
76 |
+
|
77 |
+
if triggered_id == 'add-range':
|
78 |
+
new_index = len(existing_ranges)
|
79 |
+
new_range = dbc.Row([
|
80 |
+
dbc.Col(dbc.Input(id={'type': 'range-input', 'index': new_index}, type='text', placeholder='Enter page range (e.g., 1-3)'), width=10),
|
81 |
+
dbc.Col(dbc.Button("Remove", id={'type': 'remove-range', 'index': new_index}, color="danger", size="sm"), width=2),
|
82 |
+
], className="mb-2")
|
83 |
+
existing_ranges.append(new_range)
|
84 |
+
elif 'remove-range' in triggered_id:
|
85 |
+
remove_index = json.loads(triggered_id)['index']
|
86 |
+
existing_ranges = [range for range in existing_ranges if json.loads(range['props']['children'][1]['props']['children']['props']['id'])['index'] != remove_index]
|
87 |
+
|
88 |
+
return existing_ranges
|
89 |
|
90 |
def process_pdf(contents, filename, ranges):
|
91 |
global generated_file, progress
|
|
|
126 |
Input('split-button', 'n_clicks'),
|
127 |
State('upload-pdf', 'contents'),
|
128 |
State('upload-pdf', 'filename'),
|
129 |
+
State({'type': 'range-input', 'index': ALL}, 'value'),
|
130 |
prevent_initial_call=True
|
131 |
)
|
132 |
def split_pdf(n_clicks, contents, filename, ranges):
|
133 |
if not contents or not ranges:
|
134 |
raise PreventUpdate
|
135 |
|
136 |
+
ranges = [r for r in ranges if r] # Filter out empty ranges
|
137 |
thread = Thread(target=process_pdf, args=(contents, filename, ranges))
|
138 |
thread.start()
|
139 |
|