From 1cbee4f5e782199fab253b899bba1d2500594d73 Mon Sep 17 00:00:00 2001 From: Sander Land <48946947+sanderland@users.noreply.github.com> Date: Thu, 28 Jan 2021 02:37:12 +0900 Subject: [PATCH] 1.7.3 (#337) * download fix * download fix * mac fix * close fix * package * Update osxbuild.yaml --- .github/workflows/osxbuild.yaml | 2 +- katrain/__main__.py | 7 +++-- katrain/core/constants.py | 2 +- katrain/core/engine.py | 24 +++++++++------- katrain/gui/popups.py | 50 +++++++++++++++++---------------- 5 files changed, 46 insertions(+), 39 deletions(-) diff --git a/.github/workflows/osxbuild.yaml b/.github/workflows/osxbuild.yaml index 2fd5705..b4d824c 100644 --- a/.github/workflows/osxbuild.yaml +++ b/.github/workflows/osxbuild.yaml @@ -67,4 +67,4 @@ jobs: with: files: KaTrainOSX/* draft: true - fail_on_unmatched_files: true \ No newline at end of file + fail_on_unmatched_files: true diff --git a/katrain/__main__.py b/katrain/__main__.py index 05e9dc6..36cda24 100644 --- a/katrain/__main__.py +++ b/katrain/__main__.py @@ -551,8 +551,9 @@ class KaTrainGui(Screen, KaTrainBase): @property def popup_open(self) -> Popup: app = App.get_running_app() - first_child = app.root_window.children[0] - return first_child if isinstance(first_child, Popup) else None + if app: + first_child = app.root_window.children[0] + return first_child if isinstance(first_child, Popup) else None def _on_keyboard_down(self, _keyboard, keycode, _text, modifiers): self.last_key_down = keycode @@ -715,7 +716,7 @@ class KaTrainApp(MDApp): if getattr(self, "gui", None): self.gui.play_mode.save_ui_state() if self.gui.engine: - self.gui.engine.shutdown() + self.gui.engine.shutdown(finish=None) def signal_handler(self, _signal, _frame): if self.gui.debug_level >= OUTPUT_DEBUG: diff --git a/katrain/core/constants.py b/katrain/core/constants.py index 2ca4216..bd32d0c 100644 --- a/katrain/core/constants.py +++ b/katrain/core/constants.py @@ -1,5 +1,5 @@ PROGRAM_NAME = "KaTrain" -VERSION = "1.7.2" +VERSION = "1.7.3" HOMEPAGE = "https://github.com/sanderland/katrain" CONFIG_MIN_VERSION = "1.7.0" # keep config files from this version ANALYSIS_FORMAT_VERSION = "1.0" diff --git a/katrain/core/engine.py b/katrain/core/engine.py index fce51f1..8800dbd 100644 --- a/katrain/core/engine.py +++ b/katrain/core/engine.py @@ -1,16 +1,17 @@ import copy import json import os -import sys +import platform import queue import shlex import subprocess +import sys import threading import time import traceback from typing import Callable, Dict, List, Optional -from kivy.utils import platform +from kivy.utils import platform as kivy_platform from katrain.core.constants import OUTPUT_DEBUG, OUTPUT_ERROR, OUTPUT_EXTRA_DEBUG, OUTPUT_KATAGO_STDERR from katrain.core.game_node import GameNode @@ -60,14 +61,14 @@ class KataGoEngine: self.shell = True else: if not exe: - if platform == "win": + if kivy_platform == "win": exe = "katrain/KataGo/katago.exe" - elif platform == "linux": + elif kivy_platform == "linux": exe = "katrain/KataGo/katago" else: - exe = find_package_resource("katrain/KataGo/katago-osx") # github actions built - if not os.path.isfile(exe): - exe = "katago" # e.g. MacOS after brewing + exe = find_package_resource("katrain/KataGo/katago-osx") # github actions built + if not os.path.isfile(exe) or "arm" in platform.machine(): + exe = "katago" # e.g. MacOS after brewing model = find_package_resource(config["model"]) cfg = find_package_resource(config["config"]) @@ -166,10 +167,13 @@ class KataGoEngine: self.wait_to_finish() if process: self.katago_process = None + self.katrain.log("Terminating KataGo process", OUTPUT_DEBUG) process.terminate() - for t in [self.stderr_thread, self.analysis_thread, self.write_stdin_thread]: - if t: - t.join() + self.katrain.log("Terminated KataGo process", OUTPUT_DEBUG) + if finish is not None: # don't care if exiting app + for t in [self.write_stdin_thread, self.analysis_thread, self.stderr_thread]: + if t: + t.join() def is_idle(self): return not self.queries and self.write_queue.empty() diff --git a/katrain/gui/popups.py b/katrain/gui/popups.py index 7d5f81f..a1c700d 100644 --- a/katrain/gui/popups.py +++ b/katrain/gui/popups.py @@ -225,7 +225,7 @@ class QuickConfigGui(MDBoxLayout): for c in widget.children: self._set_properties_subtree(c) - def update_config(self, save_to_file=True): + def update_config(self, save_to_file=True, close_popup=True): updated = set() for multikey, value in self.collect_properties(self).items(): old_value, conf, key = self.get_setting(multikey) @@ -235,14 +235,14 @@ class QuickConfigGui(MDBoxLayout): updated.add(multikey) if save_to_file: self.katrain.save_config() - if self.popup: + if self.popup and close_popup: self.popup.dismiss() return updated class ConfigTimerPopup(QuickConfigGui): - def update_config(self, save_to_file=True): - super().update_config(save_to_file=save_to_file) + def update_config(self, save_to_file=True, close_popup=True): + super().update_config(save_to_file=save_to_file, close_popup=close_popup) for p in self.katrain.players_info.values(): p.periods_used = 0 self.katrain.controls.timer.paused = True @@ -283,8 +283,8 @@ class NewGamePopup(QuickConfigGui): if rules is not None: self.rules_spinner.select_key(rules.strip()) - def update_config(self, save_to_file=True): - super().update_config(save_to_file=save_to_file) + def update_config(self, save_to_file=True, close_popup=True): + super().update_config(save_to_file=save_to_file, close_popup=close_popup) self.katrain.log(f"New game settings: {self.katrain.config('game')}", OUTPUT_DEBUG) if self.restart.active: self.katrain.log("Restarting Engine", OUTPUT_DEBUG) @@ -356,8 +356,8 @@ class ConfigTeacherPopup(QuickConfigGui): ) super().build_and_set_properties() - def update_config(self, save_to_file=True): - super().update_config(save_to_file=save_to_file) + def update_config(self, save_to_file=True, close_popup=True): + super().update_config(save_to_file=save_to_file, close_popup=close_popup) self.build_and_set_properties() @@ -421,13 +421,13 @@ class ConfigAIPopup(QuickConfigGui): self.options_grid.add_widget(Label(size_hint_x=None)) Clock.schedule_once(self.estimate_rank_from_options) - def update_config(self, save_to_file=True): - super().update_config(save_to_file=save_to_file) + def update_config(self, save_to_file=True, close_popup=True): + super().update_config(save_to_file=save_to_file, close_popup=close_popup) self.katrain.update_calculated_ranks() Clock.schedule_once(self.katrain.controls.update_players, 0) -class ConfigPopup(QuickConfigGui): +class BaseConfigPopup(QuickConfigGui): MODEL_ENDPOINTS = { "Latest distributed model": "https://katagotraining.org/api/networks/newest_training/", "Strongest distributed model": "https://katagotraining.org/api/networks/get_strongest/", @@ -465,13 +465,6 @@ class ConfigPopup(QuickConfigGui): super().__init__(katrain) self.paths = [self.katrain.config("engine/model"), "katrain/models", DATA_FOLDER] self.katago_paths = [self.katrain.config("engine/katago"), DATA_FOLDER] - Clock.schedule_once(self.check_katas) - self.last_clicked_download_models = 0 - MDApp.get_running_app().bind(language=self.check_models) - MDApp.get_running_app().bind(language=self.check_katas) - - def build_and_set_properties(self, *_args): - super().build_and_set_properties() def check_models(self, *args): all_models = [self.MODELS, self.MODEL_DESC, self.katrain.config("dist_models", {})] @@ -492,7 +485,8 @@ class ConfigPopup(QuickConfigGui): done = set() model_files = [] - for path in self.paths + [self.model_path.text]: + distributed_training_models = os.path.expanduser(os.path.join(DATA_FOLDER, "katago_contribute/kata1/models")) + for path in self.paths + [self.model_path.text, distributed_training_models]: path = path.rstrip("/\\") if path.startswith("katrain"): path = path.replace("katrain", PATHS["PACKAGE"].rstrip("/\\"), 1) @@ -608,7 +602,7 @@ class ConfigPopup(QuickConfigGui): if not any(os.path.split(f)[1] == filename for f in self.model_files.values): savepath = os.path.expanduser(os.path.join(DATA_FOLDER, filename)) savepath_tmp = savepath + ".part" - self.katrain.log(f"Downloading {name} model from {url} to {savepath_tmp}", OUTPUT_INFO) + self.katrain.log(f"Downloading {name} from {url} to {savepath_tmp}", OUTPUT_INFO) Clock.schedule_once( lambda _dt, _savepath=savepath, _savepath_tmp=savepath_tmp, _url=url, _name=name: ProgressLoader( self.download_progress_box, @@ -685,7 +679,8 @@ class ConfigPopup(QuickConfigGui): savepath_tmp = os.path.expanduser(os.path.join(DATA_FOLDER, filename)) exe_path_name = os.path.expanduser(os.path.join(DATA_FOLDER, exe_name)) self.katrain.log(f"Downloading binary {name} from {url} to {savepath_tmp}", OUTPUT_INFO) - progress = ProgressLoader( + ProgressLoader( + root_instance=self.katago_download_progress_box, download_url=url, path_to_file=savepath_tmp, downloading_text=f"Downloading {name}: " + "{}", @@ -700,7 +695,6 @@ class ConfigPopup(QuickConfigGui): f"Download of {mname} failed or cancelled ({error})", OUTPUT_ERROR ), ) - progress.start(self.katago_download_progress_box) downloading = True if not downloading: if not self.KATAGOS.get(platform): @@ -712,8 +706,16 @@ class ConfigPopup(QuickConfigGui): Label(text=i18n._("All binaries downloaded"), font_name=i18n.font_name, text_size=(None, dp(50))) ) - def update_config(self, save_to_file=True): - updated = super().update_config(save_to_file=save_to_file) + +class ConfigPopup(BaseConfigPopup): + def __init__(self, katrain): + super().__init__(katrain) + Clock.schedule_once(self.check_katas) + MDApp.get_running_app().bind(language=self.check_models) + MDApp.get_running_app().bind(language=self.check_katas) + + def update_config(self, save_to_file=True, close_popup=True): + updated = super().update_config(save_to_file=save_to_file, close_popup=close_popup) self.katrain.debug_level = self.katrain.config("general/debug_level", OUTPUT_INFO) ignore = {"max_visits", "fast_visits", "max_time", "enable_ownership", "wide_root_noise"}