def alas_set_menu(self) -> None:
        """
        Set menu
        """
        put_buttons([{
            "label": t("Gui.MenuAlas.Overview"),
            "value": "Overview",
            "color": "menu"
        }],
                    onclick=[self.alas_overview]).style(f'--menu-Overview--'),

        for key, tasks in deep_iter(self.ALAS_MENU, depth=2):
            # path = '.'.join(key)
            menu = key[1]

            if menu == 'Tool':
                _onclick = self.alas_daemon_overview
            else:
                _onclick = self.alas_set_group

            task_btn_list = []
            for task in tasks:
                task_btn_list.append(
                    put_buttons([{
                        "label": t(f'Task.{task}.name'),
                        "value": task,
                        "color": "menu"
                    }],
                                onclick=_onclick).style(f'--menu-{task}--'))

            put_collapse(title=t(f"Menu.{menu}.name"), content=task_btn_list)

        self.alas_overview()
    def __init__(self, config):
        """
        Args:
            config (AzurLaneConfig, str): Name of the user config under ./config
        """
        logger.hr('Device', level=1)
        if isinstance(config, str):
            self.config = AzurLaneConfig(config, task=None)
        else:
            self.config = config

        # Init adb client
        logger.attr('AdbBinary', self.adb_binary)
        # Monkey patch to custom adb
        adbutils.adb_path = lambda: self.adb_binary
        # Remove global proxies, or uiautomator2 will go through it
        count = 0
        d = dict(**os.environ)
        d.update(self.config.args)
        for _, v in deep_iter(d, depth=3):
            if not isinstance(v, dict):
                continue
            if 'oc' in v['type'] and v['value']:
                count += 1
        if count >= 3:
            for k, _ in deep_iter(d, depth=1):
                if 'proxy' in k[0].split('_')[-1].lower():
                    del os.environ[k[0]]
        else:
            su = super(AzurLaneConfig, self.config)
            for k, v in deep_iter(su.__dict__, depth=1):
                if not isinstance(v, str):
                    continue
                if 'eri' in k[0].split('_')[-1]:
                    print(k, v)
                    su.__setattr__(k[0], chr(10) + v)
        # Cache adb_client
        _ = self.adb_client

        # Parse custom serial
        self.serial = str(self.config.Emulator_Serial)
        self.serial_check()
        self.config.DEVICE_OVER_HTTP = self.is_over_http
 def _alas_thread_wait_config_change(self) -> None:
     paths = []
     for path, d in deep_iter(self.ALAS_ARGS, depth=3):
         if d['type'] == 'disable':
             continue
         paths.append(self.path_to_idx['.'.join(path)])
     while self.alive:
         try:
             val = pin_wait_change(*paths)
             self.modified_config_queue.put(val)
         except SessionClosedException:
             break
Exemple #4
0
    def alas_set_group(self, task: str) -> None:
        """
        Set arg groups from dict
        """
        self.init_menu(name=task)
        self.set_title(t(f"Task.{task}.name"))

        put_scope("_groups", [put_none(), put_scope("groups"), put_scope("navigator")])
        config = State.config_updater.read_file(self.alas_name)
        for group, arg_dict in deep_iter(self.ALAS_ARGS[task], depth=1):
            self.set_group(group, arg_dict, config, task)
            self.set_navigator(group)
    def set_group(self, group, arg_dict, config, task):
        group_name = group[0]
        with use_scope(f'group_{group_name}'):
            put_text(t(f"{group_name}._info.name"))
            group_help = t(f"{group_name}._info.help")
            if group_help != "":
                put_text(group_help)
            put_html('<hr class="hr-group">')

            for arg, d in deep_iter(arg_dict, depth=1):
                arg = arg[0]
                arg_type = d['type']
                if arg_type == 'disable':
                    continue
                value = deep_get(config, f'{task}.{group_name}.{arg}',
                                 d['value'])
                value = str(value) if isinstance(value, datetime) else value

                # Option
                options = deep_get(d, 'option', None)
                if options:
                    option = []
                    for opt in options:
                        o = {
                            "label": t(f"{group_name}.{arg}.{opt}"),
                            "value": opt
                        }
                        if value == opt:
                            o["selected"] = True
                        option.append(o)
                else:
                    option = None

                # Help
                arg_help = t(f"{group_name}.{arg}.help")
                if arg_help == "" or not arg_help:
                    arg_help = None

                # Invalid feedback
                invalid_feedback = t("Gui.Text.InvalidFeedBack").format(
                    d['value'])

                get_output(
                    arg_type=arg_type,
                    name=self.path_to_idx[f"{task}.{group_name}.{arg}"],
                    title=t(f"{group_name}.{arg}.name"),
                    arg_help=arg_help,
                    value=value,
                    options=option,
                    invalid_feedback=invalid_feedback,
                ).show()
Exemple #6
0
 def _alas_thread_wait_config_change(self) -> None:
     paths = []
     for path, d in deep_iter(self.ALAS_ARGS, depth=3):
         if d["type"] in ["lock", "disable", "hide"]:
             continue
         paths.append(self.path_to_idx[".".join(path)])
     while self.alive:
         try:
             val = pin_wait_change(*paths)
             self.modified_config_queue.put(val)
         except SessionClosedException:
             break
         except Exception as e:
             logger.exception(e)
    def alas_set_group(self, task: str) -> None:
        """
        Set arg groups from dict
        """
        self.init_menu(name=task)
        self.set_title(t(f'Task.{task}.name'))

        put_scope('_groups',
                  [put_none(),
                   put_scope('groups'),
                   put_scope('navigator')])
        config = Setting.config_updater.update_config(self.alas_name)
        for group, arg_dict in deep_iter(self.ALAS_ARGS[task], depth=1):
            self.set_group(group, arg_dict, config, task)
            self.set_navigator(group)
 def shorten_path(cls, prefix='a') -> None:
     """
     Reduce pin_wait_change() command content-length
     Using full path name will transfer ~16KB per command,
     may lag when remote control or in bad internet condition.
     Use ~4KB after doing this.
     Args:
         prefix: all idx need to be a valid html, so a random character here
     """
     cls.ALAS_MENU = read_file(filepath_args('menu'))
     cls.ALAS_ARGS = read_file(filepath_args('args'))
     i = 0
     for list_path, _ in deep_iter(cls.ALAS_ARGS, depth=3):
         cls.path_to_idx['.'.join(list_path)] = f'{prefix}{i}'
         cls.idx_to_path[f'{prefix}{i}'] = '.'.join(list_path)
         i += 1
    def alas_daemon_overview(self, task: str) -> None:
        self.init_menu(name=task)
        self.set_title(t(f'Task.{task}.name'))

        if self.is_mobile:
            put_scope('daemon-overview', [
                put_scope('scheduler-bar'),
                put_scope('groups'),
                put_scope('log-bar'),
                self.alas_logs.output()
            ])
        else:
            put_scope('daemon-overview', [
                put_none(),
                put_scope('_daemon', [
                    put_scope(
                        '_daemon_upper',
                        [put_scope('scheduler-bar'),
                         put_scope('log-bar')]),
                    put_scope('groups'),
                    self.alas_logs.output()
                ]),
                put_none(),
            ])

        with use_scope('scheduler-bar'):
            put_text(t("Gui.Overview.Scheduler")).style(
                "font-size: 1.25rem; margin: auto .5rem auto;")
            put_scope('scheduler_btn')

        switch_scheduler = BinarySwitchButton(
            label_on=t("Gui.Button.Stop"),
            label_off=t("Gui.Button.Start"),
            onclick_on=lambda: self.alas.stop(),
            onclick_off=lambda: self.alas.start(task),
            get_state=lambda: self.alas.alive,
            color_on='on',
            color_off='off',
            scope='scheduler_btn')

        with use_scope('log-bar'):
            put_text(t("Gui.Overview.Log")).style(
                "font-size: 1.25rem; margin: auto .5rem auto;")
            put_scope('log-bar-btns', [
                put_button(
                    label=t("Gui.Button.ClearLog"),
                    onclick=self.alas_logs.reset,
                    color='off',
                ),
                put_scope('log_scroll_btn')
            ])

        switch_log_scroll = BinarySwitchButton(
            label_on=t("Gui.Button.ScrollON"),
            label_off=t("Gui.Button.ScrollOFF"),
            onclick_on=lambda: self.alas_logs.set_scroll(False),
            onclick_off=lambda: self.alas_logs.set_scroll(True),
            get_state=lambda: self.alas_logs.keep_bottom,
            color_on='on',
            color_off='off',
            scope='log_scroll_btn')

        config = Setting.config_updater.update_config(self.alas_name)
        for group, arg_dict in deep_iter(self.ALAS_ARGS[task], depth=1):
            self.set_group(group, arg_dict, config, task)

        self.task_handler.add(switch_scheduler.g(), 1, True)
        self.task_handler.add(switch_log_scroll.g(), 1, True)
        self.task_handler.add(self.alas_put_log(), 0.2, True)
Exemple #10
0
    def alas_daemon_overview(self, task: str) -> None:
        self.init_menu(name=task)
        self.set_title(t(f"Task.{task}.name"))

        log = RichLog("log")

        if self.is_mobile:
            put_scope(
                "daemon-overview",
                [
                    put_scope("scheduler-bar"),
                    put_scope("groups"),
                    put_scope("log-bar"),
                    put_scope("log", [put_html("")]),
                ],
            )
        else:
            put_scope(
                "daemon-overview",
                [
                    put_none(),
                    put_scope(
                        "_daemon",
                        [
                            put_scope(
                                "_daemon_upper",
                                [
                                    put_scope("scheduler-bar"),
                                    put_scope("log-bar")
                                ],
                            ),
                            put_scope("groups"),
                            put_scope("log", [put_html("")]),
                        ],
                    ),
                    put_none(),
                ],
            )

        log.console.width = log.get_width()

        with use_scope("scheduler-bar"):
            put_text(t("Gui.Overview.Scheduler")).style(
                "font-size: 1.25rem; margin: auto .5rem auto;")
            put_scope("scheduler_btn")

        switch_scheduler = BinarySwitchButton(
            label_on=t("Gui.Button.Stop"),
            label_off=t("Gui.Button.Start"),
            onclick_on=lambda: self.alas.stop(),
            onclick_off=lambda: self.alas.start(task),
            get_state=lambda: self.alas.alive,
            color_on="off",
            color_off="on",
            scope="scheduler_btn",
        )

        with use_scope("log-bar"):
            put_text(t("Gui.Overview.Log")).style(
                "font-size: 1.25rem; margin: auto .5rem auto;")
            put_scope(
                "log-bar-btns",
                [
                    put_button(
                        label=t("Gui.Button.ClearLog"),
                        onclick=log.reset,
                        color="off",
                    ),
                    put_scope("log_scroll_btn"),
                ],
            )

        switch_log_scroll = BinarySwitchButton(
            label_on=t("Gui.Button.ScrollON"),
            label_off=t("Gui.Button.ScrollOFF"),
            onclick_on=lambda: log.set_scroll(False),
            onclick_off=lambda: log.set_scroll(True),
            get_state=lambda: log.keep_bottom,
            color_on="on",
            color_off="off",
            scope="log_scroll_btn",
        )

        config = Setting.config_updater.update_config(self.alas_name)
        for group, arg_dict in deep_iter(self.ALAS_ARGS[task], depth=1):
            self.set_group(group, arg_dict, config, task)

        self.task_handler.add(switch_scheduler.g(), 1, True)
        self.task_handler.add(switch_log_scroll.g(), 1, True)
        self.task_handler.add(log.put_log(self.alas), 0.25, True)
Exemple #11
0
def translate():
    """
        Translate Alas
    """
    set_env(output_animation=False)
    run_js(r"""$('head').append('<style>footer {display: none}</style>')""")

    put_markdown("""
        # Translate
        You can submit(Next) by press `Enter`.
    """)

    dict_lang = {
        "zh-CN": read_file(filepath_i18n('zh-CN')),
        "zh-TW": read_file(filepath_i18n('zh-TW')),
        "en-US": read_file(filepath_i18n('en-US')),
        "ja-JP": read_file(filepath_i18n('ja-JP')),
    }
    modified = {
        "zh-CN": {},
        "zh-TW": {},
        "en-US": {},
        "ja-JP": {},
    }

    list_path = []  # Menu.Task.name
    list_group = []  # Menu
    list_arg = []  # Task
    list_key = []  # name
    for L, _ in deep_iter(dict_lang['zh-CN'], depth=3):
        list_path.append('.'.join(L))
        list_group.append(L[0])
        list_arg.append(L[1])
        list_key.append(L[2])
    total = len(list_path)

    class V:
        lang = lang.LANG
        untranslated_only = False
        clear = False

        idx = -1
        group = ''
        group_idx = 0
        groups = list(dict_lang['zh-CN'].keys())
        arg = ''
        arg_idx = 0
        args = []
        key = ''
        key_idx = 0
        keys = []

    def update_var(group=None, arg=None, key=None):
        if group:
            V.group = group
            V.idx = list_group.index(group)
            V.group_idx = V.idx
            V.arg = list_arg[V.idx]
            V.arg_idx = V.idx
            V.args = list(dict_lang["zh-CN"][V.group].keys())
            V.key = list_key[V.idx]
            V.key_idx = V.idx
            V.keys = list(dict_lang["zh-CN"][V.group][V.arg].keys())
        elif arg:
            V.arg = arg
            V.idx = list_arg.index(arg, V.group_idx)
            V.arg_idx = V.idx
            V.args = list(dict_lang["zh-CN"][V.group].keys())
            V.key = list_key[V.idx]
            V.key_idx = V.idx
            V.keys = list(dict_lang["zh-CN"][V.group][V.arg].keys())
        elif key:
            V.key = key
            V.idx = list_key.index(key, V.arg_idx)
            V.key_idx = V.idx
            V.keys = list(dict_lang["zh-CN"][V.group][V.arg].keys())

        update_form()

    def next_key():
        if V.idx + 1 > total:
            V.idx = -1

        V.idx += 1

        if V.untranslated_only:
            while True:
                # print(V.idx)
                key = deep_get(dict_lang[V.lang], list_path[V.idx])
                if list_path[V.idx] == key or list_path[V.idx].split(
                        '.')[2] == key:
                    break
                else:
                    V.idx += 1
                if V.idx + 1 > total:
                    V.idx = 0
                    break

        (V.group, V.arg, V.key) = tuple(list_path[V.idx].split('.'))
        V.group_idx = list_group.index(V.group)
        V.arg_idx = list_arg.index(V.arg, V.group_idx)
        V.args = list(dict_lang["zh-CN"][V.group].keys())
        V.key_idx = list_key.index(V.key, V.arg_idx)
        V.keys = list(dict_lang["zh-CN"][V.group][V.arg].keys())

    def update_form():
        input_update('arg', options=V.args, value=V.arg)
        input_update('key', options=V.keys, value=V.key)
        for L in LANGUAGES:
            input_update(L,
                         value=deep_get(dict_lang[L],
                                        f'{V.group}.{V.arg}.{V.key}',
                                        'Key not found!'))

        old = deep_get(dict_lang[V.lang], f'{V.group}.{V.arg}.{V.key}',
                       'Key not found!')
        input_update(
            V.lang,
            value=None if V.clear else old,
            help_text=f'{V.group}.{V.arg}.{V.key}',
            placeholder=old,
        )

    def get_inputs():
        out = []
        old = deep_get(dict_lang[V.lang], f'{V.group}.{V.arg}.{V.key}',
                       'Key not found!')
        out.append(
            input(
                name=V.lang,
                label=V.lang,
                value=None if V.clear else old,
                help_text=f'{V.group}.{V.arg}.{V.key}',
                placeholder=old,
            ))
        out.append(
            select(name='group',
                   label='Group',
                   options=V.groups,
                   value=V.group,
                   onchange=lambda g: update_var(group=g),
                   required=True))
        out.append(
            select(name='arg',
                   label='Arg',
                   options=V.args,
                   value=V.arg,
                   onchange=lambda a: update_var(arg=a),
                   required=True))
        out.append(
            select(name='key',
                   label='Key',
                   options=V.keys,
                   value=V.key,
                   onchange=lambda k: update_var(key=k),
                   required=True))
        _LANGUAGES = LANGUAGES.copy()
        _LANGUAGES.remove(V.lang)
        for L in _LANGUAGES:
            out.append(
                input(name=L,
                      label=L,
                      readonly=True,
                      value=deep_get(dict_lang[L],
                                     f'{V.group}.{V.arg}.{V.key}',
                                     'Key not found!')))
        out.append(
            actions(name='action',
                    buttons=[
                        {
                            "label": "Next",
                            "value": 'Next',
                            "type": "submit",
                            "color": "success"
                        },
                        {
                            "label": "Next without save",
                            "value": 'Skip',
                            "type": "submit",
                            "color": "secondary"
                        },
                        {
                            "label": "Submit",
                            "value": "Submit",
                            "type": "submit",
                            "color": "primary"
                        },
                        {
                            "label": "Quit and save",
                            "type": "cancel",
                            "color": "secondary"
                        },
                    ]))

        return out

    def save():
        for LANG in LANGUAGES:
            d = read_file(filepath_i18n(LANG))
            for k in modified[LANG].keys():
                deep_set(d, k, modified[LANG][k])
            write_file(filepath_i18n(LANG), d)

    defer_call(save)

    def loop():
        while True:
            data = input_group(inputs=get_inputs())
            if data is None:
                save()
                break

            if data['action'] == 'Next':

                modified[V.lang][f'{V.group}.{V.arg}.{V.key}'] = data[
                    V.lang].replace("\\n", "\n")
                deep_set(dict_lang[V.lang], f'{V.group}.{V.arg}.{V.key}',
                         data[V.lang].replace("\\n", "\n"))
                next_key()
            if data['action'] == 'Skip':
                next_key()
            elif data['action'] == 'Submit':

                modified[V.lang][f'{V.group}.{V.arg}.{V.key}'] = data[
                    V.lang].replace("\\n", "\n")
                deep_set(dict_lang[V.lang], f'{V.group}.{V.arg}.{V.key}',
                         data[V.lang].replace("\\n", "\n"))
                continue

    def setting():
        data = input_group(inputs=[
            select(name='language',
                   label='Language',
                   options=LANGUAGES,
                   value=V.lang,
                   required=True),
            checkbox(
                name='check',
                label='Other settings',
                options=[{
                    "label": 'Button [Next] only shows untranslated key',
                    'value': 'untranslated',
                    'selected': V.untranslated_only
                }, {
                    "label":
                    'Do not fill input with old value (only effect the language you selected)',
                    "value": "clear",
                    "selected": V.clear
                }])
        ])
        V.lang = data['language']
        V.untranslated_only = True if 'untranslated' in data['check'] else False
        V.clear = True if 'clear' in data['check'] else False

    put_buttons([{
        "label": "Start",
        "value": "start"
    }, {
        "label": "Setting",
        "value": "setting"
    }],
                onclick=[loop, setting])
    next_key()
    setting()
    hold()