Пример #1
0
    def build(self):
        self.icon = ICON  # how you're supposed to set an icon

        self.title = f"KaTrain v{VERSION}"
        self.theme_cls.theme_style = "Dark"
        self.theme_cls.primary_palette = "Gray"
        self.theme_cls.primary_hue = "200"

        kv_file = find_package_resource("katrain/gui.kv")
        popup_kv_file = find_package_resource("katrain/popups.kv")
        resource_add_path(PATHS["PACKAGE"] + "/fonts")
        resource_add_path(PATHS["PACKAGE"] + "/sounds")
        resource_add_path(PATHS["PACKAGE"] + "/img")
        resource_add_path(os.path.abspath(os.path.expanduser(DATA_FOLDER)))  # prefer resources in .katrain

        theme_file = resource_find("theme.json")
        if theme_file:
            try:
                with open(theme_file) as f:
                    theme_overrides = json.load(f)
                for k, v in theme_overrides.items():
                    setattr(Theme, k, v)
                    print(f"[{theme_file}] Found theme override {k} = {v}")
            except Exception as e:  # noqa E722
                print(f"Failed to load theme file {theme_file}: {e}")

        Theme.DEFAULT_FONT = resource_find(Theme.DEFAULT_FONT)
        Builder.load_file(kv_file)

        Window.bind(on_request_close=self.on_request_close)
        Window.bind(on_dropfile=lambda win, file: self.gui.load_sgf_file(file.decode("utf8")))
        self.gui = KaTrainGui()
        Builder.load_file(popup_kv_file)
        return self.gui
Пример #2
0
    def get_engine_path(self, exe):
        if not exe:
            if kivy_platform == "win":
                exe = "katrain/KataGo/katago.exe"
            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) or "arm64" in platform.version().lower():
                    exe = "katago"  # e.g. MacOS after brewing
        if exe.startswith("katrain"):
            exe = find_package_resource(exe)
        exepath, exename = os.path.split(exe)

        if exepath and not os.path.isfile(exe):
            self.katrain.log(i18n._("Kata exe not found").format(exe=exe), OUTPUT_ERROR)
            return None
        elif not exepath:
            paths = os.getenv("PATH", ".").split(os.pathsep) + ["/opt/homebrew/bin/"]
            exe_with_paths = [os.path.join(path, exe) for path in paths if os.path.isfile(os.path.join(path, exe))]
            if not exe_with_paths:
                self.katrain.log(i18n._("Kata exe not found in path").format(exe=exe), OUTPUT_ERROR)
                return None
            exe = exe_with_paths[0]
        return exe
Пример #3
0
    def __init__(self, katrain, config, override_command=None):
        self.katrain = katrain
        if override_command:
            self.command = override_command
        else:
            executable = config["katago"].strip()
            if not executable:
                if platform == "win":
                    executable = "katrain/KataGo/katago.exe"
                elif platform == "linux":
                    executable = "katrain/KataGo/katago"
                else:  # e.g. MacOS after brewing
                    executable = "katago"

            model = find_package_resource(config["model"])
            cfg = find_package_resource(config["config"])
            exe = find_package_resource(executable)
            self.command = f'"{exe}" analysis -model "{model}" -config "{cfg}" -analysis-threads {config["threads"]}'

        self.queries = {}  # outstanding query id -> start time and callback
        self.config = config
        self.query_counter = 0
        self.katago_process = None
        self.base_priority = 0
        self.override_settings = {}  # mainly for bot scripts to hook into
        self._lock = threading.Lock()
        self.analysis_thread = None
        self.stderr_thread = None
        self.start()
Пример #4
0
    def __init__(self, katrain, config):
        self.katrain = katrain
        self.queries = {}  # outstanding query id -> start time and callback
        self.config = config
        self.query_counter = 0
        self.katago_process = None
        self.base_priority = 0
        self.override_settings = {
            "reportAnalysisWinratesAs": "BLACK"
        }  # force these settings
        self.analysis_thread = None
        self.stderr_thread = None
        self.write_stdin_thread = None
        self.shell = False
        self.write_queue = queue.Queue()

        exe = config.get("katago", "").strip()
        if config.get("altcommand", ""):
            self.command = config["altcommand"]
            self.shell = True
        else:
            if not exe:
                if platform == "win":
                    exe = "katrain/KataGo/katago.exe"
                elif platform == "linux":
                    exe = "katrain/KataGo/katago"
                else:  # e.g. MacOS after brewing
                    exe = "katago"

            model = find_package_resource(config["model"])
            cfg = find_package_resource(config["config"])
            if exe.startswith("katrain"):
                exe = find_package_resource(exe)

            exepath, exename = os.path.split(exe)
            if exepath and not os.path.isfile(exe):
                self.katrain.log(
                    i18n._("Kata exe not found").format(exe=exe), OUTPUT_ERROR)
                return  # don't start
            elif not exepath and not any(
                    os.path.isfile(os.path.join(path, exe))
                    for path in os.environ.get("PATH", "").split(os.pathsep)):
                self.katrain.log(
                    i18n._("Kata exe not found in path").format(exe=exe),
                    OUTPUT_ERROR)
                return  # don't start
            elif not os.path.isfile(model):
                self.katrain.log(
                    i18n._("Kata model not found").format(model=model),
                    OUTPUT_ERROR)
                return  # don't start
            elif not os.path.isfile(cfg):
                self.katrain.log(
                    i18n._("Kata config not found").format(config=cfg),
                    OUTPUT_ERROR)
                return  # don't start
            self.command = shlex.split(
                f'"{exe}" analysis -model "{model}" -config "{cfg}" -analysis-threads {config["threads"]}'
            )
        self.start()
Пример #5
0
    def __init__(self, katrain, config):
        super().__init__(katrain, config)

        self.queries = {}  # outstanding query id -> start time and callback
        self.query_counter = 0
        self.katago_process = None
        self.base_priority = 0
        self.override_settings = {"reportAnalysisWinratesAs": "BLACK"}  # force these settings
        self.analysis_thread = None
        self.stderr_thread = None
        self.write_stdin_thread = None
        self.shell = False
        self.write_queue = queue.Queue()
        self.thread_lock = threading.Lock()
        exe = config.get("katago", "").strip()
        if config.get("altcommand", ""):
            self.command = config["altcommand"]
            self.shell = True
        else:
            model = find_package_resource(config["model"])
            cfg = find_package_resource(config["config"])
            exe = self.get_engine_path(config["katago"])
            if not exe:
                return
            if not os.path.isfile(model):
                self.katrain.log(i18n._("Kata model not found").format(model=model), OUTPUT_ERROR)
                return  # don't start
            if not os.path.isfile(cfg):
                self.katrain.log(i18n._("Kata config not found").format(config=cfg), OUTPUT_ERROR)
                return  # don't start
            self.command = shlex.split(
                f'"{exe}" analysis -model "{model}" -config "{cfg}" -analysis-threads {config["threads"]} -override-config "homeDataDir={os.path.expanduser(DATA_FOLDER)}"'
            )
        self.start()
Пример #6
0
    def build(self):
        self.icon = ICON  # how you're supposed to set an icon

        self.title = f"KaTrain v{VERSION}"
        self.theme_cls.theme_style = "Dark"
        self.theme_cls.primary_palette = "Gray"
        self.theme_cls.primary_hue = "200"

        kv_file = find_package_resource("katrain/gui.kv")
        popup_kv_file = find_package_resource("katrain/popups.kv")
        resource_add_path(PATHS["PACKAGE"] + "/fonts")
        resource_add_path(PATHS["PACKAGE"] + "/sounds")
        resource_add_path(PATHS["PACKAGE"] + "/img")
        resource_add_path(os.path.abspath(
            os.path.expanduser(DATA_FOLDER)))  # prefer resources in .katrain

        theme_file = resource_find("theme.json")
        if theme_file:
            try:
                with open(theme_file) as f:
                    theme_overrides = json.load(f)
                for k, v in theme_overrides.items():
                    setattr(Theme, k, v)
                    print(f"[{theme_file}] Found theme override {k} = {v}")
            except Exception as e:  # noqa E722
                print(f"Failed to load theme file {theme_file}: {e}")

        Theme.DEFAULT_FONT = resource_find(Theme.DEFAULT_FONT)
        Builder.load_file(kv_file)

        Window.bind(on_request_close=self.on_request_close)
        Window.bind(on_dropfile=lambda win, file: self.gui.load_sgf_file(
            file.decode("utf8")))
        self.gui = KaTrainGui()
        Builder.load_file(popup_kv_file)

        win_size = self.gui.config("ui_state/size", [])
        win_left = self.gui.config("ui_state/left", None)
        win_top = self.gui.config("ui_state/top", None)
        if not win_size:
            window_scale_fac = 1
            try:
                from screeninfo import get_monitors

                for m in get_monitors():
                    window_scale_fac = min(window_scale_fac,
                                           (m.height - 100) / 1000,
                                           (m.width - 100) / 1300)
            except Exception as e:
                window_scale_fac = 0.85
            win_size = [1300 * window_scale_fac, 1000 * window_scale_fac]
        Window.size = (win_size[0], win_size[1])
        if win_left is not None and win_top is not None:
            Window.left = win_left
            Window.top = win_top

        return self.gui
Пример #7
0
    def __init__(self, katrain, config, override_command=None):
        self.katrain = katrain
        self.queries = {}  # outstanding query id -> start time and callback
        self.config = config
        self.query_counter = 0
        self.katago_process = None
        self.base_priority = 0
        self.override_settings = {}  # mainly for bot scripts to hook into
        self._lock = threading.Lock()
        self.analysis_thread = None
        self.stderr_thread = None

        if override_command:
            self.command = override_command
        else:
            exe = config["katago"].strip()
            if not exe:
                if platform == "win":
                    exe = "katrain/KataGo/katago.exe"
                elif platform == "linux":
                    exe = "katrain/KataGo/katago"
                else:  # e.g. MacOS after brewing
                    exe = "katago"

            model = find_package_resource(config["model"])
            cfg = find_package_resource(config["config"])
            if exe.startswith("katrain"):
                exe = find_package_resource(exe)

            exepath, exename = os.path.split(exe)
            if exepath and not os.path.isfile(exe):
                self.katrain.log(
                    i18n._("Kata exe not found").format(exe=exe), OUTPUT_ERROR)
                return  # don't start
            elif not exepath and not any(
                    os.path.isfile(os.path.join(path, exe))
                    for path in os.environ.get("PATH", "").split(os.pathsep)):
                self.katrain.log(
                    i18n._("Kata exe not found in path").format(exe=exe),
                    OUTPUT_ERROR)
                return  # don't start
            elif not os.path.isfile(model):
                self.katrain.log(
                    i18n._("Kata model not found").format(model=model),
                    OUTPUT_ERROR)
                return  # don't start
            elif not os.path.isfile(cfg):
                self.katrain.log(
                    i18n._("Kata config not found").format(config=cfg),
                    OUTPUT_ERROR)
                return  # don't start
            self.command = f'"{exe}" analysis -model "{model}" -config "{cfg}" -analysis-threads {config["threads"]}'
        self.start()
Пример #8
0
    def __init__(self, katrain):
        super().__init__(katrain, katrain.config("contribute"))
        self.katrain = katrain
        base_dir = os.path.expanduser("~/.katrain/katago_contribute")
        self.katago_process = None
        self.stdout_thread = None
        self.stderr_thread = None
        self.shell = False
        self.active_games = {}
        self.finished_games = set()
        self.showing_game = None
        self.last_advance = 0
        self.move_count = 0
        self.uploaded_games_count = 0
        self.last_move_for_game = defaultdict(int)
        self.visits_count = 0
        self.start_time = 0
        self.server_error = None

        self.save_sgf = self.config.get("savesgf", False)
        self.save_path = self.config.get("savepath", "./dist_sgf/")
        self.move_speed = self.config.get("movespeed", 2.0)

        exe = self.get_engine_path(self.config.get("katago"))
        cacert_path = os.path.join(os.path.split(exe)[0], "cacert.pem")
        if not os.path.isfile(cacert_path):
            try:
                shutil.copyfile(
                    find_package_resource("katrain/KataGo/cacert.pem"),
                    cacert_path)
            except Exception as e:
                self.katrain.log(
                    f"Could not copy cacert file ({e}), please add it manually to your katago.exe directory",
                    OUTPUT_ERROR,
                )
        cfg = find_package_resource(self.config.get("config"))

        settings_dict = {
            "username": self.config.get("username"),
            "password": self.config.get("password"),
            "maxSimultaneousGames": self.config.get("maxgames")
            or self.DEFAULT_MAX_GAMES,
            "includeOwnership": self.config.get("ownership") or False,
            "logGamesAsJson": True,
            "homeDataDir": os.path.expanduser(DATA_FOLDER),
        }
        self.max_buffer_games = 2 * settings_dict["maxSimultaneousGames"]
        settings = {f"{k}={v}" for k, v in settings_dict.items()}
        self.command = shlex.split(
            f'"{exe}" contribute -config "{cfg}" -base-dir "{base_dir}" -override-config "{",".join(settings)}"'
        )
        self.start()
Пример #9
0
 def _load_config(self, force_package_config):
     if len(sys.argv) > 1 and sys.argv[1].endswith("config.json"):
         config_file = os.path.abspath(sys.argv[1])
         self.log(f"Using command line config file {config_file}",
                  OUTPUT_INFO)
     else:
         user_config_file = find_package_resource(self.USER_CONFIG_FILE)
         package_config_file = find_package_resource(
             self.PACKAGE_CONFIG_FILE)
         if force_package_config:
             config_file = package_config_file
         else:
             try:
                 if not os.path.exists(user_config_file):
                     os.makedirs(os.path.split(user_config_file)[0],
                                 exist_ok=True)
                     shutil.copyfile(package_config_file, user_config_file)
                     config_file = user_config_file
                     self.log(
                         f"Copied package config to local file {config_file}",
                         OUTPUT_INFO)
                 else:  # user file exists
                     try:
                         version = JsonStore(user_config_file).get(
                             "general")["version"]
                     except Exception:  # noqa E722 broken file etc
                         version = "0.0.0"
                     if version < CONFIG_MIN_VERSION:
                         backup = user_config_file + f".{version}.backup"
                         shutil.copyfile(user_config_file, backup)
                         shutil.copyfile(package_config_file,
                                         user_config_file)
                         self.log(
                             f"Copied package config file to {user_config_file} as user file is outdated or broken ({version}<{CONFIG_MIN_VERSION}). Old version stored as {backup}",
                             OUTPUT_INFO,
                         )
                     config_file = user_config_file
                     self.log(f"Using user config file {config_file}",
                              OUTPUT_INFO)
             except Exception as e:
                 config_file = package_config_file
                 self.log(
                     f"Using package config file {config_file} (exception {e} occurred when finding or creating user config)",
                     OUTPUT_INFO,
                 )
     try:
         self._config_store = JsonStore(config_file, indent=4)
     except Exception as e:
         self.log(f"Failed to load config {config_file}: {e}", OUTPUT_ERROR)
         sys.exit(1)
     self._config = dict(self._config_store)
     return config_file
Пример #10
0
def run_app():
    kv_file = find_package_resource("katrain/gui.kv")
    popup_kv_file = find_package_resource("katrain/popups.kv")
    resource_add_path(os.path.split(kv_file)[0])
    Builder.load_file(kv_file)
    Builder.load_file(popup_kv_file)
    app = KaTrainApp()
    signal.signal(signal.SIGINT, app.signal_handler)
    try:
        app.run()
    except Exception as e:
        print(e)
        app.on_request_close()
        raise
Пример #11
0
    def switch_lang(self, lang):
        if lang == self.lang:
            return
        # get the right locales directory, and instantiate a gettext
        self.lang = lang
        self.font_name = self.FONTS.get(lang) or DEFAULT_FONT
        i18n_dir, _ = os.path.split(
            find_package_resource("katrain/i18n/__init__.py"))
        locale_dir = os.path.join(i18n_dir, "locales")
        locales = gettext.translation("katrain", locale_dir, languages=[lang])
        self.ugettext = locales.gettext

        # update all the kv rules attached to this text
        for widget, func, args in self.observers:
            try:
                func(args[0], None, None)
                self.set_widget_font(widget)
            except ReferenceError:
                pass  # proxy no longer exists
            except Exception as e:
                print("Error in switching languages", e)
        for cb in self.callbacks:
            try:
                cb(self)
            except Exception as e:
                print(f"Failed callback on language change: {e}",
                      file=sys.stderr)
Пример #12
0
    def build(self):
        self.icon = ICON  # how you're supposed to set an icon

        kv_file = find_package_resource("katrain/gui.kv")
        popup_kv_file = find_package_resource("katrain/popups.kv")
        resource_add_path(os.path.split(kv_file)[0])
        Builder.load_file(kv_file)
        Builder.load_file(popup_kv_file)

        self.gui = KaTrainGui()
        self.title = f"KaTrain v{VERSION}"
        self.theme_cls.theme_style = "Dark"
        self.theme_cls.primary_palette = "Blue"

        Window.bind(on_request_close=self.on_request_close)
        return self.gui
Пример #13
0
    def check_models(self, *args):  # WIP
        try:
            model = self.collect_properties(self)["engine/model"]
        except InputParseError:
            self.model_files.values = []
            return

        if os.path.exists(model):
            if os.path.isdir(model):
                path = model.rstrip("\\/")
                file = None
            else:
                if model.startswith("katrain"):
                    model = find_package_resource(model)
                path, file = os.path.split(model)
            files = sorted([
                os.path.split(f)[1] for ftype in ["*.bin.gz", "*.txt.gz"]
                for f in glob.glob(path + os.path.sep + ftype)
            ])
            self.model_files.values = files
            print(file, files, file in files)
            if file in files:
                self.model_files.text = file
        else:
            self.model_files.values = []
Пример #14
0
    def build(self):
        self.icon = ICON  # how you're supposed to set an icon

        self.title = f"KaTrain v{VERSION}"
        self.theme_cls.theme_style = "Dark"
        self.theme_cls.primary_palette = "Gray"
        self.theme_cls.primary_hue = "200"

        kv_file = find_package_resource("katrain/gui.kv")
        popup_kv_file = find_package_resource("katrain/popups.kv")
        resource_add_path(PATHS["PACKAGE"])
        Builder.load_file(kv_file)

        Window.bind(on_request_close=self.on_request_close)
        Window.bind(on_dropfile=lambda win, file: self.gui.load_sgf_file(file.decode("utf8")))

        self.gui = KaTrainGui()
        Builder.load_file(popup_kv_file)
        return self.gui
Пример #15
0
 def check_error(self, _dt=None):
     file = find_package_resource(self.input_value, silent_errors=True)
     self.error = self.check_path and not (file and os.path.exists(file))
Пример #16
0
"""isort:skip_file"""
# first, logging level lower
import os

os.environ["KCFG_KIVY_LOG_LEVEL"] = os.environ.get("KCFG_KIVY_LOG_LEVEL", "warning")
if "KIVY_AUDIO" not in os.environ:
    os.environ["KIVY_AUDIO"] = "sdl2"  # some backends hard crash / this seems to be most stable

# next, icon
from katrain.core.utils import find_package_resource, PATHS
from kivy.config import Config
from kivy.utils import platform

ICON = find_package_resource("katrain/img/icon.ico")
Config.set("kivy", "window_icon", ICON)

# finally, window size
WINDOW_SCALE_FAC, WINDOW_X, WINDOW_Y = 1, 1300, 1000
try:
    from screeninfo import get_monitors

    for m in get_monitors():
        WINDOW_SCALE_FAC = min(WINDOW_SCALE_FAC, (m.height - 100) / WINDOW_Y, (m.width - 100) / WINDOW_X)
except Exception as e:
    if platform != "macosx":
        print(f"Exception {e} while getting screen resolution.")
        WINDOW_SCALE_FAC = 0.85

Config.set("graphics", "width", max(400, int(WINDOW_X * WINDOW_SCALE_FAC)))
Config.set("graphics", "height", max(400, int(WINDOW_Y * WINDOW_SCALE_FAC)))
Config.set("input", "mouse", "mouse,multitouch_on_demand")
Пример #17
0
# first, logging level lower
import os
os.environ["KCFG_KIVY_LOG_LEVEL"] = os.environ.get("KCFG_KIVY_LOG_LEVEL",
                                                   "warning")
os.environ['KIVY_AUDIO'] = "sdl2"  # force working audio

# next, icon
from katrain.core.utils import find_package_resource  # isort:skip
from kivy.config import Config  # isort:skip
ICON = find_package_resource("katrain/img/icon.ico")  # isort:skip  # find icon
Config.set("kivy", "window_icon", ICON)  # isort:skip  # set icon

# finally, window size
from kivy.metrics import dp
WINDOW_X, WINDOW_Y = 1300, 1000
try:
    from screeninfo import get_monitors
    scale = 1.0
    for m in get_monitors():
        scale = min(scale, (m.height - 100) / WINDOW_Y,
                    (m.width - 100) / WINDOW_X)
    WINDOW_SCALE_FAC = max(0.4, scale)
except Exception as e:
    print("Exception while getting screen resolution", e)
    WINDOW_SCALE_FAC = 1

Config.set("graphics", "width", int(WINDOW_SCALE_FAC * WINDOW_X))
Config.set("graphics", "height", int(WINDOW_SCALE_FAC * WINDOW_Y))
Config.set("input", "mouse", "mouse,multitouch_on_demand")

import signal
Пример #18
0
    def __init__(self, katrain, config):
        self.katrain = katrain
        self.queries = {}  # outstanding query id -> start time and callback
        self.config = config
        self.query_counter = 0
        self.katago_process = None
        self.base_priority = 0
        self.override_settings = {
            "reportAnalysisWinratesAs": "BLACK"
        }  # force these settings
        self.analysis_thread = None
        self.stderr_thread = None
        self.write_stdin_thread = None
        self.shell = False
        self.write_queue = queue.Queue()
        self.thread_lock = threading.Lock()
        exe = config.get("katago", "").strip()
        if config.get("altcommand", ""):
            self.command = config["altcommand"]
            self.shell = True
        else:
            if not exe:
                if kivy_platform == "win":
                    exe = "katrain/KataGo/katago.exe"
                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) or "arm64" in platform.version(
                    ).lower():
                        exe = "katago"  # e.g. MacOS after brewing

            model = find_package_resource(config["model"])
            cfg = find_package_resource(config["config"])
            if exe.startswith("katrain"):
                exe = find_package_resource(exe)

            exepath, exename = os.path.split(exe)
            if exepath and not os.path.isfile(exe):
                self.katrain.log(
                    i18n._("Kata exe not found").format(exe=exe), OUTPUT_ERROR)
                return  # don't start
            elif not exepath:
                paths = os.getenv("PATH", ".").split(
                    os.pathsep) + ["/opt/homebrew/bin/"]
                exe_with_paths = [
                    os.path.join(path, exe) for path in paths
                    if os.path.isfile(os.path.join(path, exe))
                ]
                if not exe_with_paths:
                    self.katrain.log(
                        i18n._("Kata exe not found in path").format(exe=exe),
                        OUTPUT_ERROR)
                    return  # don't start
                exe = exe_with_paths[0]
            elif not os.path.isfile(model):
                self.katrain.log(
                    i18n._("Kata model not found").format(model=model),
                    OUTPUT_ERROR)
                return  # don't start
            elif not os.path.isfile(cfg):
                self.katrain.log(
                    i18n._("Kata config not found").format(config=cfg),
                    OUTPUT_ERROR)
                return  # don't start
            self.command = shlex.split(
                f'"{exe}" analysis -model "{model}" -config "{cfg}" -analysis-threads {config["threads"]}'
            )
        self.start()