import streamlit as st
import os
import shutil
import base64
import PyPDF2
from datetime import datetime
from PyPDF2 import PdfFileMerger, PdfFileReader
from PIL import Image
st.set_page_config(
page_title="QTG Review System",
page_icon="π",
layout="wide",
initial_sidebar_state="expanded",
)
source_folder = "source_folder"
pass_folder = "pass_folder"
fail_folder = "fail_folder"
signed_folder = "signed_folder"
def list_files(folder):
try:
return os.listdir(folder)
except FileNotFoundError:
return []
def move_file(src, dest):
try:
shutil.move(src, dest)
return True
except Exception as e:
st.error(f"Error moving file {src} to {dest}: {e}")
return False
def retrieve_files(selected_files, src_folder, dest_folder):
moved_files = []
for item in selected_files:
src_path = os.path.join(src_folder, item)
dest_path = os.path.join(dest_folder, item)
if move_file(src_path, dest_path):
moved_files.append(item)
return moved_files
st.sidebar.header("QTG Review System")
st.sidebar.markdown("Manage and review your QTG files efficiently.")
def get_file_link(file_path):
with open(file_path, "rb") as f:
pdf_data = f.read()
b64 = base64.b64encode(pdf_data).decode() # Encode to base64
return f'<a href="data:application/pdf;base64,{b64}" target="_blank">Open PDF</a>'
def add_signature_to_pdf(pdf_path, signature_path, output_path):
try:
pdf_reader = PdfFileReader(pdf_path)
pdf_writer = PdfFileMerger()
for page_num in range(len(pdf_reader.pages)):
page = pdf_reader.pages[page_num]
if page_num == 0: # Add signature to the first page only
signature_img = Image.open(signature_path)
pdf_writer.add_page(page)
with open(output_path, "wb") as f_out:
pdf_writer.write(f_out)
return True
except Exception as e:
st.error(f"Error signing PDF: {e}")
return False
tab1, tab2, tab3 = st.tabs(["π Manage QTG Files", "π Retrieve Files", "ποΈ E-Sign Document"])
with tab1:
st.header("π QTG Review and Classification")
with st.container(border=True):
st.subheader("1. Review QTG Files")
files = list_files(source_folder)
if files:
file_to_move = st.selectbox("Select the QTG to review", files)
pdf_file_path = os.path.join(source_folder, file_to_move)
if os.path.exists(pdf_file_path):
# Create an Open PDF button
open_pdf_link = get_file_link(pdf_file_path)
st.markdown(open_pdf_link, unsafe_allow_html=True)
status = st.radio("Status of QTG", ["Pass", "Fail"], horizontal=True)
if st.button("Submit"):
destination_folder = pass_folder if status == "Pass" else fail_folder
src_path = os.path.join(source_folder, file_to_move)
dest_path = os.path.join(destination_folder, file_to_move)
if move_file(src_path, dest_path):
st.success(f"Moved '{file_to_move}' to **{'Pass' if status == 'Pass' else 'Fail'}** folder.")
else:
st.warning("π« No files to move in the source folder.")
st.markdown("---") # Separator
with st.container(border=True):
st.subheader("2. View Folder Contents")
col1, col2, col3 = st.columns(3)
with col1:
st.markdown("### π Source Folder")
source_contents = list_files(source_folder)
if source_contents:
for item in source_contents:
st.markdown(f"- **{item}**")
else:
st.write("No files in source folder.")
with col2:
st.markdown("### Pass Folder")
pass_contents = list_files(pass_folder)
if pass_contents:
for item in pass_contents:
st.markdown(f"- **{item}**")
else:
st.write("No files in pass folder.")
with col3:
st.markdown("### Fail Folder")
fail_contents = list_files(fail_folder)
if fail_contents:
for item in fail_contents:
st.markdown(f"- **{item}**")
else:
st.write("No files in fail folder.")
with tab2:
st.header("π Retrieve Files to Source Folder")
with st.container(border=True):
st.subheader("1. Select Files to Retrieve")
st.markdown("#### π Files in Pass Folder")
pass_files = list_files(pass_folder)
selected_pass = []
if pass_files:
selected_pass = st.multiselect("Select files to retrieve from Pass folder:", pass_files)
else:
st.write("No files to retrieve from Pass folder.")
st.markdown("#### Files in Fail Folder")
fail_files = list_files(fail_folder)
selected_fail = []
if fail_files:
selected_fail = st.multiselect("Select files to retrieve from Fail folder:", fail_files)
else:
st.write("No files to retrieve from Fail folder.")
if st.button("Retrieve Selected Files"):
retrieved_files = []
if selected_pass:
moved_pass = retrieve_files(selected_pass, pass_folder, source_folder)
retrieved_files.extend(moved_pass)
if selected_fail:
moved_fail = retrieve_files(selected_fail, fail_folder, source_folder)
retrieved_files.extend(moved_fail)
if retrieved_files:
st.success(f"Retrieved files: {', '.join(retrieved_files)} back to the source folder!")
else:
st.info("βΉοΈ No files selected for retrieval.")
st.markdown("---") # Separator
with st.container(border=True):
st.subheader("2. Updated Folder Contents")
col1, col2, col3 = st.columns(3)
with col1:
st.markdown("### π Source Folder")
source_contents = list_files(source_folder)
if source_contents:
for item in source_contents:
st.markdown(f"- **{item}**")
else:
st.write("No files in source folder.")
with col2:
st.markdown("### Pass Folder")
pass_contents = list_files(pass_folder)
if pass_contents:
for item in pass_contents:
st.markdown(f"- **{item}**")
else:
st.write("No files in pass folder.")
with col3:
st.markdown("### Fail Folder")
fail_contents = list_files(fail_folder)
if fail_contents:
for item in fail_contents:
st.markdown(f"- **{item}**")
else:
st.write("No files in fail folder.")
with tab3:
st.header("ποΈ E-Sign Document")
st.subheader("Upload Signature Image")
signature_image = st.file_uploader("Choose an image file for your signature", type=["png", "jpg", "jpeg"])
if signature_image:
st.image(signature_image, caption="Uploaded Signature Image", use_column_width=True)
st.subheader("Select Document to Sign")
pass_files = list_files(pass_folder)
if pass_files:
file_to_sign = st.selectbox("Select a document to sign", pass_files)
selected_file_path = os.path.join(pass_folder, file_to_sign)
signed_file_path = os.path.join(signed_folder, f"signed_{file_to_sign}")
if st.button("Apply Signature"):
if signature_image:
# Save signature image temporarily for adding to PDF
signature_path = f"temp_signature_{file_to_sign}.png"
with open(signature_path, "wb") as sig_file:
sig_file.write(signature_image.getbuffer())
if add_signature_to_pdf(selected_file_path, signature_path, signed_file_path):
st.success(f"Signature applied to {file_to_sign} successfully!")
st.markdown(f"[Download Signed Document](signed_folder/{signed_file_path})", unsafe_allow_html=True)
os.remove(signature_path)
else:
st.warning("Please upload a signature image first.")
else:
st.info("No documents in the 'Pass' folder to sign.")
In the code shown above, I tried to esign the pdf after it is declared as pass. Please help me in this regard, whether streamlit is already having an option to esign the pdf document using the app.