Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import joblib | |
| import re | |
| from related_news import fetch_related_articles | |
| # Load model and vectorizer | |
| model = joblib.load("model.pkl") | |
| vectorizer = joblib.load("vectorizer.pkl") | |
| # π§Ό Text cleaning function | |
| def clean_text(text): | |
| text = re.sub(r"http\S+", "", text) | |
| text = re.sub(r"[^a-zA-Z\s]", "", text) | |
| text = text.lower() | |
| return text | |
| # π Page setup | |
| st.set_page_config( | |
| page_title="TruthRadar π§ ", | |
| page_icon="π°οΈ", | |
| layout="centered", | |
| initial_sidebar_state="auto" | |
| ) | |
| # π¨ Custom styles for light theme | |
| st.markdown(""" | |
| <style> | |
| body, .reportview-container, .main { | |
| background-color: white !important; | |
| color: black !important; | |
| } | |
| .stTextArea textarea { | |
| background-color: #ffffff !important; | |
| color: #111827 !important; | |
| font-size: 16px !important; | |
| border: 1px solid #d1d5db !important; | |
| border-radius: 10px !important; | |
| padding: 12px !important; | |
| } | |
| .stButton > button { | |
| background-color: #2563eb; | |
| color: white; | |
| border-radius: 0.5rem; | |
| padding: 0.6rem 1.2rem; | |
| } | |
| .stButton > button:hover { | |
| background-color: #1e40af; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # π°οΈ Header | |
| st.markdown("<h1 style='text-align: center; color: #1f2937;'>π°οΈ TruthRadar</h1>", unsafe_allow_html=True) | |
| st.markdown("<p style='text-align: center; color: #4b5563;'>Detect fake news in a flash β headlines or full articles π</p>", unsafe_allow_html=True) | |
| st.markdown("---") | |
| st.markdown("<p style='color: #4b5563;'>Currently optimised for US-based news articles.</p>", unsafe_allow_html=True) | |
| #input | |
| st.markdown("<label style='font-weight:600; font-size:16px; color:#1f2937;'>π Paste any news headline or article below:</label>", unsafe_allow_html=True) | |
| user_input = st.text_area("", height=200) | |
| # π Analyze button | |
| if st.button("π Analyze"): | |
| if not user_input.strip(): | |
| st.warning("Bruhhh paste *something* to analyze π ") | |
| else: | |
| with st.spinner("π§ Scanning for truth..."): | |
| try: | |
| cleaned = clean_text(user_input) | |
| transformed = vectorizer.transform([cleaned]) | |
| prediction = model.predict(transformed)[0] | |
| proba = model.predict_proba(transformed)[0] | |
| confidence = max(proba) * 100 | |
| label = prediction.upper() | |
| articles = fetch_related_articles(user_input) | |
| # β¨ Show prediction result using markdown for HTML formatting | |
| if label == "REAL": | |
| st.markdown("<div style='background-color:#dcfce7; padding:10px; border-radius:8px;'><strong>β Prediction:</strong> <span style='color:green;'>REAL</span></div>", unsafe_allow_html=True) | |
| else: | |
| st.markdown("<div style='background-color:#fee2e2; padding:10px; border-radius:8px;'><strong>β Prediction:</strong> <span style='color:#b91c1c;'>FAKE</span></div>", unsafe_allow_html=True) | |
| st.markdown(f"<div style='background-color:#e0f2fe; padding:10px; border-radius:8px;'><strong>π Confidence:</strong> <span style='color:#2563eb;'>{confidence:.2f}%</span></div>", unsafe_allow_html=True) | |
| # π§ Improved keyword matching for warning | |
| if label == "FAKE": | |
| input_keywords = set(re.findall(r'\b\w{4,}\b', user_input.lower())) | |
| similar_found = any( | |
| any(word in (article.get("title", "") + article.get("description", "")).lower() | |
| for word in input_keywords) | |
| for article in articles | |
| ) | |
| if similar_found: | |
| st.markdown( | |
| "<div style='background-color:#fef9c3; padding:10px; border-radius:8px;'><strong>π§ Warning:</strong> <span style='color:#92400e;'> Similar stories were found from trusted sources. Cross-check below.</span></div>", | |
| unsafe_allow_html=True | |
| ) | |
| # π° Related News Display | |
| st.markdown("---") | |
| st.markdown("<h3 style='color:#1f2937;'>π° Related News from Trusted Sources</h3>", unsafe_allow_html=True) | |
| if not articles: | |
| st.write("No related articles found.") | |
| else: | |
| for article in articles: | |
| title = article.get("title", "No title") | |
| url = article.get("url", "#") | |
| desc = article.get("description", "No description available.") | |
| st.markdown(f"**[{title}]({url})**") | |
| st.caption(desc) | |
| except Exception as e: | |
| st.error(f"π¨ Error: {e}") | |
| # π Footer | |
| st.markdown("---") | |
| st.markdown("<p style='text-align: center; font-size: 0.9em; color: gray;'>Made with π» by Sai Srikar β’ TruthRadar AI</p>", unsafe_allow_html=True) | |