|
import os |
|
import streamlit as st |
|
import google.generativeai as genai |
|
from dotenv import load_dotenv |
|
from PIL import Image |
|
import pandas as pd |
|
import numpy as np |
|
from typing import Dict, Any, List |
|
|
|
|
|
load_dotenv() |
|
|
|
|
|
genai.configure(api_key=os.getenv('GOOGLE_API_KEY')) |
|
|
|
|
|
st.set_page_config( |
|
page_title="Advanced Fake News Detector π΅οΈββοΈ", |
|
page_icon="π¨", |
|
layout="wide" |
|
) |
|
|
|
|
|
st.markdown(""" |
|
<style> |
|
.main-container { |
|
background-color: #f0f2f6; |
|
padding: 2rem; |
|
border-radius: 15px; |
|
} |
|
.analysis-box { |
|
background-color: white; |
|
border-radius: 10px; |
|
padding: 1.5rem; |
|
box-shadow: 0 4px 6px rgba(0,0,0,0.1); |
|
} |
|
.stButton>button { |
|
background-color: #4CAF50; |
|
color: white; |
|
font-weight: bold; |
|
border: none; |
|
padding: 10px 20px; |
|
border-radius: 5px; |
|
transition: all 0.3s ease; |
|
} |
|
.stButton>button:hover { |
|
background-color: #45a049; |
|
transform: scale(1.05); |
|
} |
|
</style> |
|
""", unsafe_allow_html=True) |
|
|
|
class FakeNewsDetector: |
|
def __init__(self): |
|
"""Initialize the Fake News Detection system""" |
|
self.model = genai.GenerativeModel('gemini-2.0-flash') |
|
|
|
def analyze_article(self, article_text: str) -> Dict[str, Any]: |
|
""" |
|
Analyze the article using Gemini AI |
|
|
|
Args: |
|
article_text (str): Full text of the article |
|
|
|
Returns: |
|
Dict containing analysis results |
|
""" |
|
prompt = f"""Comprehensive Fake News Analysis: |
|
|
|
Article Text: |
|
{article_text} |
|
|
|
Provide a detailed analysis with: |
|
1. Fake News Probability (0-100%) |
|
2. Credibility Score (0-10) |
|
3. Key Red Flags |
|
4. Verification Recommendations |
|
5. Potential Bias Indicators |
|
6. Source Reliability Assessment |
|
|
|
Format response as a structured JSON.""" |
|
|
|
try: |
|
response = self.model.generate_content(prompt) |
|
return self._parse_analysis(response.text) |
|
except Exception as e: |
|
st.error(f"Analysis Error: {e}") |
|
return {} |
|
|
|
def _parse_analysis(self, analysis_text: str) -> Dict[str, Any]: |
|
""" |
|
Parse the AI-generated analysis into a structured format |
|
|
|
Args: |
|
analysis_text (str): Raw analysis text |
|
|
|
Returns: |
|
Parsed analysis dictionary |
|
""" |
|
try: |
|
|
|
return { |
|
'fake_news_probability': self._extract_percentage(analysis_text), |
|
'credibility_score': self._extract_score(analysis_text), |
|
'red_flags': self._extract_red_flags(analysis_text), |
|
'verification_steps': self._extract_verification_steps(analysis_text), |
|
'bias_indicators': self._extract_bias_indicators(analysis_text), |
|
'source_reliability': self._extract_source_reliability(analysis_text) |
|
} |
|
except Exception as e: |
|
st.warning(f"Parsing Error: {e}") |
|
return {} |
|
|
|
def _extract_percentage(self, text: str) -> float: |
|
"""Extract fake news probability percentage""" |
|
import re |
|
match = re.search(r'(\d+(?:\.\d+)?)\s*%', text) |
|
return float(match.group(1)) if match else 50.0 |
|
|
|
def _extract_score(self, text: str) -> float: |
|
"""Extract credibility score""" |
|
import re |
|
match = re.search(r'Credibility Score[:\s]*(\d+(?:\.\d+)?)', text) |
|
return float(match.group(1)) if match else 5.0 |
|
|
|
def _extract_red_flags(self, text: str) -> List[str]: |
|
"""Extract red flags from the analysis""" |
|
import re |
|
flags = re.findall(r'Red Flags?[:\s]*([^\n]+)', text, re.IGNORECASE) |
|
return flags[:3] if flags else ["No specific red flags identified"] |
|
|
|
def _extract_verification_steps(self, text: str) -> List[str]: |
|
"""Extract verification recommendations""" |
|
import re |
|
steps = re.findall(r'Verification[:\s]*([^\n]+)', text, re.IGNORECASE) |
|
return steps[:3] if steps else ["Conduct independent research"] |
|
|
|
def _extract_bias_indicators(self, text: str) -> List[str]: |
|
"""Extract potential bias indicators""" |
|
import re |
|
biases = re.findall(r'Bias[:\s]*([^\n]+)', text, re.IGNORECASE) |
|
return biases[:3] if biases else ["No clear bias detected"] |
|
|
|
def _extract_source_reliability(self, text: str) -> str: |
|
"""Extract source reliability assessment""" |
|
import re |
|
match = re.search(r'Source Reliability[:\s]*([^\n]+)', text, re.IGNORECASE) |
|
return match.group(1) if match else "Reliability not conclusively determined" |
|
|
|
def main(): |
|
st.title("π¨ Advanced Fake News Detector") |
|
st.markdown("Powered by Google's Gemini 2.0 Flash AI") |
|
|
|
|
|
st.sidebar.header("π οΈ Detection Settings") |
|
confidence_threshold = st.sidebar.slider( |
|
"Confidence Threshold", |
|
min_value=0.0, |
|
max_value=1.0, |
|
value=0.7, |
|
step=0.05 |
|
) |
|
|
|
|
|
st.header("π Article Analysis") |
|
article_text = st.text_area( |
|
"Paste the full article text", |
|
height=300, |
|
help="Copy and paste the complete article for comprehensive analysis" |
|
) |
|
|
|
|
|
st.header("πΌοΈ Article Evidence") |
|
uploaded_image = st.file_uploader( |
|
"Upload supporting/source image", |
|
type=['png', 'jpg', 'jpeg'], |
|
help="Optional: Upload an image related to the article for additional context" |
|
) |
|
|
|
|
|
if st.button("π Detect Fake News", key="analyze_btn"): |
|
if not article_text: |
|
st.error("Please provide an article to analyze.") |
|
return |
|
|
|
|
|
detector = FakeNewsDetector() |
|
|
|
|
|
with st.spinner('Analyzing article...'): |
|
analysis = detector.analyze_article(article_text) |
|
|
|
|
|
if analysis: |
|
st.subheader("π¬ Detailed Analysis") |
|
|
|
|
|
col1, col2, col3 = st.columns(3) |
|
|
|
with col1: |
|
st.metric( |
|
"Fake News Probability", |
|
f"{analysis.get('fake_news_probability', 50):.2f}%" |
|
) |
|
|
|
with col2: |
|
st.metric( |
|
"Credibility Score", |
|
f"{analysis.get('credibility_score', 5):.2f}/10" |
|
) |
|
|
|
with col3: |
|
st.metric( |
|
"Risk Level", |
|
"High" if analysis.get('fake_news_probability', 50) > 50 else "Low" |
|
) |
|
|
|
|
|
st.subheader("π© Red Flags") |
|
for flag in analysis.get('red_flags', []): |
|
st.warning(flag) |
|
|
|
st.subheader("π΅οΈ Verification Steps") |
|
for step in analysis.get('verification_steps', []): |
|
st.info(step) |
|
|
|
|
|
if uploaded_image: |
|
image = Image.open(uploaded_image) |
|
st.subheader("πΈ Uploaded Image") |
|
st.image(image, caption="Article Supporting Image", use_column_width=True) |
|
|
|
|
|
st.markdown("---") |
|
st.markdown(""" |
|
### π€ How to Interpret Results |
|
- **Low Probability**: Article seems credible |
|
- **High Probability**: Exercise caution, verify sources |
|
- **Always cross-reference with multiple sources** |
|
""") |
|
|
|
if __name__ == "__main__": |
|
main() |