from collections import deque import customtkinter as ctk from views.mainScreen import MainFrame from models.data import TextData from Ai.interence import VeraMindInference from utils.database.database import FakeNewsChecker from models.provider import Provider from collections import Counter from Ai.llm import ArticleRater class MainFrameController: """ Controller class for the main frame of the application. Handles user interactions, data processing, and database operations. """ def __init__(self, frame: MainFrame) -> None: """ Initialize the controller with the main frame and required components. :param frame: The main frame of the application """ self.frame = frame self.model_inference = VeraMindInference('VeraMind-Mini') self.db = FakeNewsChecker() self.update_provider_list() self.rater = ArticleRater() def get_text_data(self) -> TextData: """ Retrieve text data from the UI input fields. :return: TextData object containing URL and text content """ text_data = TextData() text_data.url = self.frame.entry_url.get() if not text_data.text_from_url(): text_data.text = self.frame.input_textbox.get("0.0", "end") text_data.provider = "Unknown" return text_data def press_check_button(self): self.frame.result_label.configure(text="", fg_color="#333333") self.frame.confidence_label.configure(text="", fg_color="#333333") text_data = self.get_text_data() if not text_data.text.strip(): return text_data = self._predict(text_data) self._add_to_db(text_data) self.update_provider_list() self.frame.output_textbox.configure(state="normal") self.frame.output_textbox.delete("0.0", "end") confidence = text_data.confidence * 100 self.frame.confidence_label.configure(text=f"{confidence:.2f}%") result_color = "green" if text_data.result == "REAL" else "red" self.frame.result_label.configure(text=text_data.result, fg_color=result_color) confidence_color = "green" if confidence > 80 else ("orange" if confidence > 50 else "red") self.frame.confidence_label.configure(fg_color=confidence_color) if self.rater.token: response_stream = self.rater.get_response(text_data.text, text_data.result, confidence) for chunk in response_stream: self.frame.output_textbox.insert("end", chunk.content) self.frame.output_textbox.see("end") self.frame.update_idletasks() def _predict(self, text_data: TextData) -> TextData: """ Make a prediction using the VeraMind model. :param text_data: TextData object containing the text to analyze :return: Updated TextData object with prediction results """ result = self.model_inference.predict(text_data.text) text_data.confidence = result["confidence"] text_data.result = result["result"] text_data.is_fake_news = result["is_fake"] return text_data def _add_to_db(self, text_data: TextData) -> None: """ Add the analyzed data to the database. :param text_data: TextData object containing the analyzed information """ self.db.insert_data(url=text_data.url, anbieter=text_data.get_provider(), is_fake_news= text_data.is_fake_news) def _fetch_db_data(self): self.text_data_list = [] data = self.db.fetch_data() if data: for row in data: text_data = TextData(url=row[1], provider=row[2], is_fake_news= row[3]) self.text_data_list.append(text_data) def sort_provider(self, text_data_list): # Gruppiere TextData-Objekte nach Provider provider_groups = {} for text_data in text_data_list: if text_data.provider: if text_data.provider not in provider_groups: provider_groups[text_data.provider] = [] provider_groups[text_data.provider].append(text_data) # Zähle die Häufigkeit jedes Providers provider_counts = Counter(text_data.provider for text_data in text_data_list if text_data.provider) # Erstelle die Provider-Liste providers = [ Provider(name, count, provider_groups.get(name, [])) for name, count in provider_counts.items() ] # Sortiere die Provider-Liste nach dem Fake-Prozentsatz (absteigend) sorted_providers = sorted(providers, key=lambda x: x.get_fake_percentage(), reverse=True) return sorted_providers def update_provider_list(self): self._fetch_db_data() # Lösche vorhandene Einträge in der scrollbaren Ansicht for widget in self.frame.provider_container.winfo_children(): widget.destroy() # Sortiere und zähle die Provider sorted_providers = self.sort_provider(self.text_data_list) # Füge die sortierten Provider zur scrollbaren Ansicht hinzu for i, provider in enumerate(sorted_providers): provider_frame = ctk.CTkFrame(self.frame.provider_container) provider_frame.pack(fill="x", padx=5, pady=2) name_label = ctk.CTkLabel(provider_frame, text=provider.title) name_label.pack(side="left", padx=5) count_label = ctk.CTkLabel(provider_frame, text=str(provider.get_fake_percentage())+"%") count_label.pack(side="right", padx=5) def _update_output(self, output: str) -> None: """ Update the output text box with the result. :param output: String containing the output to display """ self.frame.output_textbox.configure(state="normal") self.frame.output_textbox.delete("0.0", "end") self.frame.output_textbox.insert("0.0", output) self.frame.output_textbox.configure(state="disabled")