Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -672,48 +672,108 @@ def make_image_sized_pdf(sources):
|
|
| 672 |
return None
|
| 673 |
|
| 674 |
|
| 675 |
-
|
| 676 |
-
# --- Sidebar Gallery Update Function (Keep from previous) --------
|
| 677 |
def update_gallery():
|
| 678 |
-
|
| 679 |
-
|
| 680 |
-
|
| 681 |
-
|
| 682 |
-
|
| 683 |
-
|
| 684 |
-
|
| 685 |
-
|
| 686 |
-
|
| 687 |
-
|
| 688 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 689 |
try:
|
| 690 |
-
|
| 691 |
-
|
| 692 |
-
|
| 693 |
-
|
| 694 |
-
|
| 695 |
-
|
| 696 |
-
|
| 697 |
-
|
| 698 |
-
|
| 699 |
-
|
| 700 |
-
|
| 701 |
-
|
| 702 |
-
|
| 703 |
-
|
| 704 |
-
|
| 705 |
-
|
| 706 |
-
|
| 707 |
-
|
| 708 |
-
|
| 709 |
-
|
| 710 |
-
|
| 711 |
-
|
| 712 |
-
|
| 713 |
-
|
| 714 |
-
|
| 715 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 716 |
|
|
|
|
| 717 |
|
| 718 |
# --- UI Elements -----------------------------------------
|
| 719 |
|
|
@@ -881,7 +941,7 @@ with tabs[0]:
|
|
| 881 |
st.image(Image.open(scan_name), caption=f"Scanned: {scan_name}", use_container_width=True)
|
| 882 |
if scan_name not in st.session_state['layout_snapshots']: st.session_state['layout_snapshots'].append(scan_name)
|
| 883 |
st.success(f"Scan saved as {scan_name}")
|
| 884 |
-
update_gallery();
|
| 885 |
except Exception as e: st.error(f"Failed to save scan: {e}"); logger.error(f"Failed to save camera scan {scan_name}: {e}")
|
| 886 |
|
| 887 |
layout_uploads = st.file_uploader("๐ Upload PNG/JPG Images for Layout PDF", type=["png","jpg","jpeg"], accept_multiple_files=True, key="layout_uploader")
|
|
@@ -959,7 +1019,7 @@ with tabs[1]:
|
|
| 959 |
try:
|
| 960 |
with open(filename, "wb") as f: f.write(cam0_img.getvalue())
|
| 961 |
st.session_state['cam0_file'] = filename; st.session_state['history'].append(f"Snapshot from Cam 0: {filename}"); st.image(Image.open(filename), caption="Camera 0 Snap", use_container_width=True); logger.info(f"Saved snapshot from Camera 0: {filename}"); st.success(f"Saved {filename}")
|
| 962 |
-
update_gallery();
|
| 963 |
except Exception as e:
|
| 964 |
st.error(f"Failed to save Cam 0 snap: {e}"); logger.error(f"Failed to save Cam 0 snap {filename}: {e}")
|
| 965 |
with cols[1]:
|
|
@@ -974,7 +1034,7 @@ with tabs[1]:
|
|
| 974 |
try:
|
| 975 |
with open(filename, "wb") as f: f.write(cam1_img.getvalue())
|
| 976 |
st.session_state['cam1_file'] = filename; st.session_state['history'].append(f"Snapshot from Cam 1: {filename}"); st.image(Image.open(filename), caption="Camera 1 Snap", use_container_width=True); logger.info(f"Saved snapshot from Camera 1: {filename}"); st.success(f"Saved {filename}")
|
| 977 |
-
update_gallery();
|
| 978 |
except Exception as e: st.error(f"Failed to save Cam 1 snap: {e}"); logger.error(f"Failed to save Cam 1 snap {filename}: {e}")
|
| 979 |
|
| 980 |
|
|
@@ -999,7 +1059,7 @@ with tabs[2]:
|
|
| 999 |
if download_pdf(url, output_path): st.session_state['downloaded_pdfs'][url] = output_path; logger.info(f"Downloaded PDF from {url} to {output_path}"); st.session_state['history'].append(f"Downloaded PDF: {output_path}"); st.session_state['asset_checkboxes'][output_path] = False; download_count += 1; existing_pdfs.append(output_path)
|
| 1000 |
else: st.error(f"Failed to download: {url}")
|
| 1001 |
status_text.success(f"Download process complete! Successfully downloaded {download_count} new PDFs.")
|
| 1002 |
-
if download_count > 0: update_gallery();
|
| 1003 |
|
| 1004 |
st.subheader("Create Snapshots from Gallery PDFs")
|
| 1005 |
snapshot_mode = st.selectbox("Snapshot Mode", ["First Page (High-Res)", "First Two Pages (High-Res)", "All Pages (High-Res)", "First Page (Low-Res Preview)"], key="pdf_snapshot_mode")
|
|
@@ -1019,7 +1079,7 @@ with tabs[2]:
|
|
| 1019 |
st.write(f"Snapshots for {os.path.basename(pdf_path)}:"); cols = st.columns(3)
|
| 1020 |
for i, snap_path in enumerate(new_snapshots):
|
| 1021 |
with cols[i % 3]: st.image(Image.open(snap_path), caption=os.path.basename(snap_path), use_container_width=True); st.session_state['asset_checkboxes'][snap_path] = False # Add to gallery
|
| 1022 |
-
if total_snapshots_generated > 0: st.success(f"Generated {total_snapshots_generated} snapshots from {snapshot_count} PDFs."); update_gallery();
|
| 1023 |
else: st.warning("No snapshots were generated. Check logs or PDF files.")
|
| 1024 |
|
| 1025 |
# --- Tab 4: Build Titan (Local Models) ---
|
|
@@ -1162,8 +1222,6 @@ with tabs[3]:
|
|
| 1162 |
finally:
|
| 1163 |
progress_bar_build.progress(1.0)
|
| 1164 |
status_text_build.empty()
|
| 1165 |
-
# Update sidebar selector
|
| 1166 |
-
st.rerun()
|
| 1167 |
|
| 1168 |
st.subheader("Manage Local Models")
|
| 1169 |
loaded_model_paths = list(st.session_state.get('local_models', {}).keys())
|
|
@@ -1196,7 +1254,6 @@ with tabs[3]:
|
|
| 1196 |
shutil.rmtree(path_to_delete)
|
| 1197 |
st.success(f"Deleted model '{model_to_delete}' and its files.")
|
| 1198 |
logger.info(f"Deleted local model: {path_to_delete}")
|
| 1199 |
-
st.rerun()
|
| 1200 |
except Exception as e:
|
| 1201 |
st.error(f"Failed to delete model '{model_to_delete}': {e}")
|
| 1202 |
logger.error(f"Failed to delete model {path_to_delete}: {e}")
|
|
|
|
| 672 |
return None
|
| 673 |
|
| 674 |
|
| 675 |
+
# --- Sidebar Gallery Update Function (MODIFIED) --------
|
|
|
|
| 676 |
def update_gallery():
|
| 677 |
+
st.sidebar.markdown("### Asset Gallery ๐ธ๐")
|
| 678 |
+
|
| 679 |
+
all_files = get_gallery_files() # Get currently available files
|
| 680 |
+
|
| 681 |
+
if not all_files:
|
| 682 |
+
st.sidebar.info("No assets (images, PDFs, text files) found yet.")
|
| 683 |
+
return
|
| 684 |
+
|
| 685 |
+
st.sidebar.caption(f"Found {len(all_files)} assets:")
|
| 686 |
+
|
| 687 |
+
for idx, file in enumerate(all_files):
|
| 688 |
+
st.session_state['unique_counter'] += 1
|
| 689 |
+
unique_id = st.session_state['unique_counter']
|
| 690 |
+
item_key_base = f"gallery_item_{os.path.basename(file)}_{unique_id}"
|
| 691 |
+
basename = os.path.basename(file)
|
| 692 |
+
st.sidebar.markdown(f"**{basename}**") # Display filename clearly
|
| 693 |
+
|
| 694 |
+
try:
|
| 695 |
+
file_ext = os.path.splitext(file)[1].lower()
|
| 696 |
+
# Display previews
|
| 697 |
+
if file_ext in ['.png', '.jpg', '.jpeg']:
|
| 698 |
+
# Add expander for large galleries
|
| 699 |
+
with st.sidebar.expander("Preview", expanded=False):
|
| 700 |
+
st.image(Image.open(file), use_container_width=True)
|
| 701 |
+
elif file_ext == '.pdf':
|
| 702 |
+
with st.sidebar.expander("Preview (Page 1)", expanded=False):
|
| 703 |
+
doc = fitz.open(file)
|
| 704 |
+
if len(doc) > 0:
|
| 705 |
+
pix = doc[0].get_pixmap(matrix=fitz.Matrix(0.5, 0.5)) # Smaller preview
|
| 706 |
+
img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
|
| 707 |
+
st.image(img, use_container_width=True)
|
| 708 |
+
else:
|
| 709 |
+
st.warning("Empty PDF")
|
| 710 |
+
doc.close()
|
| 711 |
+
elif file_ext in ['.md', '.txt']:
|
| 712 |
+
with st.sidebar.expander("Preview (Start)", expanded=False):
|
| 713 |
+
with open(file, 'r', encoding='utf-8', errors='ignore') as f:
|
| 714 |
+
content_preview = f.read(200) # Show first 200 chars
|
| 715 |
+
st.code(content_preview + "...", language='markdown' if file_ext == '.md' else 'text')
|
| 716 |
+
|
| 717 |
+
# --- Actions for the file (Select, Download, Delete) ---
|
| 718 |
+
action_cols = st.sidebar.columns(3) # Use columns for buttons
|
| 719 |
+
with action_cols[0]:
|
| 720 |
+
checkbox_key = f"cb_{item_key_base}"
|
| 721 |
+
st.session_state['asset_checkboxes'][file] = st.checkbox(
|
| 722 |
+
"Select",
|
| 723 |
+
value=st.session_state['asset_checkboxes'].get(file, False),
|
| 724 |
+
key=checkbox_key
|
| 725 |
+
)
|
| 726 |
+
with action_cols[1]:
|
| 727 |
+
mime_map = {'.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.pdf': 'application/pdf', '.txt': 'text/plain', '.md': 'text/markdown'}
|
| 728 |
+
mime_type = mime_map.get(file_ext, "application/octet-stream")
|
| 729 |
+
# Use button for download to avoid complex HTML link generation issues sometimes
|
| 730 |
+
dl_key = f"dl_{item_key_base}"
|
| 731 |
try:
|
| 732 |
+
with open(file, "rb") as fp:
|
| 733 |
+
st.download_button(
|
| 734 |
+
label="๐ฅ",
|
| 735 |
+
data=fp,
|
| 736 |
+
file_name=basename,
|
| 737 |
+
mime=mime_type,
|
| 738 |
+
key=dl_key,
|
| 739 |
+
help="Download this file"
|
| 740 |
+
)
|
| 741 |
+
except Exception as dl_e:
|
| 742 |
+
st.error(f"DL Err: {dl_e}")
|
| 743 |
+
|
| 744 |
+
with action_cols[2]:
|
| 745 |
+
delete_key = f"del_{item_key_base}"
|
| 746 |
+
if st.button("๐๏ธ", key=delete_key, help=f"Delete {basename}"):
|
| 747 |
+
try:
|
| 748 |
+
os.remove(file)
|
| 749 |
+
st.session_state['asset_checkboxes'].pop(file, None) # Remove from selection state
|
| 750 |
+
# Remove from layout_snapshots if present
|
| 751 |
+
if file in st.session_state.get('layout_snapshots', []):
|
| 752 |
+
st.session_state['layout_snapshots'].remove(file)
|
| 753 |
+
logger.info(f"Deleted asset: {file}")
|
| 754 |
+
st.toast(f"Deleted {basename}!", icon="โ
") # Use toast for less intrusive feedback
|
| 755 |
+
# REMOVED st.rerun() - Rely on file watcher
|
| 756 |
+
except OSError as e:
|
| 757 |
+
logger.error(f"Error deleting file {file}: {e}")
|
| 758 |
+
st.error(f"Could not delete {basename}")
|
| 759 |
+
# Trigger a rerun MANUALLY after deletion completes if file watcher is unreliable
|
| 760 |
+
st.rerun()
|
| 761 |
+
|
| 762 |
+
|
| 763 |
+
except (fitz.fitz.FileNotFoundError, FileNotFoundError):
|
| 764 |
+
st.sidebar.error(f"File not found: {basename}")
|
| 765 |
+
st.session_state['asset_checkboxes'].pop(file, None) # Clean up state
|
| 766 |
+
except (fitz.fitz.FileDataError, fitz.fitz.RuntimeException) as pdf_err:
|
| 767 |
+
st.sidebar.error(f"Corrupt PDF: {basename}")
|
| 768 |
+
logger.warning(f"Error opening PDF {file}: {pdf_err}")
|
| 769 |
+
except UnidentifiedImageError:
|
| 770 |
+
st.sidebar.error(f"Invalid Image: {basename}")
|
| 771 |
+
logger.warning(f"Cannot identify image file {file}")
|
| 772 |
+
except Exception as e:
|
| 773 |
+
st.sidebar.error(f"Error: {basename}")
|
| 774 |
+
logger.error(f"Error displaying asset {file}: {e}")
|
| 775 |
|
| 776 |
+
st.sidebar.markdown("---") # Separator between items
|
| 777 |
|
| 778 |
# --- UI Elements -----------------------------------------
|
| 779 |
|
|
|
|
| 941 |
st.image(Image.open(scan_name), caption=f"Scanned: {scan_name}", use_container_width=True)
|
| 942 |
if scan_name not in st.session_state['layout_snapshots']: st.session_state['layout_snapshots'].append(scan_name)
|
| 943 |
st.success(f"Scan saved as {scan_name}")
|
| 944 |
+
update_gallery(); # Add to gallery
|
| 945 |
except Exception as e: st.error(f"Failed to save scan: {e}"); logger.error(f"Failed to save camera scan {scan_name}: {e}")
|
| 946 |
|
| 947 |
layout_uploads = st.file_uploader("๐ Upload PNG/JPG Images for Layout PDF", type=["png","jpg","jpeg"], accept_multiple_files=True, key="layout_uploader")
|
|
|
|
| 1019 |
try:
|
| 1020 |
with open(filename, "wb") as f: f.write(cam0_img.getvalue())
|
| 1021 |
st.session_state['cam0_file'] = filename; st.session_state['history'].append(f"Snapshot from Cam 0: {filename}"); st.image(Image.open(filename), caption="Camera 0 Snap", use_container_width=True); logger.info(f"Saved snapshot from Camera 0: {filename}"); st.success(f"Saved {filename}")
|
| 1022 |
+
update_gallery();
|
| 1023 |
except Exception as e:
|
| 1024 |
st.error(f"Failed to save Cam 0 snap: {e}"); logger.error(f"Failed to save Cam 0 snap {filename}: {e}")
|
| 1025 |
with cols[1]:
|
|
|
|
| 1034 |
try:
|
| 1035 |
with open(filename, "wb") as f: f.write(cam1_img.getvalue())
|
| 1036 |
st.session_state['cam1_file'] = filename; st.session_state['history'].append(f"Snapshot from Cam 1: {filename}"); st.image(Image.open(filename), caption="Camera 1 Snap", use_container_width=True); logger.info(f"Saved snapshot from Camera 1: {filename}"); st.success(f"Saved {filename}")
|
| 1037 |
+
update_gallery();
|
| 1038 |
except Exception as e: st.error(f"Failed to save Cam 1 snap: {e}"); logger.error(f"Failed to save Cam 1 snap {filename}: {e}")
|
| 1039 |
|
| 1040 |
|
|
|
|
| 1059 |
if download_pdf(url, output_path): st.session_state['downloaded_pdfs'][url] = output_path; logger.info(f"Downloaded PDF from {url} to {output_path}"); st.session_state['history'].append(f"Downloaded PDF: {output_path}"); st.session_state['asset_checkboxes'][output_path] = False; download_count += 1; existing_pdfs.append(output_path)
|
| 1060 |
else: st.error(f"Failed to download: {url}")
|
| 1061 |
status_text.success(f"Download process complete! Successfully downloaded {download_count} new PDFs.")
|
| 1062 |
+
if download_count > 0: update_gallery();
|
| 1063 |
|
| 1064 |
st.subheader("Create Snapshots from Gallery PDFs")
|
| 1065 |
snapshot_mode = st.selectbox("Snapshot Mode", ["First Page (High-Res)", "First Two Pages (High-Res)", "All Pages (High-Res)", "First Page (Low-Res Preview)"], key="pdf_snapshot_mode")
|
|
|
|
| 1079 |
st.write(f"Snapshots for {os.path.basename(pdf_path)}:"); cols = st.columns(3)
|
| 1080 |
for i, snap_path in enumerate(new_snapshots):
|
| 1081 |
with cols[i % 3]: st.image(Image.open(snap_path), caption=os.path.basename(snap_path), use_container_width=True); st.session_state['asset_checkboxes'][snap_path] = False # Add to gallery
|
| 1082 |
+
if total_snapshots_generated > 0: st.success(f"Generated {total_snapshots_generated} snapshots from {snapshot_count} PDFs."); update_gallery();
|
| 1083 |
else: st.warning("No snapshots were generated. Check logs or PDF files.")
|
| 1084 |
|
| 1085 |
# --- Tab 4: Build Titan (Local Models) ---
|
|
|
|
| 1222 |
finally:
|
| 1223 |
progress_bar_build.progress(1.0)
|
| 1224 |
status_text_build.empty()
|
|
|
|
|
|
|
| 1225 |
|
| 1226 |
st.subheader("Manage Local Models")
|
| 1227 |
loaded_model_paths = list(st.session_state.get('local_models', {}).keys())
|
|
|
|
| 1254 |
shutil.rmtree(path_to_delete)
|
| 1255 |
st.success(f"Deleted model '{model_to_delete}' and its files.")
|
| 1256 |
logger.info(f"Deleted local model: {path_to_delete}")
|
|
|
|
| 1257 |
except Exception as e:
|
| 1258 |
st.error(f"Failed to delete model '{model_to_delete}': {e}")
|
| 1259 |
logger.error(f"Failed to delete model {path_to_delete}: {e}")
|