analisisNews / app /analyzers /digest.py
ahmadsayadi's picture
feat: add keywords extraction, NER, project digest endpoints
f39a9fa
Raw
History Blame Contribute Delete
2.45 kB
"""
Project digest — ringkasan otomatis dari kumpulan artikel.
Menghasilkan ringkasan naratif dari berita-berita dalam project.
"""
from typing import List, Dict
import re
from collections import Counter
def generate_digest(items: List, project_name: str = "") -> Dict:
"""
Generate ringkasan dari kumpulan artikel.
Returns: { summary, top_topics, sentiment_overview, key_entities, article_count }
"""
if not items:
return {
"summary": "Belum ada artikel untuk dirangkum.",
"top_topics": [],
"sentiment_overview": "",
"key_entities": [],
"article_count": 0,
}
# Collect all text
all_words = []
all_titles = []
for item in items:
all_titles.append(item.text.split(". ")[0] if ". " in item.text else item.text[:100])
words = re.findall(r'\b[a-zA-Z]{4,}\b', item.text.lower())
all_words.extend(words)
# Stopwords filter
stopwords = {
"yang", "dari", "untuk", "pada", "dengan", "dalam", "akan",
"juga", "tidak", "telah", "sudah", "masih", "hanya", "saja",
"adalah", "tersebut", "mereka", "oleh", "sebagai", "karena",
"republika", "okezone", "detik", "kompas", "antara", "tempo",
}
filtered = [w for w in all_words if w not in stopwords]
# Top keywords/topics
word_freq = Counter(filtered)
top_topics = [{"topic": word, "count": count} for word, count in word_freq.most_common(10)]
# Simple extractive summary: pick most representative titles
# Score titles by how many top keywords they contain
top_words_set = set(w for w, _ in word_freq.most_common(20))
scored_titles = []
for title in all_titles:
title_words = set(re.findall(r'\b[a-zA-Z]{4,}\b', title.lower()))
overlap = len(title_words & top_words_set)
scored_titles.append((overlap, title))
scored_titles.sort(key=lambda x: x[0], reverse=True)
summary_titles = [t for _, t in scored_titles[:5]]
summary = f"Dari {len(items)} artikel"
if project_name:
summary += f" dalam project \"{project_name}\""
summary += f", topik utama meliputi: {', '.join(t['topic'] for t in top_topics[:5])}. "
summary += "Berita terpenting: " + "; ".join(summary_titles[:3]) + "."
return {
"summary": summary,
"top_topics": top_topics,
"key_titles": summary_titles[:5],
"article_count": len(items),
}