Esempio n. 1
0
    def show(self) -> None:
        self._show()
        self.init_aside(name="Home")
        self.set_aside()
        self.collapse_menu()
        self.alas_name = ""
        if hasattr(self, "alas"):
            del self.alas
        self.set_status(0)

        def set_language(l):
            lang.set_language(l)
            self.show()

        def set_theme(t):
            self.set_theme(t)
            run_js("location.reload()")

        with use_scope("content"):
            put_text("Select your language / 选择语言").style("text-align: center")
            put_buttons(
                [
                    {"label": "简体中文", "value": "zh-CN"},
                    {"label": "繁體中文", "value": "zh-TW"},
                    {"label": "English", "value": "en-US"},
                    {"label": "日本語", "value": "ja-JP"},
                ],
                onclick=lambda l: set_language(l),
            ).style("text-align: center")
            put_text("Change theme / 更改主题").style("text-align: center")
            put_buttons(
                [
                    {"label": "Light", "value": "default", "color": "light"},
                    {"label": "Dark", "value": "dark", "color": "dark"},
                ],
                onclick=lambda t: set_theme(t),
            ).style("text-align: center")

            # show something
            put_markdown(
                """
            Alas is a free open source software, if you paid for Alas from any channel, please refund.
            Alas 是一款免费开源软件,如果你在任何渠道付费购买了Alas,请退款。
            Project repository 项目地址:`https://github.com/LmeSzinc/AzurLaneAutoScript`
            """
            ).style("text-align: center")

        if lang.TRANSLATE_MODE:
            lang.reload()

            def _disable():
                lang.TRANSLATE_MODE = False
                self.show()

            toast(
                _t("Gui.Toast.DisableTranslateMode"),
                duration=0,
                position="right",
                onclick=_disable,
            )
Esempio n. 2
0
 def _force_restart():
     if State.restart_event is not None:
         toast("Alas will restart in 3 seconds", duration=0, color="error")
         clearup()
         State.restart_event.set()
     else:
         toast("Reload not enabled", color="error")
Esempio n. 3
0
async def main():
    """PyWebIO聊天室
    和当前所有在线的人聊天
    """
    global chat_msgs
    # run_js("alert('233')")
    put_markdown(
        "## PyWebIO聊天室\n欢迎来到聊天室,你可以和当前所有在线的人聊天。你可以在浏览器的多个标签页中打开本页面来测试聊天效果。"
        "本应用使用不到80行代码实现,源代码[链接](https://github.com/wang0618/PyWebIO/blob/dev/demos/chat_room.py)",
        lstrip=True)

    msg_box = output()
    put_scrollable(msg_box, height=300, keep_bottom=True)
    nickname = await input("请输入你的昵称",
                           required=True,
                           validate=lambda n: '昵称已被使用'
                           if n in online_users or n == '📢' else None)

    online_users.add(nickname)
    chat_msgs.append(
        ('📢', '`%s`加入聊天室. 当前在线人数 %s' % (nickname, len(online_users))))
    msg_box.append(
        put_markdown('`📢`: `%s`加入聊天室. 当前在线人数 %s' %
                     (nickname, len(online_users))))

    @defer_call
    def on_close():
        online_users.remove(nickname)
        chat_msgs.append(
            ('📢', '`%s`退出聊天室. 当前在线人数 %s' % (nickname, len(online_users))))

    refresh_task = run_async(refresh_msg(nickname, msg_box))

    while True:
        data = await input_group(
            '发送消息', [
                input(name='msg', help_text='消息内容支持行内Markdown语法'),
                actions(
                    name='cmd',
                    buttons=['发送', '多行输入', {
                        'label': '退出',
                        'type': 'cancel'
                    }])
            ],
            validate=lambda d: ('msg', '消息不为空')
            if d['cmd'] == '发送' and not d['msg'] else None)
        if data is None:
            break
        if data['cmd'] == '多行输入':
            data['msg'] = '\n' + await textarea(
                '消息内容', help_text='消息内容支持Markdown语法', required=True)
        msg_box.append(
            put_markdown('`%s`: %s' % (nickname, data['msg']), sanitize=True))
        msg_box.append(put_markdown(str(chat_msgs), sanitize=True))
        chat_msgs.append((nickname, data['msg']))

    refresh_task.close()
    toast("你已经退出聊天室")
Esempio n. 4
0
def login(password):
    if get_localstorage("password") == str(password):
        return True
    pwd = input(label="Please login below.",
                type=PASSWORD,
                placeholder="PASSWORD")
    if str(pwd) == str(password):
        set_localstorage("password", str(pwd))
        return True
    else:
        toast("Wrong password!", color="error")
        return False
Esempio n. 5
0
def login(password):
    if get_localstorage('password') == password:
        return True
    pwd = input(label='Please login below.',
                type=PASSWORD,
                placeholder='PASSWORD')
    if pwd == password:
        set_localstorage('password', pwd)
        return True
    else:
        toast('Wrong password!', color='error')
        return False
Esempio n. 6
0
 def _alas_thread_update_config(self) -> None:
     modified = {}
     valid = []
     invalid = []
     while self.alive:
         try:
             d = self.modified_config_queue.get(timeout=10)
             config_name = self.alas_name
         except queue.Empty:
             continue
         modified[self.idx_to_path[d["name"]]] = parse_pin_value(d["value"])
         while True:
             try:
                 d = self.modified_config_queue.get(timeout=1)
                 modified[self.idx_to_path[d["name"]]] = parse_pin_value(
                     d["value"])
             except queue.Empty:
                 config = read_file(filepath_config(config_name))
                 for k, v in modified.copy().items():
                     validate = deep_get(self.ALAS_ARGS, k + ".validate")
                     if not len(str(v)):
                         default = deep_get(self.ALAS_ARGS, k + ".value")
                         deep_set(config, k, default)
                         valid.append(self.path_to_idx[k])
                         modified[k] = default
                     elif not validate or re_fullmatch(validate, v):
                         deep_set(config, k, v)
                         valid.append(self.path_to_idx[k])
                     else:
                         modified.pop(k)
                         invalid.append(self.path_to_idx[k])
                         logger.warning(
                             f"Invalid value {v} for key {k}, skip saving.")
                         # toast(t("Gui.Toast.InvalidConfigValue").format(
                         #       t('.'.join(k.split('.')[1:] + ['name']))),
                         #       duration=0, position='right', color='warn')
                 self.pin_remove_invalid_mark(valid)
                 self.pin_set_invalid_mark(invalid)
                 if modified:
                     toast(
                         t("Gui.Toast.ConfigSaved"),
                         duration=1,
                         position="right",
                         color="success",
                     )
                     logger.info(
                         f"Save config {filepath_config(config_name)}, {dict_to_kv(modified)}"
                     )
                     write_file(filepath_config(config_name), config)
                 modified.clear()
                 valid.clear()
                 invalid.clear()
                 break
Esempio n. 7
0
    def _save_config(self, modified: Dict[str, str], config_name: str) -> None:
        try:
            valid = []
            invalid = []
            config = State.config_updater.read_file(config_name)
            for k, v in modified.copy().items():
                valuetype = deep_get(self.ALAS_ARGS, k + ".valuetype")
                v = parse_pin_value(v, valuetype)
                validate = deep_get(self.ALAS_ARGS, k + ".validate")
                if not len(str(v)):
                    default = deep_get(self.ALAS_ARGS, k + ".value")
                    deep_set(config, k, default)
                    valid.append(self.path_to_idx[k])
                    modified[k] = default
                elif not validate or re_fullmatch(validate, v):
                    deep_set(config, k, v)
                    valid.append(self.path_to_idx[k])

                    # update Emotion Record if Emotion Value is changed
                    if "Emotion" in k and "Value" in k:
                        k = k.split(".")
                        k[-1] = k[-1].replace("Value", "Record")
                        k = ".".join(k)
                        v = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                        modified[k] = v
                        deep_set(config, k, v)
                        valid.append(self.path_to_idx[k])
                        pin[self.path_to_idx[k]] = v
                else:
                    modified.pop(k)
                    invalid.append(self.path_to_idx[k])
                    logger.warning(f"Invalid value {v} for key {k}, skip saving.")
            self.pin_remove_invalid_mark(valid)
            self.pin_set_invalid_mark(invalid)
            if modified:
                toast(
                    t("Gui.Toast.ConfigSaved"),
                    duration=1,
                    position="right",
                    color="success",
                )
                logger.info(
                    f"Save config {filepath_config(config_name)}, {dict_to_kv(modified)}"
                )
                State.config_updater.write_file(config_name, config)
        except Exception as e:
            logger.exception(e)
Esempio n. 8
0
    def run(self) -> None:
        # setup gui
        set_env(title="Alas", output_animation=False)
        add_css(filepath_css('alas'))
        if self.is_mobile:
            add_css(filepath_css('alas-mobile'))
        else:
            add_css(filepath_css('alas-pc'))

        if self.theme == 'dark':
            add_css(filepath_css('dark-alas'))
        else:
            add_css(filepath_css('light-alas'))

        # Auto refresh when lost connection
        # [For develop] Disable by run `reload=0` in console
        run_js('''
        reload = 1;
        WebIO._state.CurrentSession.on_session_close(
            ()=>{
                setTimeout(
                    ()=>{
                        if (reload == 1){
                            location.reload();
                        }
                    }, 4000
                )
            }
        );
        ''')

        aside = get_localstorage('aside')
        self.show()

        # detect config change
        _thread_wait_config_change = Thread(
            target=self._alas_thread_wait_config_change)
        register_thread(_thread_wait_config_change)
        _thread_wait_config_change.start()

        # save config
        _thread_save_config = Thread(target=self._alas_thread_update_config)
        register_thread(_thread_save_config)
        _thread_save_config.start()

        visibility_state_switch = Switch(status={
            True: [
                lambda: self.__setattr__('visible', True),
                lambda: self.alas_update_overiew_task()
                if self.page == 'Overview' else 0,
                lambda: self.task_handler._task.__setattr__('delay', 15)
            ],
            False: [
                lambda: self.__setattr__('visible', False),
                lambda: self.task_handler._task.__setattr__('delay', 1)
            ]
        },
                                         get_state=get_window_visibility_state,
                                         name='visibility_state')

        self.state_switch = Switch(
            status=self.set_status,
            get_state=lambda: getattr(getattr(self, 'alas', -1), 'state', 0),
            name='state')

        def goto_update():
            self.ui_develop()
            self.dev_update()

        update_switch = Switch(status={
            1:
            lambda: toast(t("Gui.Toast.ClickToUpdate"),
                          duration=0,
                          position='right',
                          color='success',
                          onclick=goto_update)
        },
                               get_state=lambda: updater.state,
                               name='update_state')

        self.task_handler.add(self.state_switch.g(), 2)
        self.task_handler.add(visibility_state_switch.g(), 15)
        self.task_handler.add(update_switch.g(), 1)
        self.task_handler.start()

        # Return to previous page
        if aside not in ["Develop", "Home", None]:
            self.ui_alas(aside)
def show_text():
    pout.toast("Button is clicked!", duration=10)
#
# pout.put_code("""pin.select("Who's GOAT in NBA?", options=["Bryant", "Jordan", "James"])""")
# pin.select("Who's GOAT in NBA?", options=["Bryant", "Jordan", "James"])
#
# pout.put_code("""pin.radio("Are you ready to try pyWebIO?", options=["Yes", "No"])""")
# pin.radio("Are you ready to try pyWebIO?", options=["Yes", "No"])

pout.put_text("This is an awesome library.")

pout.put_table([("Col 1 Title", "Col 2 Title"),
                ("Row 1, Col 1", "Row 1, Col 2"),
                ("Row 2, Col 1", "Row 2, Col2")])

pout.put_markdown("# This is the Title")
pout.put_markdown("## This is the Subtitle")
pout.put_markdown("_Bold Text_")
pout.put_markdown("__Italic Text__")
pout.put_markdown("*__Bold & Italic__*")
pout.put_markdown("[google.com](google.com)")

pout.put_image(open("airplane.jpg", "rb").read())
pout.toast("Please Pay Attention!", duration=10)


def show_text():
    pout.toast("Button is clicked!", duration=10)


pout.put_button("I'm Ready!", onclick=show_text)
pout.toast("test")