diff --git a/build.bat b/build.bat index aa69ad5..7a51856 100644 --- a/build.bat +++ b/build.bat @@ -1,6 +1,5 @@ @echo off rd build dist /s /q -call activate ./venv python ./setup.py sdist python ./setup.py bdist_wheel PAUSE diff --git a/fishy/__init__.py b/fishy/__init__.py index 00b55e3..f877530 100644 --- a/fishy/__init__.py +++ b/fishy/__init__.py @@ -1,2 +1,2 @@ from fishy.__main__ import main -__version__ = "0.3.2" +__version__ = "0.3.3" diff --git a/fishy/__main__.py b/fishy/__main__.py index 32a4d38..afdc468 100644 --- a/fishy/__main__.py +++ b/fishy/__main__.py @@ -49,18 +49,18 @@ def main(): window_to_hide = win32gui.GetForegroundWindow() c = Config() - events_buffer = [] if not gui.check_eula(c): return - gui_window = GUI(c, lambda a, b=None: events_buffer.append((a, b))) + bot = Engine(c, lambda: gui_window) + gui_window = GUI(c, lambda: bot) + gui_window.start() logging.info(f"Fishybot v{fishy.__version__}") initialize(c, window_to_hide) - bot = Engine(gui_window, events_buffer, c) bot.start_event_handler() diff --git a/fishy/gui/__init__.py b/fishy/gui/__init__.py index ac61885..6cd565a 100644 --- a/fishy/gui/__init__.py +++ b/fishy/gui/__init__.py @@ -1,3 +1,2 @@ from .gui import GUI from .terms_gui import check_eula -from .comms import GUIFunction, GUIEvent diff --git a/fishy/gui/comms.py b/fishy/gui/comms.py deleted file mode 100644 index 76c3eb8..0000000 --- a/fishy/gui/comms.py +++ /dev/null @@ -1,46 +0,0 @@ -import threading -from enum import Enum -from tkinter import * -from tkinter import messagebox, filedialog - -from .log_config import _write_to_console -import typing - -if typing.TYPE_CHECKING: - from . import GUI - - -class GUIEvent(Enum): - START_BUTTON = 0 # args: ip: str, action_key: str, fullscreen: bool, collect_r: bool - CHECK_PIXELVAL = 1 - QUIT = 2 - - -class GUIFunction(Enum): - LOG = 0 # args: str - STARTED = 1 # args: bool - ASK_DIRECTORY = 2 # callback: callable - SHOW_ERROR = 3 - SET_NOTIFY = 4 - - -def _clear_function_queue(gui: 'GUI'): - while len(gui._function_queue) > 0: - func = gui._function_queue.pop(0) - - if func[0] == GUIFunction.LOG: - _write_to_console(gui, func[1][0]) - elif func[0] == GUIFunction.STARTED: - gui._bot_running = func[1][0] - gui._start_button["text"] = "STOP" if gui._bot_running else "START" - elif func[0] == GUIFunction.ASK_DIRECTORY: - messagebox.showinfo("Directory?", func[1][1]) - path = filedialog.askdirectory() - if path != '': - threading.Thread(target=func[1][0], args=(path,)).start() - elif func[0] == GUIFunction.SHOW_ERROR: - messagebox.showerror("ERROR", func[1][0]) - elif func[0] == GUIFunction.SET_NOTIFY: - gui._notify.set(func[1][0]) - if func[1][1]: - gui._notify_check['state'] = NORMAL diff --git a/fishy/gui/funcs.py b/fishy/gui/funcs.py new file mode 100644 index 0000000..6f5c79c --- /dev/null +++ b/fishy/gui/funcs.py @@ -0,0 +1,23 @@ +from tkinter import messagebox, NORMAL + + +# noinspection PyProtectedMember +class GUIFuncs: + def __init__(self, gui): + self.gui = gui + + def set_notify(self, flag): + def func(): + self.gui._notify_check['state'] = NORMAL + self.gui._notify.set(flag) + self.gui.call_in_thread(func) + + def show_error(self, error): + self.gui.call_in_thread(lambda: messagebox.showerror("ERROR", error)) + + def bot_started(self, started): + def func(): + self.gui._bot_running = started + self.gui._start_button["text"] = "STOP" if self.gui._bot_running else "START" + + self.gui.call_in_thread(func) diff --git a/fishy/gui/gui.py b/fishy/gui/gui.py index 2cafc5f..66f2f6a 100644 --- a/fishy/gui/gui.py +++ b/fishy/gui/gui.py @@ -1,25 +1,27 @@ import logging -from typing import Tuple, List, Callable, Optional +from typing import List, Callable import threading +from fishy.gui.funcs import GUIFuncs +from fishy.tech import Engine from . import main_gui -from .comms import GUIEvent, GUIFunction from .log_config import GUIStreamHandler from fishy.helper import Config class GUI: - def __init__(self, config: Config, event_trigger: Callable[[GUIEvent, Optional[Tuple]], None]): + def __init__(self, config: Config, get_engine: Callable[[], Engine]): """ :param config: used to get and set configuration settings - :param event_trigger: used to communicate with other threads """ + self.funcs = GUIFuncs(self) + self.get_engine = get_engine + self._config = config self._start_restart = False self._destroyed = True self._log_strings = [] - self._function_queue: List[Tuple[GUIFunction, Tuple]] = [] - self._event_trigger = event_trigger + self._function_queue: List[Callable] = [] self._bot_running = False # UI items @@ -37,11 +39,20 @@ class GUI: new_console = GUIStreamHandler(self) root_logger.addHandler(new_console) + @property + def engine(self): + return self.get_engine().funcs + def create(self): main_gui._create(self) def start(self): self._thread.start() - def call(self, gui_func, args): - self._function_queue.append((gui_func, args)) + def _clear_function_queue(self): + while len(self._function_queue) > 0: + func = self._function_queue.pop(0) + func() + + def call_in_thread(self, func: Callable): + self._function_queue.append(func) diff --git a/fishy/gui/log_config.py b/fishy/gui/log_config.py index c4e6ce8..585a9b4 100644 --- a/fishy/gui/log_config.py +++ b/fishy/gui/log_config.py @@ -12,9 +12,8 @@ class GUIStreamHandler(StreamHandler): self.gui = gui def emit(self, record): - from .comms import GUIFunction msg = self.format(record) - self.gui.call(GUIFunction.LOG, (msg,)) + self.gui.call_in_thread(lambda: _write_to_console(self.gui, msg)) def _write_to_console(root: 'GUI', msg): diff --git a/fishy/gui/main_gui.py b/fishy/gui/main_gui.py index 334815a..cae33a6 100644 --- a/fishy/gui/main_gui.py +++ b/fishy/gui/main_gui.py @@ -7,7 +7,6 @@ from ttkthemes import ThemedTk from fishy import helper, web -from .comms import GUIEvent, GUIFunction, _clear_function_queue from .notification import _give_notification_link import typing @@ -16,7 +15,7 @@ if typing.TYPE_CHECKING: def _apply_theme(gui: 'GUI'): - dark = gui._config.get("dark", True) + dark = gui._config.get("dark_mode", True) gui._root["theme"] = "equilux" if dark else "breeze" gui._console["background"] = "#707070" if dark else "#ffffff" gui._console["fg"] = "#ffffff" if dark else "#000000" @@ -25,7 +24,6 @@ def _apply_theme(gui: 'GUI'): def _create(gui: 'GUI'): gui._root = ThemedTk(theme="equilux", background=True) gui._root.title("Fishybot for Elder Scrolls Online") - gui._root.geometry('650x550') gui._root.iconbitmap(helper.manifest_file('icon.ico')) @@ -48,7 +46,7 @@ def _create(gui: 'GUI'): debug_menu = Menu(menubar, tearoff=0) debug_menu.add_command(label="Check PixelVal", - command=lambda: gui._event_trigger(GUIEvent.CHECK_PIXELVAL, ())) + command=lambda: gui.engine.check_pixel_val()) debug_var = IntVar() debug_var.set(int(gui._config.get('debug', False))) @@ -93,7 +91,8 @@ def _create(gui: 'GUI'): def update_notify_check(): is_subbed = web.is_subbed(gui._config.get('uid')) - gui.call(GUIFunction.SET_NOTIFY, (int(is_subbed[0]), is_subbed[1])) + if is_subbed[1]: + gui.funcs.set_notify(is_subbed[0]) threading.Thread(target=update_notify_check).start() @@ -121,10 +120,9 @@ def _create(gui: 'GUI'): gui._start_button = Button(gui._root, text="STOP" if gui._bot_running else "START", width=25) def start_button_callback(): - args = (action_key_entry.get(), - borderless.instate(['selected']), - collect_r.instate(['selected'])) - gui._event_trigger(GUIEvent.START_BUTTON, args) + gui.engine.start_button_pressed(action_key_entry.get(), + borderless.instate(['selected']), + collect_r.instate(['selected'])) gui._config.set("action_key", action_key_entry.get(), False) gui._config.set("borderless", borderless.instate(['selected']), False) @@ -147,13 +145,13 @@ def _create(gui: 'GUI'): while True: gui._root.update() - _clear_function_queue(gui) + gui._clear_function_queue() if gui._start_restart: gui._root.destroy() gui._root.quit() gui._start_restart = False gui.create() if gui._destroyed: - gui._event_trigger(GUIEvent.QUIT, ()) + gui.engine.quit() break time.sleep(0.01) diff --git a/fishy/gui/notification.py b/fishy/gui/notification.py index 647408f..c91ab02 100644 --- a/fishy/gui/notification.py +++ b/fishy/gui/notification.py @@ -1,9 +1,8 @@ -import os -import tempfile +import time from tkinter import * from tkinter import messagebox from tkinter.ttk import * -import pyqrcode +from tkhtmlview import HTMLLabel from fishy import web import typing @@ -12,6 +11,7 @@ if typing.TYPE_CHECKING: from . import GUI +# noinspection PyProtectedMember def _give_notification_link(gui: 'GUI'): if web.is_subbed(gui._config.get("uid"))[0]: web.unsub(gui._config.get("uid")) @@ -25,37 +25,49 @@ def _give_notification_link(gui: 'GUI'): top_running[0] = False def check(): - if web.is_subbed(gui._config.get("uid"), False)[0]: - gui._notify.set(1) - web.send_notification(gui._config.get("uid"), "Sending a test notification :D") - messagebox.showinfo("Note!", "Notification configured successfully!") - quit_top() + if web.sub(gui._config.get("uid"), discord_name.get()): + if web.is_subbed(gui._config.get("uid"), False)[0]: + gui._notify.set(1) + messagebox.showinfo("Note!", "Notification configured successfully!") + quit_top() else: messagebox.showerror("Error", "Subscription wasn't successful") - print("got to {}".format(web.get_notification_page(gui._config.get("uid")))) - qrcode = pyqrcode.create(web.get_notification_page(gui._config.get("uid"))) - t = os.path.join(tempfile.gettempdir(), "fishyqr.png") - qrcode.png(t, scale=8) - top_running = [True] top = Toplevel(background=gui._root["background"]) - top.minsize(width=500, height=500) + top.minsize(width=300, height=300) top.title("Notification Setup") - Label(top, text="Step 1.").pack(pady=(5, 5)) - Label(top, text="Scan the QR Code on your Phone and press \"Enable Notification\"").pack(pady=(5, 5)) - canvas = Canvas(top, width=qrcode.get_png_size(8), height=qrcode.get_png_size(8)) - canvas.pack(pady=(5, 5)) - Label(top, text="Step 2.").pack(pady=(5, 5)) - Button(top, text="Check", command=check).pack(pady=(5, 5)) + html_label = HTMLLabel(top, + html=f'
Step 1.
'
+ f'Join Discord server
Step 2.
'
+ f'Enter username (ex. Fishy#1234)'
+ f'
Step 3.
'
+ f'Install Discord App on your phone
Step 4.