|
| 1 | +#!/usr/bin/env python3 |
| 2 | +from http.server import SimpleHTTPRequestHandler, HTTPServer |
| 3 | +import json |
| 4 | +import os |
| 5 | + |
| 6 | +from .layout import KeyboardLayout |
| 7 | + |
| 8 | +def keyboard_server(file_path): |
| 9 | + kb_layout = KeyboardLayout(file_path) |
| 10 | + |
| 11 | + host_name = 'localhost' |
| 12 | + server_port = 8080 |
| 13 | + |
| 14 | + def main_page(layout): |
| 15 | + return f""" |
| 16 | + <!DOCTYPE html> |
| 17 | + <html xmlns="http://www.w3.org/1999/xhtml"> |
| 18 | + <head> |
| 19 | + <meta charset="utf-8" /> |
| 20 | + <title>Kalamine</title> |
| 21 | + <link rel="stylesheet" type="text/css" href="style.css" /> |
| 22 | + <script src="x-keyboard.js" type="module"></script> |
| 23 | + <script src="demo.js" type="text/javascript"></script> |
| 24 | + </head> |
| 25 | + <body> |
| 26 | + <p> |
| 27 | + <a href="{layout.meta['url']}">{layout.meta['name']}</a> |
| 28 | + <br /> {layout.meta['locale']}/{layout.meta['variant']} |
| 29 | + <br /> {layout.meta['description']} |
| 30 | + </p> |
| 31 | + <input spellcheck="false" placeholder="" /> |
| 32 | + <x-keyboard src="/json"></x-keyboard> |
| 33 | + <p style="text-align: right;"> |
| 34 | + <select> |
| 35 | + <option value="iso"> ISO </option> |
| 36 | + <option value="ansi"> ANSI </option> |
| 37 | + <option value="ol60"> ERGO </option> |
| 38 | + <option value="ol50"> 4×12 </option> |
| 39 | + <option value="ol40"> 3×12 </option> |
| 40 | + </select> |
| 41 | + </p> |
| 42 | + <p style="text-align: center;"> |
| 43 | + <a href="/json">json</a> |
| 44 | + | <a href="/keylayout">keylayout</a> |
| 45 | + | <a href="/klc">klc</a> |
| 46 | + | <a href="/xkb">xkb</a> |
| 47 | + | <a href="/xkb_custom">xkb_custom</a> |
| 48 | + </p> |
| 49 | + </body> |
| 50 | + </html> |
| 51 | + """ |
| 52 | + |
| 53 | + class LayoutHandler(SimpleHTTPRequestHandler): |
| 54 | + def __init__(self, *args, **kwargs): |
| 55 | + dir_path = os.path.dirname(os.path.realpath(__file__)) |
| 56 | + www_path = os.path.join(dir_path, 'www') |
| 57 | + super().__init__(*args, directory=www_path, **kwargs) |
| 58 | + |
| 59 | + def do_GET(self): |
| 60 | + self.send_response(200) |
| 61 | + |
| 62 | + def send(page, content='text/plain', charset='utf-8'): |
| 63 | + self.send_header('Content-type', f"{content}; charset={charset}") |
| 64 | + self.end_headers() |
| 65 | + self.wfile.write(bytes(page, charset)) |
| 66 | + # self.wfile.write(page.encode(charset)) |
| 67 | + |
| 68 | + # XXX always reloads the layout on the root page, never in sub pages |
| 69 | + global kb_layout |
| 70 | + if self.path == '/json': |
| 71 | + send(json.dumps(kb_layout.json), content='application/json') |
| 72 | + elif self.path == '/keylayout': |
| 73 | + # send(kb_layout.keylayout, content='application/xml') |
| 74 | + send(kb_layout.keylayout) |
| 75 | + elif self.path == '/klc': |
| 76 | + send(kb_layout.klc, charset='utf-16-le') |
| 77 | + elif self.path == '/xkb': |
| 78 | + send(kb_layout.xkb) |
| 79 | + elif self.path == '/xkb_custom': |
| 80 | + send(kb_layout.xkb_patch) |
| 81 | + elif self.path == '/': |
| 82 | + kb_layout = KeyboardLayout(file_path) # refresh |
| 83 | + send(main_page(kb_layout), content='text/html') |
| 84 | + else: |
| 85 | + return SimpleHTTPRequestHandler.do_GET(self) |
| 86 | + |
| 87 | + webserver = HTTPServer((host_name, server_port), LayoutHandler) |
| 88 | + print(f"Server started: http://{host_name}:{server_port}") |
| 89 | + print('Hit Ctrl-C to stop.') |
| 90 | + |
| 91 | + try: |
| 92 | + webserver.serve_forever() |
| 93 | + except KeyboardInterrupt: |
| 94 | + pass |
| 95 | + |
| 96 | + webserver.server_close() |
| 97 | + print('Server stopped.') |
0 commit comments