| import streamlit as st
|
| import pandas as pd
|
| import json
|
| import io
|
|
|
| st.set_page_config(page_title="URL Discovery Tool", layout="wide")
|
|
|
|
|
| st.markdown("""
|
| <style>
|
| .card {
|
| padding:15px;
|
| border-radius:10px;
|
| background-color:#f9f9f9;
|
| margin-bottom:10px;
|
| border:1px solid #ddd;
|
| }
|
| .metric-box {
|
| padding:15px;
|
| border-radius:10px;
|
| text-align:center;
|
| background:#f3f6fb;
|
| border:1px solid #ddd;
|
| }
|
| .metric-value {
|
| font-size:28px;
|
| font-weight:bold;
|
| }
|
| .metric-label {
|
| font-size:14px;
|
| color:#555;
|
| }
|
| </style>
|
| """, unsafe_allow_html=True)
|
|
|
| st.image("logo.png", width=80)
|
| st.title("π· URL Discovery Tool")
|
|
|
|
|
| if "index" not in st.session_state:
|
| st.session_state.index = 0
|
|
|
| if "df" not in st.session_state:
|
| st.session_state.df = None
|
|
|
| if "started" not in st.session_state:
|
| st.session_state.started = False
|
|
|
| if "stop" not in st.session_state:
|
| st.session_state.stop = False
|
|
|
| if "verified_added" not in st.session_state:
|
| st.session_state.verified_added = False
|
|
|
| if "reset_inputs" not in st.session_state:
|
| st.session_state.reset_inputs = False
|
|
|
|
|
| uploaded_file = st.file_uploader("Upload Excel File", type=["xlsx"])
|
|
|
| if uploaded_file:
|
|
|
|
|
| if st.session_state.df is None:
|
| st.session_state.df = pd.read_excel(uploaded_file)
|
|
|
| df = st.session_state.df
|
|
|
|
|
| st.markdown("## π Summary")
|
|
|
| total = len(df)
|
|
|
| completed = df["Status"].eq("Completed").sum() if "Status" in df.columns else 0
|
| pending = df["Status"].eq("Pending").sum() if "Status" in df.columns else 0
|
|
|
| if "Verified URL Count" in df.columns:
|
| total_urls = df["Verified URL Count"].fillna(0).sum()
|
| else:
|
| total_urls = 0
|
|
|
| c1, c2, c3, c4 = st.columns(4)
|
|
|
| c1.markdown(f"""
|
| <div class="metric-box">
|
| <div class="metric-value">{total}</div>
|
| <div class="metric-label">Total Entities</div>
|
| </div>
|
| """, unsafe_allow_html=True)
|
|
|
| c2.markdown(f"""
|
| <div class="metric-box">
|
| <div class="metric-value">{completed}</div>
|
| <div class="metric-label">Completed</div>
|
| </div>
|
| """, unsafe_allow_html=True)
|
|
|
| c3.markdown(f"""
|
| <div class="metric-box">
|
| <div class="metric-value">{pending}</div>
|
| <div class="metric-label">Pending</div>
|
| </div>
|
| """, unsafe_allow_html=True)
|
|
|
| c4.markdown(f"""
|
| <div class="metric-box">
|
| <div class="metric-value">{int(total_urls)}</div>
|
| <div class="metric-label">Total URLs Verified</div>
|
| </div>
|
| """, unsafe_allow_html=True)
|
|
|
| st.markdown("---")
|
|
|
|
|
| col1, col2 = st.columns(2)
|
|
|
| if col1.button("βΆ Start Processing", disabled=st.session_state.started):
|
| st.session_state.started = True
|
|
|
| if col2.button("π Stop Processing"):
|
| st.session_state.stop = True
|
| st.session_state.started = False
|
|
|
|
|
| if st.session_state.stop:
|
| st.warning("β οΈ Processing stopped")
|
|
|
| buffer = io.BytesIO()
|
| df.to_excel(buffer, index=False, engine="openpyxl")
|
|
|
| st.download_button("β¬ Download Progress", buffer.getvalue(), "partial.xlsx")
|
| st.stop()
|
|
|
| if not st.session_state.started:
|
| st.info("π Click Start Processing")
|
| st.stop()
|
|
|
| entity_list = df["Entity ID"].tolist()
|
|
|
|
|
| if st.session_state.index >= len(entity_list):
|
| st.success("β
All Done!")
|
|
|
| buffer = io.BytesIO()
|
| df.to_excel(buffer, index=False, engine="openpyxl")
|
| st.download_button("β¬ Download Final File", buffer.getvalue(), "final.xlsx")
|
| st.stop()
|
|
|
|
|
| entity_id = entity_list[st.session_state.index]
|
| row = df[df["Entity ID"] == entity_id].iloc[0]
|
|
|
|
|
| st.markdown(
|
| f'<h3>π <a href="https://crawler-admin.consumerism.pressganey.com/#/verify-sources/{entity_id}" target="_blank">Entity ID: {entity_id}</a></h3>',
|
| unsafe_allow_html=True
|
| )
|
|
|
|
|
| try:
|
| payload = json.loads(row["Payload"])
|
| entity_name = payload.get("name", "")
|
| except:
|
| entity_name = "N/A"
|
|
|
|
|
| st.markdown("### π§Ύ Entity Details")
|
|
|
| c1, c2, c3 = st.columns(3)
|
|
|
| with c1:
|
| st.markdown(f"""<div class="card">
|
| <b>Entity Name:</b> {entity_name}<br>
|
| <b>Client Name:</b> {row['Client Name']}
|
| </div>""", unsafe_allow_html=True)
|
|
|
| with c2:
|
| st.markdown(f"""<div class="card">
|
| <b>Industry:</b> {row['Industry ID']}<br>
|
| <b>Sync Partner:</b> {row['Sync Partner']}
|
| </div>""", unsafe_allow_html=True)
|
|
|
| with c3:
|
| st.markdown(f"""<div class="card">
|
| <b>Products:</b> {row['Client Products']}<br>
|
| <b>Type:</b> {row['Entity Type']}
|
| </div>""", unsafe_allow_html=True)
|
|
|
|
|
| st.markdown("### π Error Details")
|
|
|
| cols = df.columns.tolist()
|
| start = cols.index("Healthgrades")
|
| end = cols.index("AppleMaps") + 1
|
|
|
| sources = cols[start:end]
|
|
|
| data = []
|
| for col in sources:
|
| val = str(row[col]).strip()
|
|
|
| if val and val.lower() != "nan":
|
|
|
| if "404" in val or "No URLs" in val:
|
| action = "Add URL"
|
| elif "500" in val:
|
| action = "Retry"
|
| elif "Different URL already exists" in val:
|
| action = "Verify Duplicate"
|
| else:
|
| action = ""
|
|
|
| data.append({
|
| "Source": col,
|
| "Value": val,
|
| "Action": action
|
| })
|
|
|
| if data:
|
| st.dataframe(pd.DataFrame(data), use_container_width=True)
|
|
|
|
|
| progress = (st.session_state.index + 1) / len(entity_list)
|
| st.progress(progress)
|
| st.caption(f"{st.session_state.index + 1} / {len(entity_list)}")
|
|
|
|
|
| if st.session_state.reset_inputs:
|
| st.session_state["verified_input"] = ""
|
| st.session_state["remarks_input"] = ""
|
| st.session_state.reset_inputs = False
|
|
|
|
|
| st.markdown("### π Remarks")
|
| remarks = st.text_area("Enter remarks", key="remarks_input")
|
|
|
|
|
| st.markdown("### π’ URL Verification")
|
|
|
| col1, col2 = st.columns([2, 1])
|
|
|
| verified_count = col1.text_input(
|
| "No of URLs Verified",
|
| key="verified_input"
|
| )
|
|
|
| if col2.button("β Add"):
|
| if verified_count.strip().isdigit():
|
|
|
| df.loc[df["Entity ID"] == entity_id, "Verified URL Count"] = int(verified_count)
|
| df.loc[df["Entity ID"] == entity_id, "Remarks"] = remarks
|
|
|
| st.session_state.verified_added = True
|
| st.success("β
Added successfully")
|
|
|
| else:
|
| st.error("β Enter valid number")
|
|
|
|
|
| col_done, col_pending = st.columns(2)
|
|
|
| if st.session_state.verified_added:
|
|
|
| if col_done.button("β
Completed & Next"):
|
| df.loc[df["Entity ID"] == entity_id, "Status"] = "Completed"
|
|
|
| st.session_state.index += 1
|
| st.session_state.verified_added = False
|
| st.session_state.reset_inputs = True
|
|
|
| st.rerun()
|
|
|
| if col_pending.button("β³ Pending & Next"):
|
| df.loc[df["Entity ID"] == entity_id, "Status"] = "Pending"
|
|
|
| st.session_state.index += 1
|
| st.session_state.verified_added = False
|
| st.session_state.reset_inputs = True
|
|
|
| st.rerun()
|
|
|
| else:
|
| st.info("π Add verified URL count to proceed") |