huesoporro/src/markovbot_gui/config_window.py

161 lines
5.5 KiB
Python

from pathlib import Path
from kivy.clock import Clock
from kivy.metrics import dp
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.popup import Popup
from kivy.uix.textinput import TextInput
from src.markovbot_gui.libs.settings import Settings
from src.markovbot_gui.libs.timer import logger
class ConfigWindow(BoxLayout):
def __init__(self, config_path: Path, **kwargs):
super().__init__(**kwargs)
self.config_path = config_path
self.orientation = "vertical"
self.spacing = dp(10)
self.padding = dp(20)
# Load existing configuration
default_config = {
"Host": "irc.chat.twitch.tv",
"Port": 6667,
"Channel": "#<channel>",
"Nickname": "<name>",
"Authentication": "oauth:<auth>",
"DeniedUsers": ["StreamElements", "Nightbot", "Moobot", "Marbiebot"],
"Cooldown": 20,
"KeyLength": 2,
"MaxSentenceWordAmount": 25,
"MinSentenceWordAmount": -1,
"HelpMessageTimer": 60 * 60 * 5, # 18000 seconds, 5 hours
"AutomaticGenerationTimer": -1,
"WhisperCooldown": True,
"EnableGenerateCommand": True,
"SentenceSeparator": " - ",
"AllowGenerateParams": True,
}
if config_path.exists():
self.s = Settings.read(config_path)
else:
self.s = Settings(**default_config) # type: ignore[arg-type]
self.s.write(config_path)
# Create widgets
# Channel input
channel_layout = BoxLayout(
orientation="horizontal",
size_hint_y=None,
height=dp(40),
)
channel_label = Label(text="Channel:", size_hint_x=0.3)
self.channel_input = TextInput(
multiline=False,
size_hint_x=0.7,
text=self.s.channel,
)
channel_layout.add_widget(channel_label)
channel_layout.add_widget(self.channel_input)
# Nickname input
nickname_layout = BoxLayout(
orientation="horizontal",
size_hint_y=None,
height=dp(40),
)
nickname_label = Label(text="Nickname:", size_hint_x=0.3)
self.nickname_input = TextInput(
multiline=False,
size_hint_x=0.7,
text=self.s.nickname,
)
nickname_layout.add_widget(nickname_label)
nickname_layout.add_widget(self.nickname_input)
# Authentication input
auth_layout = BoxLayout(
orientation="horizontal",
size_hint_y=None,
height=dp(40),
)
auth_label = Label(text="Auth:", size_hint_x=0.3)
self.auth_input = TextInput(
multiline=False,
size_hint_x=0.7,
password=True,
text=self.s.authentication,
)
auth_layout.add_widget(auth_label)
auth_layout.add_widget(self.auth_input)
automatic_generation_label = Label(text="Automatic generation (seconds): ")
self.automatic_generation_input = TextInput(
multiline=False,
size_hint_x=0.7,
text=str(self.s.automatic_generation_timer),
)
automatic_generation_layout = BoxLayout(
orientation="horizontal",
size_hint_y=None,
height=dp(40),
)
automatic_generation_layout.add_widget(automatic_generation_label)
automatic_generation_layout.add_widget(self.automatic_generation_input)
# Save button
save_button = Button(
text="Save",
size_hint=(None, None),
size=(dp(100), dp(40)),
pos_hint={"center_x": 0.5},
)
save_button.bind(on_release=self.save_config)
# Add all widgets to the layout
self.add_widget(channel_layout)
self.add_widget(nickname_layout)
self.add_widget(auth_layout)
self.add_widget(automatic_generation_layout)
self.add_widget(save_button)
def save_config(self, instance):
try:
self.s.channel = self.channel_input.text.strip()
self.s.nickname = self.nickname_input.text.strip()
self.s.authentication = self.auth_input.text.strip()
self.s.automatic_generation_timer = int(
self.automatic_generation_input.text
)
if 0 < self.s.automatic_generation_timer < 29: # noqa: PLR2004
raise ValueError(
"Value for 'Automatic generation' must be at least 30 seconds, " # noqa: EM101
"or a negative number for no automatic generations."
)
self.s.write(self.config_path)
# Show success message
success_popup = Popup(
title="Success",
content=Label(text="Configuration saved successfully"),
size_hint=(None, None),
size=(dp(250), dp(100)),
)
success_popup.open()
Clock.schedule_once(success_popup.dismiss, 1)
except Exception as e: # noqa: BLE001
self.show_error_message(f"Failed to save configuration:\n{e!s}")
error_popup = Popup(
title="Error",
content=Label(text=f"Failed to save configuration:\n{e!s}"),
size_hint=(None, None),
size=(dp(400), dp(150)),
)
error_popup.open()
logger.exception("Failed to save configuration")