Example #1
0
def main():
    set_env(title="FlyOS Panel", auto_scroll_bottom=True)
    put_html("<h1>FlyOS WEB Panel</h1>")
    put_text('FlyOS Panel By:XingYuJie', sep=' ')
    popup(
        '欢迎使用FlyOS Panel!', '欢迎使用FlyOS WEB Panel!'
        '如果程序有Bug,'
        '请务必提交到邮箱:[email protected]谢谢!'
        '程序由MicroTech Projects -- FlyOS强力驱动')
    put_link("web终端", url=f'http://{get_host_ip()}:7681')
    put_text('_______________________', sep=' ')
    put_link("VM虚拟机", url=f'http://{get_host_ip()}:8002')
    put_text('_______________________', sep=' ')
    put_link("vscode", url=f'http://{get_host_ip()}:2001')
    put_text('_______________________', sep=' ')
    put_link("Apache主页", url=f'http://{get_host_ip()}:8080')
    put_text('_______________________', sep=' ')
    put_link("Nginx主页", url=f'http://{get_host_ip()}:8088')
    put_text('_______________________', sep=' ')
    put_link("HTTP文件服务器", url=f'http://{get_host_ip()}:8081')
    put_text('_______________________', sep=' ')
    put_link("jupyter notebook", url=f'http://{get_host_ip()}:2000')
    put_text('_______________________', sep=' ')
    put_link("FlyOS桌面环境", url=f'http://{get_host_ip()}:6081/vnc.html')
    put_text('_________系统工具__________', sep=' ')
    put_link("FlyOS AM调用 ", url=f'http://{get_host_ip()}:5000')
    put_text('_______________________', sep=' ')
    put_link("FlyOS Termux:API调用 ", url=f'http://{get_host_ip()}:5002')
Example #2
0
def main():
    set_env(title="FlyOS Panel",
            auto_scroll_bottom=True
        )
    put_html("<h1>FlyOS WEB Panel</h1>")
    put_text('FlyOS Panel By:XingYuJie',
            sep=' '
        )
    popup('欢迎使用FlyOS Panel!',
            '欢迎使用FlyOS WEB Panel!'
            '如果程序有Bug,'
            '请务必提交到邮箱:[email protected]谢谢!'
            '程序由MicroTech Projects -- FlyOS强力驱动'
        )
    put_link("本地WEB终端",
            url='http://127.0.0.1:4200'
        )
    put_text('_______________________',
            sep=' '
        )
    put_link("VM虚拟机",
            url='http://127.0.0.1:8002'
        )
    put_text('_______________________',
            sep=' '
        )
    put_link("Apache主页",
            url='http://127.0.0.1:8080'
        )
    put_text('_______________________',
            sep=' '
        )
    put_link("Nginx主页",
            url='http://127.0.0.1:8088'
        )
    put_text('_______________________',
            sep=' '
        )
    put_link("HTTP文件服务器",
            url='http://127.0.0.1:8081'
        )
    put_text('_______________________',
            sep=' '
        )
    put_link("FlyOS RunShell Tool",
            url='http://127.0.0.1:8887'
        )
    put_text('_________系统工具__________',
            sep=' '
        )
    put_link("FlyOS AM调用 ",
            url='http://127.0.0.1:5000'
        )
    put_text('_______________________',
            sep=' '
        )
    put_link("FlyOS Termux:API调用 ",
            url='http://127.0.0.1:5002'
            )
Example #3
0
def target():
    set_env(auto_scroll_bottom=True)
    template.set_defer_call()

    template.basic_output()
    template.background_output()

    run_as_function(template.basic_input())
    actions(buttons=['Continue'])
    template.background_input()
Example #4
0
def task_func():
    set_env(title="Ref Expander")
    put_markdown('本页面可以将压缩位号(U5-U10)转换为未压缩的位号(U5,U6,U7,U8,U9,U10)。')
    str2process = textarea('输入压缩位号:', rows=15, placeholder='可多行,行内逗号分割。')
    lines = str2process.split('\n')
    for i, line in enumerate(lines):
        lines[i] = expand_line(line)
    expanded_lines = '\n'.join(lines)
    put_markdown('未压缩的位号为:')
    put_markdown(expanded_lines)
Example #5
0
def main():
    set_env(title="FlyOS Panel", auto_scroll_bottom=True)
    put_html("<h1>FlyOS WEB Panel</h1>")
    put_text('FlyOS RunShellTool By:XingYuJie', sep=' ')
    runshell = pywebio.input.input("Shell终端命令执行" "请输入要执行的命令(会在后台执行):")
    fastrun = pywebio.input.input("FlyOS快速运行程序(已在FlyOS环境下):")
    #启动FlyOSfastrun
    os.system("python $FLYOS" + fastrun)
    print("你输入的命令(结果在下方): %s" % runshell)
    #使用runshell
    os.system(runshell)
Example #6
0
def main():
    set_env(title="FlyOS Devices API Tool", auto_scroll_bottom=True)
    put_markdown(r"""
    <h1>FlyOS Devices API Tool</h1>
    """,
                 strip_indent=4)
    api = pywebio.input.input("输入api调用接口:")
    termux = "termux-" + api
    os.system(termux)
    print("继续使用请刷新页面")
    hold()
Example #7
0
def main():
    set_env(title="Linux  部署程序--中文版", auto_scroll_bottom=True)
    put_html("<h1>FlyOS Linux Deploy</h1>")
    put_text("By:FlyOS MicroTech XingYuJie(严禁删除版权,不允许修改版权)GPL-V3", sep=" ")
    popup(
        "欢迎使用Linux部署程序--中文版",
        "欢迎使用Linux部署程序--中文版。"
        "开始部署你的Linux吧!"
        "程序由MicroTech Projects -- FlyOS强力驱动",
    )
    Main()
Example #8
0
async def main():
    global chat_msgs

    set_env(title="PyWebIO Chat Room")

    put_markdown(
        "##PyWebIO聊天室\n欢迎来到聊天室,你可以和当前所有在线的人聊天。你可以在浏览器的多个标签页中打开本页面来测试聊天效果。"
        "本应用使用不到80行代码实现,源代码[链接](https://github.com/wang0618/PyWebIO/blob/dev/demos/chat_room.py)",
        lstrip=True)

    msg_box = output()
    with use_scope('msg-container'):
        style(put_scrollable(msg_box, max_height=300), 'height:300px')
    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 语法', required=True),
            actions(name='cmd',
                    buttons=['发送', {
                        'label': '退出',
                        'type': 'cancel'
                    }])
        ])
        if data is None:
            break

        msg_box.append(put_markdown('`%s`: %s' % (nickname, data['msg'])))
        run_js(
            '$("#pywebio-scope-msg-container>div").animate({ scrollTop: $("#pywebio-scope-msg-container>div").prop("scrollHeight")}, 1000)'
        )  # hack: to scroll bottom
        chat_msgs.append((nickname, data['msg']))

    refresh_task.close()
    toast("你已经退出聊天室")
Example #9
0
def main():
    set_env(title="FlyOS Phone Shell", auto_scroll_bottom=True)
    put_markdown(r"""
    <h1>FlyOS WEB Phone Shell</h1>
    """,
                 strip_indent=4)
    put_text('FlyOS Phone Web Shell By:XingYuJie',
             sep=' ',
             inline=False,
             scope=-1,
             position=-1)
    am = pywebio.input.input("请输入AM参数加命令:")
    os.system("am " + am)
    hold()
Example #10
0
def main():
    """主方法"""
    if not os.path.exists(FLYOS_ROOT + "/.firstuse/lock"):
        set_env(title="欢迎使用FlyOS", auto_scroll_bottom=True)
        put_html("<h1>欢迎使用! -- FlyOS 初始化向导</h1>")
        put_text('欢迎使用FlyOS!开始初始化您的FlyOS吧!')
        popup('Hi,There!欢迎使用FlyOS!让我们来初始化FlyOS吧!')

        password = pywebio.input.input("设置您的系统密码:", type="password")
        vpwd = pywebio.input.input("请再次输入密码验证:", type="password")
        if password != vpwd:
            popup('错误', "两次输入密码不一致,请刷新页面重试")
            return
        put_text('初始化完成!请进入termuxAPP开始体验FlyOS吧!')
        termux_auth.change_passwd(password)
        os.mkdir(f"{HOME}/.flyos")
    os.kill(os.getpid(), 9)
Example #11
0
def main():
    set_env(title="FlyOS Devices API Tool", auto_scroll_bottom=True)
    put_html("<h1>FlyOS Devices API Tool</h1>")
    pwd = pywebio.input.input("输入flyos密码: ")
    if termux_auth.auth(pwd):
        while 1:
            api = pywebio.input.input("输入api调用接口:")
            if re.search('[;&|<>$]', api):
                popup('检测到非法字符', content="请检查命令中是否包含;&|等特殊字符")
                continue
            status, output = subprocess.getstatusoutput(f'termux-{api}')
            if status == 0:
                popup('命令已执行', output)
            else:
                popup('执行时出现错误', output)
    else:
        put_text("密码错误, 请刷新页面重试")
Example #12
0
def main():
    set_env(title="Linux  部署程序--中文版", auto_scroll_bottom=True)
    put_html("<h1>FlyOS Linux Deploy</h1>")
    put_text("By:FlyOS MicroTech XingYuJie(严禁删除版权,不允许修改版权)GPL-V3", sep=" ")
    popup(
        "欢迎使用Linux部署程序--中文版",
        "欢迎使用Linux部署程序--中文版。"
        "开始部署你的Linux吧!"
        "程序由MicroTech Projects -- FlyOS强力驱动",
    )
    n = pywebio.input.select(
        "请选择你要执行的操作",
        options=[
            ("安装Linux", 1, True),
            ("进入Linux", 2),
        ],
    )
    if n == 1:
        name = pywebio.input.input("请输入该系统的名字")
        command = pywebio.input.radio(
            "请选择要用的命令",
            [
                ("PRoot(无root下使用)", "proot -r ", True),
                ("chroot(有root建议使用)", "sudo chroot "),
            ],
        )
        arch = subprocess.getoutput("dpkg --print-architecture")
        num = pywebio.input.select(
            "请选择你要安装的系统",
            options=[
                ("Ubuntu", 1, True),
                ("CentOS", 2),
                ("Kali", 3),
            ],
        )
        if num == 1:
            get_ubuntu(name, arch, command)
        elif num == 2:
            get_centos(name, arch, command)
        elif num == 3:
            get_kali(name, arch, command)
    elif n == 2:
        join()
    elif n == 3:
        delete()
Example #13
0
def main():
    set_env(title="FlyOS Virtual Machine", auto_scroll_bottom=True)
    put_html("<h1>FlyOS WEB Virtual Machine</h1>")
    put_text('FlyOS Virtual Machine By:XingYuJie', sep=' ')
    popup(
        '欢迎使用FlyOS FlyOS Virtual Machine!', '欢迎使用FlyOS Virtual Machine。'
        '开始创建您的虚拟机吧!'
        '程序由MicroTech Projects -- FlyOS强力驱动')
    cpu = pywebio.input.input("请输入架构,例如i386架构:")
    path = pywebio.input.input("请输入虚拟机磁盘镜像完整绝对路径:")
    memory = pywebio.input.input("请输入虚拟机内存(不建议太大):")
    network = pywebio.input.input("请输入网卡驱动(建议rtl8139):")
    vga = pywebio.input.input("请输入显卡驱动(建议vmware):")
    vnc = pywebio.input.input("输入VNC端口号(建议0):")
    qemu = f"qemu-system-{cpu} "
    qemu += f"-hda {path} -m {memory} -device {network} "
    qemu += f"-vga {vga} -vnc :{vnc}"
    os.system(qemu)
Example #14
0
def main():
    set_env(title="FlyOS Phone Shell", auto_scroll_bottom=True)
    put_html("<h1>FlyOS WEB Phone Shell</h1>")
    put_text('FlyOS Phone Web Shell By:XingYuJie', sep=' ')
    pwd = pywebio.input.input("输入flyos密码:")
    if termux_auth.auth(pwd):
        while 1:
            command = pywebio.input.input("请输入AM参数加命令:")
            if re.search('[;&|<>$]', command):
                popup('检测到非法字符', content="请检查命令中是否包含;&|等特殊字符")
                continue
            status, output = subprocess.getstatusoutput("am " + command)
            if status == 0:
                popup('命令已执行', output)
            else:
                popup('命令执行时出现错误', output)
    else:
        put_text("密码错误,请刷新页面重试")
Example #15
0
def main():
    set_env(title="FlyOS Virtual Machine", auto_scroll_bottom=True)
    put_markdown(r"""
    <h1>FlyOS WEB Virtual Machine</h1>
    """, strip_indent=4)
    put_text('FlyOS Virtual Machine By:XingYuJie', sep=' ', inline=False, scope=- 1, position=- 1)
    output.popup('欢迎使用FlyOS FlyOS Virtual Machine!', '欢迎使用FlyOS Virtual Machine。开始创建您的虚拟机吧!程序由MicroTech Projects -- FlyOS强力驱动')
  
    name = pywebio.input.input("请输入虚拟机的名称:")
    cpu = pywebio.input.input("请输入架构,例如i386架构:")
    path = pywebio.input.input("请输入虚拟机磁盘镜像完整绝对路径:")
    memory = pywebio.input.input("请输入虚拟机内存(不建议太大):")
    network = pywebio.input.input("请输入网卡驱动(建议rtl8139):")
    vga = pywebio.input.input("请输入显卡驱动(建议vmware):")
    vnc = pywebio.input.input("输入VNC端口号(建议0):")
  
    qemu = "qemu-system-" + cpu + " -hda " + path + " -m " + memory + " -device " + network + " -vga " + vga + " -vnc :" + vnc
    os.system(qemu)
    hold()
Example #16
0
def main():
    set_env(title="FlyOS初始化向导", auto_scroll_bottom=True)
    put_markdown(r"""
    <h1>FlyOS 初始化向导</h1>
    """, strip_indent=4)
    put_text('欢迎使用FlyOS!开始设置您的FlyOS吧!',
             sep=' ',
             inline=False,
             scope=-1,
             position=-1)
    output.popup('Hi,There!Welcome To Use FlyOS,Now activate your system.')
    put_text('您好,您的FlyOS尚未激活,请根据以下提示来激活您的FlyOS系统',
             sep=' ',
             inline=False,
             scope=-1,
             position=-1)
    pywebio.output.put_link("1.首先进入FlyOS激活官网获取设备密钥(点此进入)",
                            url='http://flyos.club',
                            app=None,
                            new_window=False,
                            scope=-1,
                            position=-1)
    put_text('_______________________',
             sep=' ',
             inline=False,
             scope=-1,
             position=-1)
    pywebio.output.put_link(
        "2.下载FlyOS激活系统(点此下载),然后安装打开,输入密钥并激活",
        url=
        'https://assets.huoyinetwork.cn/Flyos/Activate/FlyOS_Activate_Pro_1.5.apk',
        app=None,
        new_window=False,
        scope=-1,
        position=-1)
    put_text('_______________________',
             sep=' ',
             inline=False,
             scope=-1,
             position=-1)
    put_text('3.完全退出并重新打开Termux', sep=' ', inline=False, scope=-1, position=-1)
    hold()
Example #17
0
 def __init__(self):
     env = os.getenv('FLYOS')
     if env is None:
         env = '.'
     self.__path = os.path.abspath(env + '/virtualmachine')
     if not os.path.exists(os.path.abspath(self.__path + "/vms")):
         os.mkdir(os.path.abspath(self.__path + "/vms"))
     set_env(title="FlyOS Virtual Machine", auto_scroll_bottom=True)
     put_html("<h1>FlyOS WEB Virtual Machine</h1>")
     put_text("FlyOS Virtual Machine By:XingYuJie", sep=" ")
     popup(
         "欢迎使用FlyOS FlyOS Virtual Machine!",
         "欢迎使用FlyOS Virtual Machine。"
         "开始创建您的虚拟机吧!"
         "程序由MicroTech Projects -- FlyOS强力驱动",
     )
     pwd = pywebio.input.input("输入flyos密码:")
     if termux_auth.auth(pwd):
         self.__run()
     else:
         popup("密码错误,请刷新页面重试")
Example #18
0
def main():
    set_env(title="FlyOS Panel", auto_scroll_bottom=True)
    put_markdown(r"""
    <h1>FlyOS WEB Panel</h1>
    """, strip_indent=4)
    put_text('FlyOS RunShellTool By:XingYuJie',
             sep=' ',
             inline=False,
             scope=-1,
             position=-1)

    runshell = pywebio.input.input("Shell终端命令执行,请输入要执行的命令(会在后台执行):",
                                   lstrip=True)
    fastrun = pywebio.input.input("FlyOS快速运行程序(已在FlyOS环境下):")
    #启动FlyOSfastrun
    os.system("python $FLYOS" + fastrun)
    #结束Fastrun
    hold()
    print("你输入的命令(结果在下方): %s" % runshell)
    #使用runshell
    os.system(runshell)
    hold()
Example #19
0
def main():
    set_env(title="BMI Calculation")

    put_markdown("""# BMI指数

    [`BMI指数`](https://baike.baidu.com/item/%E4%BD%93%E8%B4%A8%E6%8C%87%E6%95%B0/1455733)(Body Mass Index,BMI),是用体重千克数除以身高米数的平方得出的数字,是国际上常用的衡量人体胖瘦程度以及是否健康的一个标准。
    
    成年人的BMI值处于以下阶段
    
    | 体形分类 | BMI值范围 |
    | -------- | --------- |
    | 极瘦   | BMI<14.9    |
    | 偏瘦    | 14.9≤BMI<18.4     |
    | 正常    | 18.4≤BMI<22.9     |
    | 过重    |  22.9≤BMI<27.5  |
    | 肥胖    |  27.5≤BMI<40  |
    | 非常肥胖 |     BMI≥40      |
    
    ## BMI指数计算器
    本程序的源代码[链接](https://github.com/wang0618/PyWebIO/blob/dev/demos/bmi.py)
    
    """,
                 strip_indent=4)

    info = input_group('计算BMI:', [
        input("请输入你的身高(cm)", name="height", type=FLOAT),
        input("请输入你的体重(kg)", name="weight", type=FLOAT),
    ])

    BMI = info['weight'] / (info['height'] / 100)**2

    top_status = [(14.9, '极瘦'), (18.4, '偏瘦'), (22.9, '正常'), (27.5, '过重'),
                  (40.0, '肥胖'), (float('inf'), '非常肥胖')]

    for top, status in top_status:
        if BMI <= top:
            put_markdown('你的 BMI 值: `%.1f`,身体状态:`%s`' % (BMI, status))
            break
Example #20
0
def main():
    set_env(title="FlyOS Panel", auto_scroll_bottom=True)
    put_markdown(r"""
    <h1>FlyOS WEB Panel</h1>
    """, strip_indent=4)
    put_text('FlyOS Panel By:XingYuJie', sep=' ', inline=False, scope=- 1, position=- 1)
    output.popup('欢迎使用FlyOS Panel!', '欢迎使用FlyOS WEB Panel!如果程序有Bug,请务必提交到邮箱:[email protected]谢谢!程序由MicroTech Projects -- FlyOS强力驱动')
    pywebio.output.put_link("本地WEB终端", url='http://127.0.0.1:4200', app=None, new_window=False, scope=- 1, position=- 1)
    put_text('_______________________', sep=' ', inline=False, scope=- 1, position=- 1)
    pywebio.output.put_link("VM虚拟机", url='http://127.0.0.1:8002', app=None, new_window=False, scope=- 1, position=- 1)
    put_text('_______________________', sep=' ', inline=False, scope=- 1, position=- 1)
    pywebio.output.put_link("Apache主页", url='http://127.0.0.1:8080', app=None, new_window=False, scope=- 1, position=- 1)
    put_text('_______________________', sep=' ', inline=False, scope=- 1, position=- 1)
    pywebio.output.put_link("Nginx主页", url='http://127.0.0.1:8088', app=None, new_window=False, scope=- 1, position=- 1)
    put_text('_______________________', sep=' ', inline=False, scope=- 1, position=- 1)
    pywebio.output.put_link("HTTP文件服务器", url='http://127.0.0.1:8081', app=None, new_window=False, scope=- 1, position=- 1)
    put_text('_______________________', sep=' ', inline=False, scope=- 1, position=- 1)
    pywebio.output.put_link("FlyOS RunShell Tool", url='http://127.0.0.1:8887', app=None, new_window=False, scope=- 1, position=- 1)
    put_text('_________系统工具__________', sep=' ', inline=False, scope=- 1, position=- 1)
    pywebio.output.put_link("FlyOS AM调用 ", url='http://127.0.0.1:5000', app=None, new_window=False, scope=- 1, position=- 1)
    put_text('_______________________', sep=' ', inline=False, scope=- 1, position=- 1)
    pywebio.output.put_link("FlyOS Termux:API调用 ", url='http://127.0.0.1:5002', app=None, new_window=False, scope=- 1, position=- 1)
    hold()
Example #21
0
def main():
    """主方法"""
    if not os.path.exists(FLYOS_ROOT + "/.firstuse/lock"):
        set_env(title="欢迎使用FlyOS", auto_scroll_bottom=True)
        put_html("<h1>欢迎使用! -- FlyOS 初始化向导</h1>")
        put_text('欢迎使用FlyOS!开始初始化您的FlyOS吧!')
        popup('Hi,There!欢迎使用FlyOS!让我们来初始化FlyOS吧!')
        password = pywebio.input.input("设置您的系统开机密码:", type="password")
        vpwd = pywebio.input.input("请再次输入密码验证:", type="password")
        if password != vpwd:
            popup('错误', "两次输入密码不一致,请刷新页面重试")
            return
        put_text('初始化完成!请进入termuxAPP开始体验FlyOS吧!')
        termux_auth.change_passwd(password)
    try:
        os.mkdir(f"{HOME}/.flyos")
    except FileExistsError:
        pass
    conn = sqlite3.connect(f'{HOME}/.flyos/service.db')
    cur = conn.cursor()
    cur.execute('''CREATE TABLE boot (
        ID INTEGER PRIMARY KEY NOT NULL,
        command           TEXT    NOT NULL,
        status            INT     NOT NULL
        );''')
    cur.execute('''CREATE TABLE login (
        ID INTEGER PRIMARY KEY NOT NULL,
        command           TEXT    NOT NULL,
        status            INT     NOT NULL
        );''')
    cur.execute('''INSERT INTO boot (command, status) VALUES (
        "ttyd pwlogin", 1
    )''')
    cur.execute(f'''INSERT INTO boot (command, status) VALUES (
        "python {FLYOS_ROOT}/panel/server.py", 1
    )''')
    cur.execute('''INSERT INTO boot (command, status) VALUES (
        "apachectl start", 1
    )''')
    cur.execute(f'''INSERT INTO boot (command, status) VALUES (
        "python {FLYOS_ROOT}/virtualmachine/web.py", 1
    )''')
    cur.execute('''INSERT INTO boot (command, status) VALUES (
        "nginx", 1
    )''')
    cur.execute('''INSERT INTO boot (command, status) VALUES (
        "php-fpm", 1
    )''')
    cur.execute('''INSERT INTO boot (command, status) VALUES (
        "http-server", 1
    )''')
    cur.execute(f'''INSERT INTO boot (command, status) VALUES (
        "python {FLYOS_ROOT}/phone/web.py", 1
    )''')
    cur.execute(f'''INSERT INTO boot (command, status) VALUES (
        "python {FLYOS_ROOT}/api/web.py", 1
    )''')
    cur.execute('''INSERT INTO boot (command, status) VALUES (
        "sshd", 1
    )''')
    cur.execute('''INSERT INTO boot (command, status) VALUES(
        "jupyter notebook --ip='0.0.0.0' --port=2000 --NotebookApp.token='' --no-browser", 1
    )''')
    cur.execute('''INSERT INTO boot (command, status) VALUES(
        "termux-wake-lock", 1
    )''')
    cur.execute('''INSERT INTO boot (command, status) VALUES(
        "code-server --bind-addr 0.0.0.0:2001", 1
    )''')
    conn.commit()
    conn.close()

    os.kill(os.getpid(), 9)
Example #22
0
def main():
    """主方法"""
    if not os.path.exists(FLYOS_ROOT + "/.firstuse/lock"):
        set_env(title="欢迎使用FlyOS", auto_scroll_bottom=True)
        put_html("<h1>欢迎使用! -- FlyOS 初始化向导</h1>")
        put_text('欢迎使用FlyOS!开始初始化您的FlyOS吧!')
        popup('Hi,There!欢迎使用FlyOS!让我们来初始化FlyOS吧!')
        password = pywebio.input.input("设置您的系统开机密码:", type="password")
        vpwd = pywebio.input.input("请再次输入密码验证:", type="password")
        if password != vpwd:
            popup('错误', "两次输入密码不一致,请刷新页面重试")
            return
        put_text('初始化完成!请进入termuxAPP开始体验FlyOS吧!')
        termux_auth.change_passwd(password)
    try:
        os.mkdir(f"{HOME}/.flyos")
    except FileExistsError:
        pass
    conn = sqlite3.connect(f'{HOME}/.flyos/service.db')
    cur = conn.cursor()
    cur.execute('''CREATE TABLE boot (
        ID INTEGER PRIMARY KEY NOT NULL,
        command           TEXT    NOT NULL,
        status            INT     NOT NULL
        );''')
    cur.execute('''CREATE TABLE login (
        ID INTEGER PRIMARY KEY NOT NULL,
        command           TEXT    NOT NULL,
        status            INT     NOT NULL
        );''')
    cur.execute('''INSERT INTO boot (command, status) VALUES (
        "shellinaboxd --disable-ssl --background", 1
    )''')
    cur.execute('''INSERT INTO boot (command, status) VALUES (
        "nohup python $FLYOS/panel/server.py &", 1
    )''')
    cur.execute('''INSERT INTO boot (command, status) VALUES (
        "nohup python $FLYOS/panel/shell.py &", 1
    )''')
    cur.execute('''INSERT INTO boot (command, status) VALUES (
        "apachectl start", 1
    )''')
    cur.execute('''INSERT INTO boot (command, status) VALUES (
        "nohup python $FLYOS/virtualmachine/web.py &", 1
    )''')
    cur.execute('''INSERT INTO boot (command, status) VALUES (
        "nohup nginx &", 1
    )''')
    cur.execute('''INSERT INTO boot (command, status) VALUES (
        "nohup php-fpm &", 1
    )''')
    cur.execute('''INSERT INTO boot (command, status) VALUES (
        "nohup http-server &", 1
    )''')
    cur.execute('''INSERT INTO boot (command, status) VALUES (
        "nohup python $FLYOS/phone/web.py &", 1
    )''')
    cur.execute('''INSERT INTO boot (command, status) VALUES (
        "nohup python $FLYOS/api/web.py &", 1
    )''')
    cur.execute('''INSERT INTO boot (command, status) VALUES (
        "sshd", 1
    )''')
    conn.commit()
    conn.close()

    os.kill(os.getpid(), 9)
Example #23
0
def main():
    """PyWebIO输入演示

    演示PyWebIO支持的各种输入形式
    """
    set_env(auto_scroll_bottom=True)

    put_markdown("""# PyWebIO 输入演示
    
    在[这里](https://github.com/wang0618/PyWebIO/blob/dev/demos/input_usage.py)可以获取本Demo的源码。
    
    本Demo仅提供了PyWebIO输入模块的部分功能的演示,完整特性请参阅[用户指南](https://pywebio.readthedocs.io/zh_CN/latest/guide.html)。
    
    PyWebIO的输入函数都定义在 `pywebio.input` 模块中,可以使用 `from pywebio.input import *` 引入。

    ### 基本输入
    首先是一些基本类型的输入

    #### 文本输入
    ```python
    name = input("What's your name?")
    ```
    """,
                 lstrip=True)
    put_text("这样一行代码的效果如下:", )
    name = input("What's your name?")
    put_markdown("`name = %r`" % name)

    # 其他类型的输入
    put_markdown("""PyWebIO的输入函数是同步的,在表单被提交之前,输入函数不会返回。
    #### 其他类型的输入:
    ```python
    # 密码输入
    password = input("Input password", type=PASSWORD)
    
    # 下拉选择框
    gift = select('Which gift you want?', ['keyboard', 'ipad'])
    
    # CheckBox
    agree = checkbox("用户协议", options=['I agree to terms and conditions'])
    
    # Text Area
    text = textarea('Text Area', rows=3, placeholder='Some text')
    
    # 文件上传
    img = file_upload("Select a image:", accept="image/*")
    ```
    """,
                 lstrip=True)
    password = input("Input password", type=PASSWORD)
    put_markdown("`password = %r`" % password)
    gift = select('Which gift you want?', ['keyboard', 'ipad'])
    put_markdown("`gift = %r`" % gift)
    agree = checkbox("用户协议", options=['I agree to terms and conditions'])
    put_markdown("`agree = %r`" % agree)
    text = textarea('Text Area', rows=3, placeholder='Some text')
    put_markdown("`text = %r`" % text)
    img = file_upload("Select a image:",
                      accept="image/*",
                      help_text='可以直接选择"提交"')
    put_markdown("`img = %r`" % img)

    # 输入选项
    put_markdown("""#### 输入选项
    输入函数可指定的参数非常丰富:
    ```python
    input('This is label', type=TEXT, placeholder='This is placeholder', 
          help_text='This is help text', required=True, 
          datalist=['candidate1', 'candidate2', 'candidate2'])
    ```
    """,
                 strip_indent=4)
    input('This is label',
          type=TEXT,
          placeholder='This is placeholder',
          help_text='This is help text',
          required=True,
          datalist=['candidate1', 'candidate2', 'candidate2'])

    # 校验函数
    put_markdown("""我们可以为输入指定校验函数,校验函数校验通过时返回None,否则返回错误消息:
    ```python
    def check_age(p):  # 检验函数校验通过时返回None,否则返回错误消息
        if p < 10:
            return 'Too young!!'
        if p > 60:
            return 'Too old!!'

    age = input("How old are you?", type=NUMBER, validate=check_age)
    ```
    """,
                 strip_indent=4)

    def check_age(p):  # 检验函数校验通过时返回None,否则返回错误消息
        if p < 10:
            return 'Too young!!'
        if p > 60:
            return 'Too old!!'

    age = input("How old are you?",
                type=NUMBER,
                validate=check_age,
                help_text='尝试输入一些非法值,比如"8"、"65"')
    put_markdown('`age = %r`' % age)

    # Codemirror
    put_markdown(
        r"""PyWebIO 的 `textarea()` 输入函数还支持使用 [Codemirror](https://codemirror.net/) 实现代码风格的编辑区,只需使用 `code` 参数传入Codemirror支持的选项即可(最简单的情况是直接传入` code={}` 或 `code=True`):
    ```python
    code = textarea('Code Edit', code={
        'mode': "python",  # 编辑区代码语言
        'theme': 'darcula',  # 编辑区darcula主题
    }, value='import something\n# Write your python code')
    ```
        """,
        strip_indent=4)

    code = textarea(
        'Code Edit',
        code={
            'mode': "python",  # 编辑区代码语言
            'theme':
            'darcula',  # 编辑区darcula主题, Visit https://codemirror.net/demo/theme.html#cobalt to get more themes
        },
        value='import something\n# Write your python code')

    put_markdown("Your code:\n```python\n%s\n```" % code)

    # 输入组
    put_markdown(r"""### 输入组
    `input_group()` 接受单项输入组成的列表作为参数,输入组中需要在每一项输入函数中提供 `name` 参数来用于在结果中标识不同输入项。输入组中同样支持设置校验函数,其接受整个表单数据作为参数。

    ```python
    def check_form(data):  # 检验函数校验通过时返回None,否则返回 (input name,错误消息)
        if len(data['name']) > 6:
            return ('name', '名字太长!')
        if data['age'] <= 0:
            return ('age', '年龄不能为负数!')

    data = input_group("Basic info", [
        input('Input your name', name='name'),
        input('Input your age', name='age', type=NUMBER, validate=check_age)
    ], validate=check_form)
    ```
    """,
                 strip_indent=4)

    def check_form(data):  # 检验函数校验通过时返回None,否则返回 (input name,错误消息)
        if len(data['name']) > 6:
            return ('name', '名字太长!')
        if data['age'] <= 0:
            return ('age', '年龄不能为负数!')

    data = input_group("Basic info", [
        input('Input your name', name='name'),
        input('Input your age', name='age', type=NUMBER, validate=check_age)
    ],
                       validate=check_form)

    put_markdown("`data = %r`" % data)

    put_markdown("""----
    PyWebIO的输入演示到这里就结束了,更多内容请访问PyWebIO[用户指南](https://pywebio.readthedocs.io/zh_CN/latest/guide.html)和[input模块文档](https://pywebio.readthedocs.io/zh_CN/latest/input.html)。
    """,
                 lstrip=True)
Example #24
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)
Example #25
0
async def main():
    set_env(title="PyWebIO输出演示")

    put_markdown("""# PyWebIO 输出演示
    
    在[这里](https://github.com/wang0618/PyWebIO/blob/dev/demos/output_usage.py)可以获取本Demo的源码。
    
    本Demo仅提供了PyWebIO输出模块的部分功能的演示,完整特性请参阅[用户指南](https://pywebio.readthedocs.io/zh_CN/latest/guide.html)。
    
    PyWebIO的输出函数都定义在 `pywebio.output` 模块中,可以使用 `from pywebio.output import *` 引入。

    ### 基本输出
    PyWebIO提供了一些便捷函数来输出表格、链接等格式:
    """,
                 strip_indent=4)

    code_block(r"""
    # 文本输出
    put_text("Hello world!")

    # 表格输出
    put_table([
        ['商品', '价格'],
        ['苹果', '5.5'],
        ['香蕉', '7'],
    ])

    # Markdown输出
    put_markdown('~~删除线~~')

    # 文件输出
    put_file('hello_word.txt', b'hello word!')
    """)

    put_markdown(r"""PyWebIO提供的全部输出函数请参考PyWebIO文档
    
    ### 组合输出
    
    函数名以 `put_` 开始的输出函数,可以与一些输出函数组合使用,作为最终输出的一部分。

    比如`put_table()`支持以`put_xxx()`调用作为单元格内容:
    """,
                 strip_indent=4)

    code_block(r"""
    put_table([
        ['Type', 'Content'],
        ['html', put_html('X<sup>2</sup>')],
        ['text', '<hr/>'],  # 等价于 ['text', put_text('<hr/>')]
        ['buttons', put_buttons(['A', 'B'], onclick=toast)],  
        ['markdown', put_markdown('`Awesome PyWebIO!`')],
        ['file', put_file('hello.text', b'hello world')],
        ['table', put_table([['A', 'B'], ['C', 'D']])]
    ])
    """)

    put_markdown(r"""类似地,`popup()`也可以将`put_xxx()`调用作为弹窗内容:
    
    """,
                 strip_indent=4)

    code_block(r"""
    popup('Popup title', [
        put_html('<h3>Popup Content</h3>'),
        'plain html: <br/>',  # 等价于 put_text('plain html: <br/>')
        put_table([['A', 'B'], ['C', 'D']]),
        put_buttons(['close_popup()'], onclick=lambda _: close_popup())
    ])
    """)

    put_markdown(r"更多接受`put_xxx()`作为参数的输出函数请参考函数文档。")

    put_markdown(r"""### 事件回调
    PyWebIO允许你输出一些控件,当控件被点击时执行提供的回调函数,就像编写GUI程序一样。
    
    下面是一个例子:
    ```python
    from functools import partial

    def edit_row(choice, row):
        put_markdown("> You click`%s` button ar row `%s`" % (choice, row))

    put_table([
        ['Idx', 'Actions'],
        [1, put_buttons(['edit', 'delete'], onclick=partial(edit_row, row=1))],
        [2, put_buttons(['edit', 'delete'], onclick=partial(edit_row, row=2))],
        [3, put_buttons(['edit', 'delete'], onclick=partial(edit_row, row=3))],
    ])
    ```
    `put_table()`的调用不会阻塞。当用户点击了某行中的按钮时,PyWebIO会自动调用相应的回调函数:
    
    """,
                 strip_indent=4)

    from functools import partial

    @use_scope('table-callback')
    def edit_row(choice, row):
        put_markdown("> You click `%s` button ar row `%s`" % (choice, row))

    put_table([
        ['Idx', 'Actions'],
        [1,
         put_buttons(['edit', 'delete'], onclick=partial(edit_row, row=1))],
        [2,
         put_buttons(['edit', 'delete'], onclick=partial(edit_row, row=2))],
        [3,
         put_buttons(['edit', 'delete'], onclick=partial(edit_row, row=3))],
    ])
    set_scope('table-callback')

    put_markdown(r"""当然,PyWebIO还支持单独的按钮控件:
    ```python
    def btn_click(btn_val):
        put_markdown("> You click `%s` button" % btn_val)

    put_buttons(['A', 'B', 'C'], onclick=btn_click)
    ```
    """,
                 strip_indent=4)

    @use_scope('button-callback')
    def btn_click(btn_val):
        put_markdown("> You click `%s` button" % btn_val)

    put_buttons(['A', 'B', 'C'], onclick=btn_click)
    set_scope('button-callback')

    put_markdown(r"""### 输出域Scope

    PyWebIO使用Scope模型来对内容输出的位置进行灵活地控制,PyWebIO的内容输出区可以划分出不同的输出域,PyWebIO将输出域称作`Scope`。
    
    输出域为输出内容的容器,各个输出域之间上下排列,输出域也可以进行嵌套。
    
    每个输出函数(函数名形如 `put_xxx()` )都会将内容输出到一个Scope,默认为”当前Scope”,”当前Scope”由运行时上下文确定,输出函数也可以手动指定输出到的Scope。Scope名在会话内唯一。
    
    可以使用 `use_scope()` 开启并进入一个新的输出域,或进入一个已经存在的输出域:

    ```python
    with use_scope('A'):
        put_text('Text in scope A')
    
        with use_scope('B'):
            put_text('Text in scope B')
    
    with use_scope('C'):
        put_text('Text in scope C')
    ```
    以上代码将会产生如下Scope布局:
    """,
                 strip_indent=4)
    with use_scope('A'):
        put_text('Text in scope A')

        with use_scope('B'):
            put_text('Text in scope B')

    with use_scope('C'):
        put_text('Text in scope C')

    put_html("""<style>                                           
    #pywebio-scope-A {border: 1px solid red;}                    
    #pywebio-scope-B {border: 1px solid blue;margin:2px}         
    #pywebio-scope-C {border: 1px solid green;margin-top:2px}    
    </style><br/>""")

    put_markdown(r"""
    输出函数(函数名形如 `put_xxx()` )在默认情况下,会将内容输出到”当前Scope”,可以通过 `use_scope()` 设置运行时上下文的”当前Scope”。
    
    此外,也可以通过输出函数的 scope 参数指定输出的目的Scope:
    """,
                 strip_indent=4)

    put_grid([
        [
            put_code("put_text('A', scope='A')", 'python'), None,
            put_buttons(['运行'], [lambda: put_text('A', scope='A')])
        ],
        [
            put_code("put_text('B', scope='B')", 'python'), None,
            put_buttons(['运行'], [lambda: put_text('B', scope='B')])
        ],
        [
            put_code("put_text('C', scope='C')", 'python'), None,
            put_buttons(['运行'], [lambda: put_text('C', scope='C')])
        ],
    ],
             cell_widths='1fr 10px auto')

    put_markdown(r"""输出函数可以使用position参数指定内容在Scope中输出的位置
    ```python
    put_text(now(), scope='A', position=...)
    ```
    """,
                 strip_indent=4)
    import datetime

    put_buttons(
        [('position=%s' % i, i) for i in [1, 2, 3, -1, -2, -3]],
        lambda i: put_text(datetime.datetime.now(), position=i, scope='A'),
        small=True)

    put_markdown(r"除了 `use_scope()` , PyWebIO同样提供了以下scope控制函数: ")

    put_grid([
        [
            put_code("clear('B')  # 清除Scope B中的内容", 'python'), None,
            put_buttons(['运行'], [lambda: clear('B')])
        ],
        [
            put_code("remove('C')  # 移除Scope C", 'python'), None,
            put_buttons(['运行'], [lambda: remove('C')])
        ],
        [
            put_code("scroll_to('A')  # 将页面滚动到Scope A处", 'python'), None,
            put_buttons(['运行'], [lambda: scroll_to('A')])
        ],
    ],
             cell_widths='1fr 10px auto')

    put_markdown(r"""### 布局
    一般情况下,使用上文介绍的各种输出函数足以完成各种内容的展示,但直接调用输出函数产生的输出之间都是竖直排列的,如果想实现更复杂的布局(比如在页 面左侧显示一个代码块,在右侧显示一个图像),就需要借助布局函数。

    `pywebio.output` 模块提供了3个布局函数,通过对他们进行组合可以完成各种复杂的布局:
    
     - `put_row()` : 使用行布局输出内容. 内容在水平方向上排列
     - `put_column()` : 使用列布局输出内容. 内容在竖直方向上排列
     - `put_grid()` : 使用网格布局输出内容

    比如,通过通过组合 `put_row()` 和 `put_column()` 实现的布局:
    """,
                 strip_indent=4)

    code_block(r"""
    put_row([
        put_column([
            put_code('A'),
            put_row([
                put_code('B1'), None,  # None 表示输出之间的空白
                put_code('B2'), None,
                put_code('B3'),
            ]),
            put_code('C'),
        ]), None,
        put_code('D'), None,
        put_code('E')
    ])
    """)

    put_markdown(r"""
    ### 样式
    
    如果你熟悉 CSS样式 ,你还可以使用 `style()` 函数给输出设定自定义样式。

    可以给单个的 `put_xxx()` 输出设定CSS样式,也可以配合组合输出使用:
    """,
                 strip_indent=4)

    code_block(r"""
    style(put_text('Red'), 'color: red')
    
    put_table([
        ['A', 'B'],
        ['C', style(put_text('Red'), 'color: red')],
    ])
    """,
               strip_indent=4)

    put_markdown(r"`style()` 也接受列表作为输入:")

    code_block(r"""
    style([
        put_text('Red'),
        put_markdown('~~del~~')
    ], 'color: red')
    
    put_collapse('title', style([
        put_text('text'),
        put_markdown('~~del~~'),
    ], 'margin-left: 20px'))

    """,
               strip_indent=4)

    put_markdown("""----
    PyWebIO的输出演示到这里就结束了,更多内容请访问PyWebIO[用户指南](https://pywebio.readthedocs.io/zh_CN/latest/guide.html)和[output模块文档](https://pywebio.readthedocs.io/zh_CN/latest/output.html)。
    """,
                 lstrip=True)

    await hold()
Example #26
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()