""" Fake news score (heuristik). Skor 0-100 indikasi potensi hoax/misinformasi berdasarkan pola teks. """ from typing import List, Dict import re # Indikator clickbait/hoax HOAX_INDICATORS = [ "terungkap", "ternyata", "rahasia", "viral", "heboh", "bikin", "terbongkar", "fakta mencengangkan", "anda harus tahu", "jangan sampai", "ini dia", "wow", "gempar", ] CREDIBILITY_MARKERS = [ "menurut", "berdasarkan", "data", "riset", "penelitian", "sumber", "narasumber", "konfirmasi", "verifikasi", "resmi", ] def calculate_fake_score(text: str, title: str = "") -> Dict: text_lower = (title + " " + text).lower() score = 0 reasons = [] # 1. Kata-kata pemicu hoax di judul title_lower = title.lower() hoax_hits = sum(1 for w in HOAX_INDICATORS if w in title_lower) if hoax_hits > 0: score += min(30, hoax_hits * 15) reasons.append(f"{hoax_hits} kata pemicu hoax") # 2. Tanda seru/tanya berlebihan excl = title.count("!") + title.count("?") if excl > 1: score += min(15, excl * 7) reasons.append(f"{excl} tanda seru/tanya") # 3. ALL CAPS caps = len(re.findall(r'\b[A-Z]{3,}\b', title)) if caps > 1: score += min(15, caps * 7) reasons.append(f"{caps} kata KAPITAL") # 4. Tidak ada sumber/narasumber cred_hits = sum(1 for w in CREDIBILITY_MARKERS if w in text_lower) if cred_hits == 0: score += 20 reasons.append("tidak ada sumber terverifikasi") elif cred_hits >= 3: score -= 10 reasons.append(f"{cred_hits} marker kredibilitas") # 5. Teks sangat pendek (kurang substansi) word_count = len(text.split()) if word_count < 50: score += 15 reasons.append("konten sangat pendek") # 6. Banyak klaim tanpa bukti (kalimat deklaratif tanpa attributor) sentences = re.split(r'[.!?]', text) declarative = sum(1 for s in sentences if len(s.strip()) > 20 and not any(m in s.lower() for m in CREDIBILITY_MARKERS)) ratio = declarative / max(len(sentences), 1) if ratio > 0.8: score += 10 reasons.append("mayoritas klaim tanpa atribusi") score = max(0, min(100, score)) level = "tinggi" if score >= 60 else "sedang" if score >= 30 else "rendah" return {"score": score, "level": level, "reasons": reasons} def analyze_batch(items: List) -> List[Dict]: results = [] for item in items: # Pisah title dari text (asumsi: kalimat pertama = title) parts = item.text.split(". ", 1) title = parts[0] if len(parts) > 1 else "" content = parts[1] if len(parts) > 1 else item.text result = calculate_fake_score(content, title) results.append({"id": item.id, **result}) return results