File size: 2,765 Bytes
599f4e5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
"""
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