""" Event Builder Service - Combines RSS fetching, NLP processing, and geocoding to build events from news articles. """ from typing import List, Dict, Optional from sqlalchemy.orm import Session from ..models import Article, LocationBase, City, Country, Continent, Priority from ..schemas import Event, EventLocation from .rss_fetcher import RssFetcher from .nlp_processor import extract_locations from .geocoder import geocode_place from ..utils.logger import setup_logger logger = setup_logger(__name__) def build_events_from_articles( articles: List[Article], db: Session ) -> List[Event]: """ Processes articles to extract locations and build events. Args: articles: List of Article objects to process db: Database session Returns: List of Event objects ready for display on the map """ events = [] for article in articles: try: # Extract locations from article text text = f"{article.title} {article.summary or ''}" places = extract_locations(text, lang="en") # Default to English if not places: logger.debug(f"No locations found in article: {article.title}") continue # Geocode the first location found first_place = places[0] coords = geocode_place(first_place) if not coords: logger.debug(f"Could not geocode place: {first_place}") continue # Determine priority based on keywords priority = determine_priority(article.title, article.summary or "") # Create event event = Event( id=article.id, title=article.title, link=article.link, summary=article.summary, published_date=article.published_date, source_name=article.source_name, priority=priority.value if isinstance(priority, Priority) else priority, location=EventLocation( latitude=coords["lat"], longitude=coords["lon"], entity_name=first_place ) ) events.append(event) except Exception as e: logger.error(f"Error building event from article {article.id}: {e}") continue return events def determine_priority(title: str, summary: str) -> Priority: """ Determines the priority level of a news article based on keywords. Critical keywords: earthquake, deprem, katliam, massacre, terror, attack High keywords: crisis, kriz, conflict, çatışma Medium: default Low: entertainment, eğlence, sports, spor """ text = (title + " " + summary).lower() critical_keywords = [ "earthquake", "deprem", "katliam", "massacre", "terror", "attack", "bomb", "bomba", "shooting", "ölüm", "death", "casualties" ] high_keywords = [ "crisis", "kriz", "conflict", "çatışma", "war", "savaş", "emergency", "acil", "disaster", "felaket" ] low_keywords = [ "entertainment", "eğlence", "sports", "spor", "game", "oyun", "music", "müzik", "movie", "film" ] if any(keyword in text for keyword in critical_keywords): return Priority.CRITICAL elif any(keyword in text for keyword in high_keywords): return Priority.HIGH elif any(keyword in text for keyword in low_keywords): return Priority.LOW else: return Priority.MEDIUM