Skip to content
Merged

Dev #24

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
38 changes: 32 additions & 6 deletions blocknet_aio_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,31 @@
from utilities import global_variables
from utilities import utils

# Create or get the root logger
logger = logging.getLogger()
logger.setLevel(logging.DEBUG) # Set the logging level to DEBUG

# Create a console handler (prints to stdout)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)

# Create a formatter and set it for the handler
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_handler.setFormatter(formatter)

# Add the handler to the logger (only once to avoid duplicate logs)
if not logger.hasHandlers():
logger.addHandler(console_handler)

asyncio_logger = logging.getLogger('asyncio')
asyncio_logger.setLevel(logging.WARNING)
pil_logger = logging.getLogger('PIL')
pil_logger.setLevel(logging.WARNING)
urllib3_logger = logging.getLogger('urllib3')
urllib3_logger.setLevel(logging.WARNING)
urllib3_logger = logging.getLogger('watchdog')
urllib3_logger.setLevel(logging.WARNING)

from gui.constants import tooltip_bg_color, MAIN_FRAMES_STICKY, TITLE_FRAMES_STICKY

ctk.set_default_color_theme(global_variables.themepath)
Expand Down Expand Up @@ -54,7 +75,7 @@ def __init__(self):
try:
self.stored_password = utils.decrypt_password(self.cfg['xl_pass'], self.cfg['salt'].encode())
except Exception as e:
logging.error(f"Error decrypting XLite password: {e}")
logger.error(f"Error decrypting XLite password: {e}")
self.stored_password = None

self.time_disable_button: int = 3000
Expand Down Expand Up @@ -235,14 +256,14 @@ def grid_frames(self, x: int, y: int, padx_main_frame: int, pady_main_frame: int

def handle_signal(self, signum: int, frame) -> None:
"""Handle signals like SIGINT and SIGTERM."""
print(f"Signal {signum} received.")
logger.info(f"Signal {signum} received.")
self.on_close()

def on_close(self) -> None:
"""Handle application close event."""
logging.info("Closing application...")
logger.info("Closing application...")
utils.terminate_all_threads()
logging.info("Threads terminated.")
logger.info("Threads terminated.")
os._exit(0)

def adjust_theme(self) -> None:
Expand All @@ -267,7 +288,11 @@ def switch_theme_command(self) -> None:
utils.save_cfg_json("theme", new_theme)

def check_processes(self) -> None:
"""
Checks the status of all relevant processes and updates the GUI accordingly.
"""
blocknet_processes, blockdx_processes, xlite_processes, xlite_daemon_processes = utils.processes_check()

# Update Blocknet process status and store the PIDs
self.blocknet_manager.blocknet_process_running = bool(blocknet_processes)
self.blocknet_manager.utility.blocknet_pids = blocknet_processes
Expand All @@ -284,6 +309,7 @@ def check_processes(self) -> None:
self.xlite_manager.daemon_process_running = bool(xlite_daemon_processes)
self.xlite_manager.utility.xlite_daemon_pids = xlite_daemon_processes

# Schedule the next check
self.after(5000, func=self.check_processes)


Expand All @@ -297,9 +323,9 @@ def run_gui() -> None:
# print("GUI execution terminated by user.")
# except Exception as e:
# # Log the error to a file
# logging.basicConfig(filename='gui_errors.log', level=logging.ERROR,
# logger.basicConfig(filename='gui_errors.log', level=logging.ERROR,
# format='%(asctime)s - %(levelname)s - %(message)s')
# logging.error("An error occurred: %s", e)
# logger.error("An error occurred: %s", e)
#
# # Print a user-friendly error message
# print("An unexpected error occurred. Please check the log file 'gui_errors.log' for more information.")
Expand Down
189 changes: 88 additions & 101 deletions gui/binary_manager.py

Large diffs are not rendered by default.

26 changes: 14 additions & 12 deletions gui/blockdx_manager.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import logging
import os

from gui.blockdx_frame_manager import BlockDxFrameManager
from utilities import global_variables
from utilities.blockdx_util import BlockdxUtility
from utilities.bin_handlers.blockdx_handler import BlockDXHandler


class BlockDXManager:
def __init__(self, root_gui):
self.frame_manager = None
self.root_gui = root_gui
self.utility = BlockdxUtility()
self.utility = BlockDXHandler()
self.version = [global_variables.blockdx_release_url.split('/')[7]]
self.process_running = False
self.is_config_sync = None
Expand All @@ -20,15 +19,18 @@ async def setup(self):
self.root_gui.after(0, self.update_status_blockdx)

def blockdx_check_config(self):
# Get required data
if bool(self.root_gui.blocknet_manager.utility.data_folder and self.root_gui.blocknet_manager.utility.blocknet_conf_local):
xbridgeconfpath = os.path.normpath(
os.path.join(self.root_gui.blocknet_manager.utility.data_folder, "xbridge.conf"))
logging.info(f"xbridgeconfpath: {xbridgeconfpath}")
rpc_user = self.root_gui.blocknet_manager.utility.blocknet_conf_local.get('global', {}).get('rpcuser')
rpc_password = self.root_gui.blocknet_manager.utility.blocknet_conf_local.get('global', {}).get(
'rpcpassword')
self.utility.compare_and_update_local_conf(xbridgeconfpath, rpc_user, rpc_password)
"""
Checks and updates the local BlockDX configuration based on Blocknet settings.
"""
blocknet_utility = self.root_gui.blocknet_manager.utility
if not (blocknet_utility.data_folder and blocknet_utility.blocknet_conf_local):
return # Blocknet configuration is not available

xbridge_conf_path = os.path.normpath(os.path.join(blocknet_utility.data_folder, "xbridge.conf"))
rpc_user = blocknet_utility.blocknet_conf_local.get('global', {}).get('rpcuser')
rpc_password = blocknet_utility.blocknet_conf_local.get('global', {}).get('rpcpassword')

self.utility.compare_and_update_local_conf(xbridge_conf_path, rpc_user, rpc_password)

def update_status_blockdx(self):
self.frame_manager.update_blockdx_process_status_checkbox()
Expand Down
4 changes: 2 additions & 2 deletions gui/blocknet_manager.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from gui.blocknet_frame_manager import BlocknetCoreFrameManager
from utilities import global_variables
from utilities.blocknet_util import BlocknetUtility
from utilities.bin_handlers.blocknet_handler import BlocknetHandler


class BlocknetManager:
Expand All @@ -12,7 +12,7 @@ def __init__(self, root_gui):

self.bootstrap_thread = None

self.utility = BlocknetUtility(custom_path=self.root_gui.custom_path)
self.utility = BlocknetHandler(custom_path=self.root_gui.custom_path)

async def setup(self):
self.frame_manager = BlocknetCoreFrameManager(self)
Expand Down
70 changes: 36 additions & 34 deletions gui/xbridge_bot_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from utilities.git_repo_management import GitRepoManagement
from utilities.global_variables import aio_folder

logger = logging.getLogger(__name__)


class XBridgeBotManager:
def __init__(self, current_branch: str = "main"):
Expand All @@ -29,64 +31,64 @@ def get_available_branches(self) -> list:
"""Return list of available branches from remote repo"""
try:
if not self.repo_management:
logging.error(f"GitRepoManagement not initialized ?")
logger.error(f"GitRepoManagement not initialized ?")
return ["main"]
else:
return self.repo_management.get_remote_branches()
except Exception as e:
logging.error(f"Error fetching branches: {e}")
logger.error(f"Error fetching branches: {e}")
return ["main"]

def install_or_update(self, branch: str) -> None:
"""Install or update repo from given branch"""

if self.thread and self.thread.is_alive():
logging.warning("Install/update already in progress")
logger.warning("Install/update already in progress")
return

if not branch or not isinstance(branch, str):
logging.error(f"Invalid branch: {branch}")
logger.error(f"Invalid branch: {branch}")
return

logging.info(f"Starting install/update for branch: {branch}")
logger.info(f"Starting install/update for branch: {branch}")
self.thread = threading.Thread(
target=self._do_install_update,
args=(branch,),
name=f"XBridgeBotInstaller-{branch}"
)
self.thread.start()
# self.thread.join()
logging.info(f"Started installer thread {self.thread.name}")
logger.info(f"Started installer thread {self.thread.name}")

def _do_install_update(self, branch: str) -> None:
try:
logging.info(f"Attempting to install/update from {self.repo_url} to {self.target_dir}")
logger.info(f"Attempting to install/update from {self.repo_url} to {self.target_dir}")
self.repo_management = GitRepoManagement(self.repo_url, self.target_dir, branch=branch,
workdir=aio_folder)

if not os.path.exists(self.target_dir):
logging.info(f"Creating target directory: {self.target_dir}")
logger.info(f"Creating target directory: {self.target_dir}")
os.makedirs(self.target_dir, exist_ok=True)

self.repo_management.setup()
self.current_branch = branch
logging.info(f"Successfully updated to branch {branch}")
logger.info(f"Successfully updated to branch {branch}")
except Exception as e:
error_msg = str(e)
if "conflict prevents checkout" in error_msg or "conflicts prevent checkout" in error_msg:
self.handle_config_folder_rename()
else:
logging.error(f"Failed to update: {error_msg}")
logging.debug(f"Repository URL: {self.repo_url}")
logging.debug(f"Target directory: {self.target_dir}")
logging.debug(f"Branch: {branch}")
logger.error(f"Failed to update: {error_msg}")
logger.debug(f"Repository URL: {self.repo_url}")
logger.debug(f"Target directory: {self.target_dir}")
logger.debug(f"Branch: {branch}")

def handle_config_folder_rename(self):
logging.info("Successfully updated after resolving config conflict")
logger.info("Successfully updated after resolving config conflict")
config_path = os.path.join(self.target_dir, "config")

if not os.path.exists(config_path):
logging.warning("Config folder not found, cannot rename")
logger.warning("Config folder not found, cannot rename")
return

# Generate a unique backup folder name with timestamp
Expand All @@ -95,39 +97,39 @@ def handle_config_folder_rename(self):

try:
os.rename(config_path, config_bak_path)
logging.info(f"Renamed config folder to {config_bak_path} to resolve conflict")
logger.info(f"Renamed config folder to {config_bak_path} to resolve conflict")
except Exception as e:
logging.error(f"Failed to rename config folder: {e}")
logger.error(f"Failed to rename config folder: {e}")
return

# Retry setup once
try:
self.repo_management.setup()
logging.info("Successfully updated after resolving config conflict")
logger.info("Successfully updated after resolving config conflict")
except Exception as retry_e:
logging.error(f"Failed to update even after config rename: {retry_e}")
logger.error(f"Failed to update even after config rename: {retry_e}")

def delete_local_repo(self) -> None:
"""Delete local repository"""
if self.repo_exists():
try:
logging.info(f"Attempting to delete repository at {self.target_dir}")
logger.info(f"Attempting to delete repository at {self.target_dir}")
import shutil
if os.path.exists(self.target_dir):
shutil.rmtree(self.target_dir)
logging.info("Successfully deleted repository")
logger.info("Successfully deleted repository")
else:
logging.warning("Delete requested but directory does not exist")
logger.warning("Delete requested but directory does not exist")

# Reset state
self.repo_management = None
self.current_branch = "main"
except Exception as e:
logging.error(f"Failed to delete repository: {str(e)}", exc_info=True)
logger.error(f"Failed to delete repository: {str(e)}", exc_info=True)

def toggle_execution(self, branch=None) -> None:
"""Toggle script execution state. Returns new state"""
logging.info("toggle_execution")
logger.info("toggle_execution")
if branch is None:
branch = self.current_branch

Expand All @@ -142,13 +144,13 @@ def toggle_execution(self, branch=None) -> None:
self._stop_execution()
self.started = False
else:
logging.info("Venv setup in progress")
logger.info("Venv setup in progress")

def _start_execution(self) -> None:
"""Start script execution in background"""
while self.thread and self.thread.is_alive():
# wait for update tread to close completely.
logging.info("waiting thread end")
logger.info("waiting thread end")
time.sleep(0.5)
#
self.thread = threading.Thread(target=self._run_script)
Expand All @@ -163,22 +165,22 @@ def _stop_execution(self) -> None:
self.process.wait(timeout=5)
except subprocess.TimeoutExpired:
self.process.kill()
logging.info("Script execution stopped")
logger.info("Script execution stopped")
self.process = None
except Exception as e:
logging.error(f"Error stopping script: {e}")
logger.error(f"Error stopping script: {e}")

def _run_script(self) -> None:
"""Internal method to run the script"""
try:
if self.repo_management:
logging.info(f"Attempting to run script gui_pingpong.py in {self.target_dir}")
self.process = self.repo_management.run_script("gui_pingpong.py")
logger.info(f"Attempting to run script main_gui.py in {self.target_dir}")
self.process = self.repo_management.run_script("main_gui.py")
if self.process:
logging.info(f"Script started with PID: {self.process.pid}")
logger.info(f"Script started with PID: {self.process.pid}")
else:
logging.error("Failed to start script - no process returned")
logger.error("Failed to start script - no process returned")
else:
logging.error("Cannot run script - repo management not initialized")
logger.error("Cannot run script - repo management not initialized")
except Exception as e:
logging.error(f"Error executing script: {str(e)}", exc_info=True)
logger.error(f"Error executing script: {str(e)}", exc_info=True)
8 changes: 5 additions & 3 deletions gui/xlite_frame_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
CHECK_BOXES_STICKY, XLITE_FRAME_WIDTH
from utilities import utils

logger = logging.getLogger(__name__)


class XliteFrameManager:
def __init__(self, parent):
Expand Down Expand Up @@ -90,7 +92,7 @@ def xlite_store_password_button_mouse_click(self, event=None):
# Check if the right mouse button was clicked
if event and event.num == 3:
# wipe_stored_password
logging.info("Right click detected")
logger.info("Right click detected")
# Prevent the right-click event from propagating further
utils.remove_cfg_json_key("salt")
utils.remove_cfg_json_key("xl_pass")
Expand All @@ -107,7 +109,7 @@ def xlite_store_password_button_mouse_click(self, event=None):
if event and event.num == 1:
# ask_user_pass
# store_salted_pass
logging.info("Left click detected")
logger.info("Left click detected")
fg_color = self.master_frame.cget('fg_color')
password = ctkInputDialogMod.CTkInputDialog(
title="Store XLite Password",
Expand All @@ -122,7 +124,7 @@ def xlite_store_password_button_mouse_click(self, event=None):
# Store the password in a variable
self.root_gui.stored_password = password
else:
logging.info("No password entered.")
logger.info("No password entered.")
# Perform actions for left-click (if needed)
return "break"

Expand Down
Loading
Loading