Skip to content
Merged

Dev #23

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ jobs:
scriptPath="${{ github.workspace }}/blocknet_aio_monitor.py"

cmd=(pyinstaller --noconfirm --onefile \
--hidden-import='PIL._tkinter_finder' \
--add-data "theme:theme" \
--add-data "img:img" \
--clean \
Expand Down Expand Up @@ -97,13 +98,19 @@ jobs:

- name: Set up Python using Homebrew
run: |
brew install python@3.10
brew install python-tk@3.10
python3.10 -m pip install --upgrade pip
brew update
brew upgrade || true
brew link --overwrite python@3.12
brew install python
brew install python-tk
python3 -m pip install --upgrade pip
# brew install python@3.10
# brew install python-tk@3.10
# python3.10 -m pip install --upgrade pip

- name: Install dependencies / Build executable on macOS
run: |
python3.10 -m venv venv
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pip install pyinstaller
Expand Down
331 changes: 142 additions & 189 deletions blocknet_aio_monitor.py

Large diffs are not rendered by default.

18 changes: 12 additions & 6 deletions gui/binary_frame_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,21 @@


class BinaryFrameManager:
def __init__(self, parent, master_frame, title_frame):
def __init__(self, parent):
self.root_gui = parent.root_gui
self.parent = parent
self.master_frame = master_frame
self.title_frame = title_frame
self.xbridge_bot_manager = XBridgeBotManager()
self.master_frame = ctk.CTkFrame(master=self.root_gui)
self.title_frame = ctk.CTkFrame(self.master_frame)

self.xbridge_bot_manager = XBridgeBotManager()
self.header_label = ctk.CTkLabel(self.title_frame,
text="Binaries Control panel:",
anchor=HEADER_FRAMES_STICKY,
width=BINS_FRAME_WIDTH)
self.title_frame.columnconfigure(1, weight=1)

self.found_label = ctk.CTkLabel(self.title_frame,
text="Found:",
anchor='s')

self.button_switch_theme = ctk.CTkButton(self.title_frame,
image=self.root_gui.theme_img,
command=self.root_gui.switch_theme_command,
Expand Down Expand Up @@ -167,6 +165,14 @@ def toggle_bots_execution_command(self):
utilities.utils.disable_button(self.install_delete_bots_button, self.root_gui.install_greyed_img)
utilities.utils.disable_button(self.bots_toggle_execution_button, self.root_gui.start_greyed_img)
self.xbridge_bot_manager.toggle_execution(branch)
if not self.xbridge_bot_manager.repo_management.venv:
self.run_after_setup()

def run_after_setup(self):
if self.xbridge_bot_manager.repo_management.venv:
self.xbridge_bot_manager.toggle_execution()
else:
self.root_gui.after(1000, self.run_after_setup)

def grid_widgets(self, x, y):
# bin
Expand Down
150 changes: 71 additions & 79 deletions gui/binary_manager.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,71 @@
import logging
import os
import shutil
import time
from threading import Thread

from watchdog.events import FileSystemEvent, FileSystemEventHandler
from watchdog.observers import Observer

import widgets_strings
from gui.binary_frame_manager import BinaryFrameManager
from utilities import utils, global_variables


class BinaryFileHandler(FileSystemEventHandler):
"""
Handles file modification events with rate limiting for binary updates.
"""

def __init__(self, binary_manager: 'BinaryManager'):
"""
Initializes the handler.
:param binary_manager: The manager responsible for binary updates.
"""
super().__init__()
self.binary_manager: 'BinaryManager' = binary_manager
self.max_delay: float = 5 # seconds
self.last_run: float = 0
self.scheduled: bool = False

def on_modified(self, event: 'FileSystemEvent') -> None:
"""
Called when a file is modified. Executes binary check/update with rate limiting.
"""
# logging.info("File modified detected: %s", event.src_path)

if self.scheduled:
# logging.debug("Update already scheduled, skipping immediate execution.")
return

time_since_last = time.time() - self.last_run
# logging.debug("Time since last run: %.2f seconds", time_since_last)

if time_since_last >= self.max_delay:
# Execute immediately
# logging.info("Executing check_and_update_aio_folder immediately.")
self.binary_manager.check_and_update_aio_folder()
self.last_run = time.time()
else:
# Schedule for later
delay_ms = int((self.max_delay - time_since_last) * 1000)
# logging.info("Scheduling check_and_update_aio_folder in %d ms.", delay_ms)
self.scheduled = True
self.binary_manager.root_gui.after(delay_ms, self._execute_scheduled)

def _execute_scheduled(self) -> None:
"""
Executes the scheduled update and resets the schedule flag.
"""
# logging.info("Executing scheduled check_and_update_aio_folder.")
self.binary_manager.check_and_update_aio_folder()
self.last_run = time.time()
self.scheduled = False


class BinaryManager:
def __init__(self, root_gui, master_frame, title_frame):
def __init__(self, root_gui):
self.root_gui = root_gui
self.title_frame = title_frame
self.master_frame = master_frame
self.frame_manager = None

self.disable_start_blocknet_button = False
Expand All @@ -23,12 +76,17 @@ def __init__(self, root_gui, master_frame, title_frame):
self.download_blockdx_thread = None
self.download_xlite_thread = None

self.observer = Observer()
self.handler = BinaryFileHandler(self)
self.observer.schedule(self.handler, global_variables.aio_folder, recursive=False)
self.observer.start()

self.tooltip_manager = self.root_gui.tooltip_manager

async def setup(self):
self.frame_manager = BinaryFrameManager(self, self.master_frame, self.title_frame)
self.frame_manager = BinaryFrameManager(self)

self.root_gui.after(0, self.bins_check_aio_folder)
self.root_gui.after(0, self.check_and_update_aio_folder)
self.root_gui.after(0, self.update_blocknet_buttons)
self.root_gui.after(0, self.update_blockdx_buttons)
self.root_gui.after(0, self.update_xlite_buttons)
Expand Down Expand Up @@ -71,11 +129,11 @@ def start_or_close_blockdx(self):
)

def start_or_close_xlite(self):
if not self.root_gui.xlite_manager.process_running:
if self.root_gui.stored_password:
env_vars = [{"CC_WALLET_PASS": self.root_gui.stored_password}, {"CC_WALLET_AUTOLOGIN": 'true'}]
else:
env_vars = []
if not self.root_gui.xlite_manager.process_running and self.root_gui.stored_password:
env_vars = [{"CC_WALLET_PASS": self.root_gui.stored_password}, {"CC_WALLET_AUTOLOGIN": 'true'}]
else:
env_vars = []

self._start_or_close_binary(
process_running=self.root_gui.xlite_manager.process_running,
stop_func=self.root_gui.xlite_manager.utility.close_xlite,
Expand Down Expand Up @@ -167,8 +225,8 @@ def delete_xlite_command(self):
logging.info(f"deleting {item_path}")
shutil.rmtree(item_path)

def bins_check_aio_folder(self):
# logging.info("bins_check_aio_folder")
def check_and_update_aio_folder(self):
# logging.info("check_and_update_aio_folder")

# Get system information and versions
is_darwin = global_variables.system == "Darwin"
Expand Down Expand Up @@ -217,16 +275,13 @@ def bins_check_aio_folder(self):
# logging.info(app_info)
app_info["boolvar"].set(app_info["found"])

# Schedule next check
self.root_gui.after(5000, self.bins_check_aio_folder)

def _prune_version(self, version):
"""Remove 'v' prefix from version string."""
return version[0].replace('v', '')

def _log_incorrect_target(self, target):
"""Log incorrect version found."""
# logging.info(f"incorrect version: {target}")
logging.info(f"incorrect version: {target}")
# shutil.rmtree(target) if os.path.isdir(target) else os.remove(target)
return

Expand All @@ -245,69 +300,6 @@ def _check_app_version(self, app_info, item, full_path):
else:
self._log_incorrect_target(full_path)

def bins_check_aio_folder_original(self):
blocknet_pruned_version = self.root_gui.blocknet_manager.version[0].replace('v', '')
blockdx_pruned_version = self.root_gui.blockdx_manager.version[0].replace('v', '')
xlite_pruned_version = self.root_gui.xlite_manager.version[0].replace('v', '')

blocknet_present = False
blockdx_present = False
xlite_present = False

for item in os.listdir(global_variables.aio_folder):
if global_variables.system == "Darwin":
blockdx_filename = os.path.basename(global_variables.blockdx_release_url)
xlite_filename = os.path.basename(global_variables.xlite_release_url)
item_path = os.path.join(global_variables.aio_folder, item)
if os.path.isdir(item_path):
if 'blocknet-' in item:
if blocknet_pruned_version in item:
blocknet_present = True
else:
logging.info(f"deleting outdated version: {item_path}")
shutil.rmtree(item_path)
elif os.path.isfile(item_path):
if 'BLOCK-DX-' in item:
if blockdx_filename in item:
blockdx_present = True
else:
logging.info(f"deleting outdated version: {item_path}")
os.remove(item_path)
elif 'XLite-' in item:
if xlite_filename in item:
xlite_present = True
else:
logging.info(f"deleting outdated version: {item_path}")
os.remove(item_path)
else:
item_path = os.path.join(global_variables.aio_folder, item)
if os.path.isdir(item_path):
# if a wrong version is found, delete it.
if 'blocknet-' in item:
if blocknet_pruned_version in item:
blocknet_present = True
else:
logging.info(f"deleting outdated version: {item_path}")
shutil.rmtree(item_path)
elif 'BLOCK-DX-' in item:
if blockdx_pruned_version in item:
blockdx_present = True
else:
logging.info(f"deleting outdated version: {item_path}")
shutil.rmtree(item_path)
elif 'XLite-' in item:
if xlite_pruned_version in item:
xlite_present = True
else:
logging.info(f"deleting outdated version: {item_path}")
shutil.rmtree(item_path)

self.root_gui.binary_manager.frame_manager.blocknet_installed_boolvar.set(blocknet_present)
self.root_gui.binary_manager.frame_manager.blockdx_installed_boolvar.set(blockdx_present)
self.root_gui.binary_manager.frame_manager.xlite_installed_boolvar.set(xlite_present)

self.root_gui.after(2000, self.bins_check_aio_folder_original)

def update_blocknet_buttons(self):
# BLOCKNET
self.update_blocknet_start_close_button()
Expand Down
10 changes: 4 additions & 6 deletions gui/blockdx_frame_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,18 @@


class BlockDxFrameManager:
def __init__(self, parent, master_frame, title_frame):
def __init__(self, parent):
self.root_gui = parent.root_gui
self.parent = parent
self.master_frame = master_frame
self.title_frame = title_frame

# Label for Block-dx frame
self.master_frame = ctk.CTkFrame(master=self.root_gui)
self.title_frame = ctk.CTkFrame(self.master_frame)

self.label = ctk.CTkLabel(self.title_frame,
text=widgets_strings.blockdx_frame_title_string,
anchor=HEADER_FRAMES_STICKY,
width=BLOCKDX_FRAME_WIDTH)

# Checkboxes
# width_mod = 35
self.process_status_checkbox_state = ctk.BooleanVar()
self.process_status_checkbox_string_var = ctk.StringVar(value='')
self.process_status_checkbox = ctkCheckBoxMod.CTkCheckBox(self.master_frame,
Expand Down
6 changes: 2 additions & 4 deletions gui/blockdx_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,16 @@


class BlockDXManager:
def __init__(self, root_gui, master_frame, title_frame):
def __init__(self, root_gui):
self.frame_manager = None
self.root_gui = root_gui
self.title_frame = title_frame
self.master_frame = master_frame
self.utility = BlockdxUtility()
self.version = [global_variables.blockdx_release_url.split('/')[7]]
self.process_running = False
self.is_config_sync = None

async def setup(self):
self.frame_manager = BlockDxFrameManager(self, self.master_frame, self.title_frame)
self.frame_manager = BlockDxFrameManager(self)
self.root_gui.after(0, self.update_status_blockdx)

def blockdx_check_config(self):
Expand Down
8 changes: 3 additions & 5 deletions gui/blocknet_frame_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,16 @@


class BlocknetCoreFrameManager:
def __init__(self, parent, master_frame, title_frame):
def __init__(self, parent):
self.root_gui = parent.root_gui
self.parent = parent
self.master_frame = master_frame
self.title_frame = title_frame
self.master_frame = ctk.CTkFrame(master=self.root_gui)
self.title_frame = ctk.CTkFrame(self.master_frame)

# Create all Blocknet Core widgets here
self.label = ctk.CTkLabel(self.title_frame,
text=widgets_strings.blocknet_frame_title_string,
anchor=HEADER_FRAMES_STICKY) # , width=FRAME_WIDTH)

# Label for Data Path
self.data_path_label = ctk.CTkLabel(self.title_frame, text="Data Path: ")

self.data_path_entry_string_var = ctk.StringVar(value=self.parent.utility.data_folder)
Expand Down
6 changes: 2 additions & 4 deletions gui/blocknet_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@


class BlocknetManager:
def __init__(self, root_gui, master_frame, title_frame):
def __init__(self, root_gui):
self.frame_manager = None
self.root_gui = root_gui
self.title_frame = title_frame
self.master_frame = master_frame
self.version = [global_variables.blocknet_release_url.split('/')[7]]
self.blocknet_process_running = False

Expand All @@ -17,7 +15,7 @@ def __init__(self, root_gui, master_frame, title_frame):
self.utility = BlocknetUtility(custom_path=self.root_gui.custom_path)

async def setup(self):
self.frame_manager = BlocknetCoreFrameManager(self, self.master_frame, self.title_frame)
self.frame_manager = BlocknetCoreFrameManager(self)

self.root_gui.after(0, self.update_status_blocknet_core)

Expand Down
Loading
Loading