Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -130,6 +130,7 @@ def main():
|
|
| 130 |
</div>
|
| 131 |
""", unsafe_allow_html=True)
|
| 132 |
|
|
|
|
| 133 |
st.sidebar.image("logoqb.jpeg", use_container_width=True)
|
| 134 |
st.sidebar.header("Scrape & Configure")
|
| 135 |
|
|
@@ -156,63 +157,54 @@ def main():
|
|
| 156 |
with st.spinner("Searching in progress... Please wait patiently."):
|
| 157 |
result = process_multiple_search_terms(search_terms)
|
| 158 |
st.session_state.scraped_data = result
|
| 159 |
-
st.success(f"β
|
| 160 |
except Exception as e:
|
| 161 |
-
st.error(f"π¨ Searching process encountered an error: {e}")
|
| 162 |
else:
|
| 163 |
-
st.warning("β οΈ Please enter valid search terms.")
|
| 164 |
else:
|
| 165 |
-
st.warning("β οΈ Please enter at least one search term to begin.")
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
st.
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
if selected_format == "CSV":
|
| 182 |
-
file_data = convert_to_csv(st.session_state.scraped_data)
|
| 183 |
-
file_name = "grants_data.csv"
|
| 184 |
-
file_type = "text/csv"
|
| 185 |
-
else:
|
| 186 |
-
file_data = convert_to_excel(st.session_state.scraped_data)
|
| 187 |
-
file_name = "grants_data.xlsx"
|
| 188 |
-
file_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
| 189 |
|
| 190 |
-
|
| 191 |
-
|
| 192 |
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
email_url = f"mailto:?subject={email_subject}&body={email_body}"
|
| 199 |
|
| 200 |
-
|
| 201 |
-
|
| 202 |
|
| 203 |
-
|
|
|
|
| 204 |
with st.spinner("Loading data into knowledge base..."):
|
| 205 |
create_knowledge_base(st.session_state.scraped_data)
|
| 206 |
st.session_state.chat_interface_active = True
|
| 207 |
st.session_state.chat_history = []
|
| 208 |
-
st.success("Knowledge base loaded!
|
| 209 |
|
|
|
|
| 210 |
if st.session_state.get("chat_interface_active"):
|
| 211 |
-
st.markdown("---")
|
| 212 |
-
st.
|
| 213 |
-
st.
|
| 214 |
-
|
| 215 |
-
query = st.text_input("Your question:", key="chat_input")
|
| 216 |
if query:
|
| 217 |
with st.spinner("Generating response..."):
|
| 218 |
response = chat_with_knowledge_base(query)
|
|
@@ -220,12 +212,24 @@ def main():
|
|
| 220 |
answer = response["answer"] if isinstance(response, dict) and "answer" in response else response
|
| 221 |
st.session_state.chat_history.append({"query": query, "response": answer})
|
| 222 |
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
|
| 227 |
-
|
|
|
|
| 228 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 229 |
else:
|
| 230 |
st.info("β¬
οΈ Enter search terms in the sidebar and click 'Get Grant Opportunities' to start searching.")
|
| 231 |
|
|
|
|
| 130 |
</div>
|
| 131 |
""", unsafe_allow_html=True)
|
| 132 |
|
| 133 |
+
# Sidebar controls
|
| 134 |
st.sidebar.image("logoqb.jpeg", use_container_width=True)
|
| 135 |
st.sidebar.header("Scrape & Configure")
|
| 136 |
|
|
|
|
| 157 |
with st.spinner("Searching in progress... Please wait patiently."):
|
| 158 |
result = process_multiple_search_terms(search_terms)
|
| 159 |
st.session_state.scraped_data = result
|
| 160 |
+
st.sidebar.success(f"β
Found {len(result['grants'])} grant opportunities from {len(search_terms)} search terms!")
|
| 161 |
except Exception as e:
|
| 162 |
+
st.sidebar.error(f"π¨ Searching process encountered an error: {e}")
|
| 163 |
else:
|
| 164 |
+
st.sidebar.warning("β οΈ Please enter valid search terms.")
|
| 165 |
else:
|
| 166 |
+
st.sidebar.warning("β οΈ Please enter at least one search term to begin.")
|
| 167 |
+
|
| 168 |
+
# Sidebar: Download and Share Options
|
| 169 |
+
if st.session_state.scraped_data and st.session_state.scraped_data.get('grants'):
|
| 170 |
+
st.sidebar.markdown("---")
|
| 171 |
+
st.sidebar.subheader("Download & Share")
|
| 172 |
+
|
| 173 |
+
selected_format = st.sidebar.selectbox("Download As:", ("CSV", "Excel"), key="download_format_selector")
|
| 174 |
+
if selected_format == "CSV":
|
| 175 |
+
file_data = convert_to_csv(st.session_state.scraped_data)
|
| 176 |
+
file_name = "grants_data.csv"
|
| 177 |
+
file_type = "text/csv"
|
| 178 |
+
else:
|
| 179 |
+
file_data = convert_to_excel(st.session_state.scraped_data)
|
| 180 |
+
file_name = "grants_data.xlsx"
|
| 181 |
+
file_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 182 |
|
| 183 |
+
download_link_html = f"<a href='data:{file_type};base64,{base64.b64encode(file_data).decode()}' download='{file_name}'><button style='background-color:#4CAF50;color:white;padding:10px 15px;border:none;border-radius:4px;'>β¬οΈ Download {selected_format}</button></a>"
|
| 184 |
+
st.sidebar.markdown(download_link_html, unsafe_allow_html=True)
|
| 185 |
|
| 186 |
+
shareable_link = get_shareable_link(file_data, file_name, file_type)
|
| 187 |
+
whatsapp_url = f"https://api.whatsapp.com/send?text={urllib.parse.quote(f'Check out these grant opportunities: {shareable_link}')}"
|
| 188 |
+
email_subject = urllib.parse.quote("Grant Opportunities File")
|
| 189 |
+
email_body = urllib.parse.quote(f"Download the grant opportunities file here: {shareable_link}")
|
| 190 |
+
email_url = f"mailto:?subject={email_subject}&body={email_body}"
|
|
|
|
| 191 |
|
| 192 |
+
st.sidebar.markdown("<div style='margin-top:10px;'>Share via:</div>", unsafe_allow_html=True)
|
| 193 |
+
st.sidebar.markdown(f"π± [WhatsApp]({whatsapp_url}) | π§ [Email]({email_url})", unsafe_allow_html=True)
|
| 194 |
|
| 195 |
+
# Sidebar: Load as Knowledge Base & Chat
|
| 196 |
+
if st.sidebar.button("π§ Load as Knowledge Base & Chat"):
|
| 197 |
with st.spinner("Loading data into knowledge base..."):
|
| 198 |
create_knowledge_base(st.session_state.scraped_data)
|
| 199 |
st.session_state.chat_interface_active = True
|
| 200 |
st.session_state.chat_history = []
|
| 201 |
+
st.sidebar.success("Knowledge base loaded!")
|
| 202 |
|
| 203 |
+
# Sidebar: Chat Interface
|
| 204 |
if st.session_state.get("chat_interface_active"):
|
| 205 |
+
st.sidebar.markdown("---")
|
| 206 |
+
st.sidebar.subheader("π¬ Chat with Grants Bot")
|
| 207 |
+
query = st.sidebar.text_input("Your question:", key="chat_input")
|
|
|
|
|
|
|
| 208 |
if query:
|
| 209 |
with st.spinner("Generating response..."):
|
| 210 |
response = chat_with_knowledge_base(query)
|
|
|
|
| 212 |
answer = response["answer"] if isinstance(response, dict) and "answer" in response else response
|
| 213 |
st.session_state.chat_history.append({"query": query, "response": answer})
|
| 214 |
|
| 215 |
+
# Main area: Preview data and chat history
|
| 216 |
+
st.markdown("---")
|
| 217 |
+
if st.session_state.scraped_data and st.session_state.scraped_data.get('grants'):
|
| 218 |
+
st.header("π Found Grant Data")
|
| 219 |
+
with st.expander(f"π Preview Grant Data ({len(st.session_state.scraped_data['grants'])} grants)"):
|
| 220 |
+
st.dataframe(st.session_state.scraped_data["grants"])
|
| 221 |
|
| 222 |
+
if st.session_state.chat_history:
|
| 223 |
+
st.subheader("Chat History")
|
| 224 |
+
for chat in st.session_state.chat_history:
|
| 225 |
+
# User message: dark grey background with white text
|
| 226 |
+
st.markdown(
|
| 227 |
+
f"<div style='padding: 10px; border-radius: 5px; margin-bottom: 5px; background-color:#444444; color: white;'><strong>You:</strong> {chat['query']}</div>",
|
| 228 |
+
unsafe_allow_html=True)
|
| 229 |
+
# Bot message: blue background with white text
|
| 230 |
+
st.markdown(
|
| 231 |
+
f"<div style='padding: 10px; border-radius: 5px; margin-bottom: 10px; background-color:#007BFF; color: white;'><strong>Grants Bot:</strong> {chat['response']}</div>",
|
| 232 |
+
unsafe_allow_html=True)
|
| 233 |
else:
|
| 234 |
st.info("β¬
οΈ Enter search terms in the sidebar and click 'Get Grant Opportunities' to start searching.")
|
| 235 |
|