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')
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' )
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()
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)
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)
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()
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()
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("你已经退出聊天室")
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()
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)
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("密码错误, 请刷新页面重试")
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()
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)
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("密码错误,请刷新页面重试")
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()
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()
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("密码错误,请刷新页面重试")
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()
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
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()
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)
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)
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)
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)
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()
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()