Update app.py
Browse files
app.py
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
import pandas as pd
|
2 |
import openpyxl
|
3 |
import gradio as gr
|
4 |
-
import
|
5 |
-
import
|
6 |
from datetime import datetime
|
7 |
|
8 |
def convert_schedule(file_path, direction):
|
@@ -103,73 +103,93 @@ def convert_schedule(file_path, direction):
|
|
103 |
# For display, include index as a column
|
104 |
display_df = result.reset_index().rename(columns={'index': first_col_name})
|
105 |
|
106 |
-
# 6. Create downloadable file
|
107 |
result_clean = result.copy().fillna('OFF')
|
108 |
|
109 |
# Ensure all values are strings
|
110 |
for col in result_clean.columns:
|
111 |
result_clean[col] = result_clean[col].astype(str)
|
112 |
|
113 |
-
# Create
|
114 |
-
|
115 |
-
output_filename = f"converted_schedule_{timestamp}.xlsx"
|
116 |
|
117 |
-
# Use
|
118 |
-
|
119 |
-
temp_path = temp_file.name
|
120 |
-
temp_file.close()
|
121 |
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
|
128 |
except Exception as e:
|
129 |
error_msg = f"Error processing file: {str(e)}"
|
130 |
-
print(f"DEBUG: {error_msg}")
|
131 |
error_df = pd.DataFrame({'Error': [error_msg]})
|
132 |
return error_df, None
|
133 |
|
134 |
-
#
|
135 |
-
def
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
'
|
|
|
|
|
162 |
),
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
167 |
|
168 |
if __name__ == "__main__":
|
169 |
-
iface = create_interface()
|
170 |
iface.launch(
|
171 |
server_name='0.0.0.0',
|
172 |
server_port=7860,
|
173 |
-
share=False
|
174 |
-
debug=True
|
175 |
)
|
|
|
1 |
import pandas as pd
|
2 |
import openpyxl
|
3 |
import gradio as gr
|
4 |
+
import io
|
5 |
+
import base64
|
6 |
from datetime import datetime
|
7 |
|
8 |
def convert_schedule(file_path, direction):
|
|
|
103 |
# For display, include index as a column
|
104 |
display_df = result.reset_index().rename(columns={'index': first_col_name})
|
105 |
|
106 |
+
# 6. Create downloadable file using in-memory approach
|
107 |
result_clean = result.copy().fillna('OFF')
|
108 |
|
109 |
# Ensure all values are strings
|
110 |
for col in result_clean.columns:
|
111 |
result_clean[col] = result_clean[col].astype(str)
|
112 |
|
113 |
+
# Create Excel file in memory
|
114 |
+
download_df = result_clean.reset_index().rename(columns={'index': first_col_name})
|
|
|
115 |
|
116 |
+
# Use BytesIO to create file in memory
|
117 |
+
excel_buffer = io.BytesIO()
|
|
|
|
|
118 |
|
119 |
+
with pd.ExcelWriter(excel_buffer, engine='openpyxl') as writer:
|
120 |
+
download_df.to_excel(writer, sheet_name='Converted Schedule', index=False)
|
121 |
+
|
122 |
+
excel_buffer.seek(0)
|
123 |
+
|
124 |
+
# Create filename with timestamp
|
125 |
+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
126 |
+
filename = f"converted_schedule_{timestamp}.xlsx"
|
127 |
+
|
128 |
+
# Return the buffer content for download
|
129 |
+
return display_df, (excel_buffer.getvalue(), filename)
|
130 |
|
131 |
except Exception as e:
|
132 |
error_msg = f"Error processing file: {str(e)}"
|
133 |
+
print(f"DEBUG: {error_msg}")
|
134 |
error_df = pd.DataFrame({'Error': [error_msg]})
|
135 |
return error_df, None
|
136 |
|
137 |
+
# Wrapper function to handle the file download properly
|
138 |
+
def process_and_download(file_path, direction):
|
139 |
+
display_result, download_data = convert_schedule(file_path, direction)
|
140 |
+
|
141 |
+
if download_data is None:
|
142 |
+
return display_result, None
|
143 |
+
|
144 |
+
# Create a temporary file that Gradio can serve
|
145 |
+
import tempfile
|
146 |
+
import os
|
147 |
+
|
148 |
+
excel_content, filename = download_data
|
149 |
+
|
150 |
+
# Save to a temporary file in the system temp directory
|
151 |
+
temp_dir = tempfile.gettempdir()
|
152 |
+
temp_path = os.path.join(temp_dir, filename)
|
153 |
+
|
154 |
+
with open(temp_path, 'wb') as f:
|
155 |
+
f.write(excel_content)
|
156 |
+
|
157 |
+
return display_result, temp_path
|
158 |
+
|
159 |
+
# Create the interface
|
160 |
+
iface = gr.Interface(
|
161 |
+
fn=process_and_download,
|
162 |
+
inputs=[
|
163 |
+
gr.File(
|
164 |
+
label='Upload Weekly Schedule (.xlsx)',
|
165 |
+
file_count='single',
|
166 |
+
file_types=['.xlsx', '.xls']
|
167 |
),
|
168 |
+
gr.Radio(
|
169 |
+
['A to B', 'B to A'],
|
170 |
+
label='Convert Direction',
|
171 |
+
value='A to B',
|
172 |
+
info='A to B: Models→Texters, B to A: Texters→Models'
|
173 |
+
)
|
174 |
+
],
|
175 |
+
outputs=[
|
176 |
+
gr.Dataframe(label='Converted Schedule (Preview)', wrap=True),
|
177 |
+
gr.File(label='Download Converted Schedule (.xlsx)')
|
178 |
+
],
|
179 |
+
title='🔄 7-Day Schedule Converter',
|
180 |
+
description=(
|
181 |
+
'**How to use:**\n'
|
182 |
+
'1. Upload your Excel file with a 7-day schedule\n'
|
183 |
+
'2. Choose conversion direction\n'
|
184 |
+
'3. Preview the result and download the converted file\n\n'
|
185 |
+
'*Supports merged headers and handles Models ↔ Texters conversion*'
|
186 |
+
),
|
187 |
+
flagging_mode='never'
|
188 |
+
)
|
189 |
|
190 |
if __name__ == "__main__":
|
|
|
191 |
iface.launch(
|
192 |
server_name='0.0.0.0',
|
193 |
server_port=7860,
|
194 |
+
share=False
|
|
|
195 |
)
|