160 lines
6.0 KiB
Python
160 lines
6.0 KiB
Python
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")
|
|
|
|
|