chagu-dev / app-memora.py
vikee's picture
Apps isolation
9228cad
from pathlib import Path
import streamlit as st
from googlesearch import search
import pandas as pd
import os
from rag_sec.document_search_system import DocumentSearchSystem
from chainguard.blockchain_logger import BlockchainLogger
from PIL import Image
from itertools import cycle
# Blockchain Logger
blockchain_logger = BlockchainLogger()
# Directory for storing uploaded files
UPLOAD_DIR = "uploaded_files"
os.makedirs(UPLOAD_DIR, exist_ok=True)
# Initialize DocumentSearchSystem
@st.cache_resource
def initialize_system():
"""Initialize the DocumentSearchSystem and load documents."""
system = DocumentSearchSystem(
neo4j_uri="neo4j+s://0ca71b10.databases.neo4j.io",
neo4j_user="neo4j",
neo4j_password="HwGDOxyGS1-79nLeTiX5bx5ohoFSpvHCmTv8IRgt-lY"
)
system.retriever.load_documents()
return system
# Initialize the system
system = initialize_system()
st.title("Memora: Secure File Upload and Search with Blockchain & Neo4j")
st.subheader("Personalized news and global updates at your fingertips")
# File Upload Section
uploaded_files = st.file_uploader("Upload your files", accept_multiple_files=True, type=['jpg', 'jpeg', 'png', 'mp4', 'avi'])
if uploaded_files:
for uploaded_file in uploaded_files:
# Save file locally
file_path = os.path.join(UPLOAD_DIR, uploaded_file.name)
with open(file_path, "wb") as f:
f.write(uploaded_file.getbuffer())
st.success(f"File saved locally: {file_path}")
# Display uploaded file details
if uploaded_file.type.startswith('image'):
image = Image.open(uploaded_file)
st.image(image, caption=uploaded_file.name, use_column_width=True)
# Metadata Input
album = st.text_input(f"Album for {uploaded_file.name}", "Default Album")
tags = st.text_input(f"Tags for {uploaded_file.name} (comma-separated)", "")
# Log Metadata and Transaction
if st.button(f"Log Metadata for {uploaded_file.name}"):
metadata = {"file_name": uploaded_file.name, "tags": tags.split(','), "album": album}
blockchain_details = blockchain_logger.log_data(metadata)
blockchain_hash = blockchain_details.get("block_hash", "N/A")
# Use Neo4jHandler from DocumentSearchSystem to log the transaction
system.neo4j_handler.log_relationships(uploaded_file.name, tags, blockchain_hash, [album])
st.write(f"Metadata logged successfully! Blockchain Details: {blockchain_details}")
# Blockchain Integrity Validation
if st.button("Validate Blockchain Integrity"):
is_valid = blockchain_logger.is_blockchain_valid()
st.write("Blockchain Integrity:", "Valid βœ…" if is_valid else "Invalid ❌")
# Document Search Section
st.subheader("Search Documents")
# Google Search: User-Specific News
st.subheader("1. Latest News About You")
user_name = st.text_input("Enter your name or handle to search for recent news", value="Talex Maxim")
if st.button("Search News About Me"):
if user_name:
st.write(f"Searching Google for news about **{user_name}**...")
try:
results = list(search(user_name, num_results=5))
if results:
st.success(f"Top {len(results)} results for '{user_name}':")
user_news_data = {"URL": results}
df_user_news = pd.DataFrame(user_news_data)
st.dataframe(df_user_news)
else:
st.warning("No recent news found about you.")
except Exception as e:
st.error(f"An error occurred during the search: {str(e)}")
else:
st.warning("Please enter your name or handle to search.")
# Google Search: Global News Categories
categories = ["Technology", "Sports", "Politics", "Entertainment", "Science"]
st.title("Global News Insights")
# News Results Dictionary
news_results = {}
try:
# Fetch News for Each Category
for category in categories:
try:
news_results[category] = list(search(f"latest {category} news", num_results=3))
except Exception as e:
news_results[category] = [f"Error fetching news: {str(e)}"]
# Display Results with Styled Buttons
for category, articles in news_results.items():
st.subheader(f"{category} News")
cols = st.columns(3) # Create 3 columns for the layout
if articles and "Error fetching news" not in articles[0]:
for idx, article in enumerate(articles):
with cols[idx % 3]: # Cycle through columns
st.markdown(
f"""
<div style="padding: 10px; border: 1px solid #ccc; border-radius: 5px; margin: 10px; text-align: center;">
<a href="{article}" target="_blank" style="text-decoration: none;">
<button style="background-color: #c4ccc8; color: white; border: none; padding: 10px 20px; text-align: center; display: inline-block; font-size: 16px; border-radius: 5px;">
{category}-{idx + 1}
</button>
</a>
</div>
""",
unsafe_allow_html=True,
)
else:
st.warning(f"Could not fetch news for **{category}**.")
except Exception as e:
st.error(f"An unexpected error occurred: {str(e)}")
# # Display results
# for category, articles in news_results.items():
# st.write(f"### Top News in {category}:")
# for idx, article in enumerate(articles, start=1):
# st.write(f"{idx}. [Read here]({article})")
# except Exception as e:
# st.error(f"An error occurred while fetching global news: {str(e)}")
# Document Search
st.subheader("3. Search Documents")
query = st.text_input("Enter your query (e.g., 'sports news', 'machine learning')")
if st.button("Search Documents"):
if query:
result = system.process_query(query)
if result["status"] == "success":
st.success(f"Query processed successfully!")
st.write("### Query Response:")
st.write(result["response"])
st.write("### Retrieved Documents:")
for idx, doc in enumerate(result["retrieved_documents"], start=1):
st.write(f"**Document {idx}:**")
st.write(doc[:500]) # Display the first 500 characters
st.write("### Blockchain Details:")
st.json(result["blockchain_details"])
elif result["status"] == "no_results":
st.warning("No relevant documents found for your query.")
elif result["status"] == "rejected":
st.error(result["message"])
else:
st.warning("Please enter a query to search.")
# Debugging Section
if st.checkbox("Show Debug Information"):
st.write(f"Total documents loaded: {len(system.retriever.documents)}")