""" 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), }