diff --git a/fake_news_checker.db b/fake_news_checker.db index e06e263..acf0f55 100644 Binary files a/fake_news_checker.db and b/fake_news_checker.db differ diff --git a/src/controller/mainFrameController.py b/src/controller/mainFrameController.py index 2f778dd..c712f82 100644 --- a/src/controller/mainFrameController.py +++ b/src/controller/mainFrameController.py @@ -1,56 +1,125 @@ +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 urllib.parse import urlparse +from models.provider import Provider +from collections import Counter + class MainFrameController: - - def __init__(self,frame:MainFrame) -> None: + """ + 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() - - def get_textdata(self) -> TextData: + self._fetch_db_data() + self.update_provider_list() + + 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 text_data.text_from_url(): + if not text_data.text_from_url(): text_data.text = self.frame.input_textbox.get("0.0", "end") - return text_data - - def press_check_button(self): - text_data = self.get_textdata() - print(f"text:{text_data.text}") - text_data = self.prediction(text_data) - - self.addDB(textData=text_data) - self.frame.output_textbox.configure(state="normal") - self.frame.output_textbox.delete("0.0", "end") - self.frame.output_textbox.insert("0.0",f"{text_data.get_output()}") - self.frame.output_textbox.configure(state="disabled") - - def prediction(self, text_data:TextData) -> TextData: + + def press_check_button(self) -> None: + """ + Handle the 'Check' button press event. + Processes the input, makes a prediction, updates the database, and displays the result. + """ + text_data = self.get_text_data() + text_data = self._predict(text_data) + self._add_to_db(text_data) + self._update_output(text_data.get_output()) + self.update_provider_list() + + 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.result = result["result"] text_data.is_fake_news = result["is_fake"] print(f"Prediction: {text_data.result}") print(f"Confidence: {text_data.confidence}") return text_data - - def addDB(self, textData: TextData): - if self.is_valid_url(textData.url): - parsed_url = urlparse(textData.url) - anbieter = parsed_url.netloc.split('.')[-2] + '.' + parsed_url.netloc.split('.')[-1] - print("Hauptdomain:", anbieter) - self.db.insert_data(url= textData.url, anbieter= anbieter,is_fake_news=textData.is_fake_news) - else: - self.db.insert_data(url= textData.url, anbieter= "None",is_fake_news=textData.is_fake_news) - - def is_valid_url(self, url): - try: - result = urlparse(url) - return all([result.scheme, result.netloc]) - except ValueError: - return False - \ No newline at end of file + + 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: + print(f"ID: {row[0]}, URL: {row[1]}, Anbieter: {row[2]}, Fake News: {'Ja' if row[3] else 'Nein'}") + 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): + provider_names = [text_data.provider for text_data in text_data_list if text_data.provider] + provider_counts = Counter(provider_names) + sorted_providers = [ + Provider(name, count) + for name, count in sorted(provider_counts.items(), key=lambda x: x[1], 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.count)) + 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") + + \ No newline at end of file diff --git a/src/models/data.py b/src/models/data.py index 2f15286..3f28398 100644 --- a/src/models/data.py +++ b/src/models/data.py @@ -1,11 +1,15 @@ +from urllib.parse import urlparse +from typing import Optional + from utils.webTextExtractor import WebTextExtractor class TextData: - def __init__(self, url: str = "") -> None: + def __init__(self, url: str = "",text: str = "",result: str = "", is_fake_news: bool = False, provider: str = "") -> None: self.url = url - self.text = "" - self.result = "" - self.is_fake_news = False + self.text = text + self.result = result + self.is_fake_news = is_fake_news + self.provider = provider self.confidence = None self._extractor = None @@ -32,4 +36,34 @@ class TextData: if self.confidence != None: output = f"Prediction: {self.result}" + f" Confidence: {self.confidence:.4f}" print(output) - return output \ No newline at end of file + return output + + def get_provider(self)-> str: + self.extract_provider() + return self.provider + + def extract_provider(self): + """ + Extract the domain (anbieter) from a given URL. + + :param url: The URL to process + :return: The extracted domain or None if the URL is invalid + """ + if not self._is_valid_url(self.url): + self.provider = "None" + parsed_url = urlparse(self.url) + domain_parts = parsed_url.netloc.split('.') + self.provider = f"{domain_parts[-2]}.{domain_parts[-1]}" if len(domain_parts) >= 2 else "None" + + def _is_valid_url(self, url: str) -> bool: + """ + Check if a given URL is valid. + + :param url: The URL to validate + :return: True if the URL is valid, False otherwise + """ + try: + result = urlparse(url) + return all([result.scheme, result.netloc]) + except ValueError: + return False \ No newline at end of file diff --git a/src/models/provider.py b/src/models/provider.py new file mode 100644 index 0000000..92e2e54 --- /dev/null +++ b/src/models/provider.py @@ -0,0 +1,5 @@ +class Provider(): + + def __init__(self, title: str, count: int) -> None: + self.title = title + self.count = count \ No newline at end of file diff --git a/src/views/mainScreen.py b/src/views/mainScreen.py index ef41506..eda2cbd 100644 --- a/src/views/mainScreen.py +++ b/src/views/mainScreen.py @@ -38,6 +38,10 @@ class MainFrame(ctk.CTkFrame): self.header = ctk.CTkLabel(self.scrollview, text="Leaderboard", font=("Arial", 24, "bold")) self.header.pack(pady=10, padx=10, anchor="w") + # Container für Provider-Einträge + self.provider_container = ctk.CTkFrame(self.scrollview) + self.provider_container.pack(fill="both", expand=True) + def set_controller(self, controller): self.controller = controller