2023-08-31 16:57:55 +08:00
|
|
|
|
|
|
|
import os
|
|
|
|
from gi.repository import Gio, WebKit2
|
|
|
|
from ._mimetypes import get_mimetype
|
2023-09-07 11:39:56 +08:00
|
|
|
from ._version import version
|
2023-08-31 16:57:55 +08:00
|
|
|
|
2023-09-07 11:39:56 +08:00
|
|
|
__dir__ = os.path.dirname(os.path.realpath(__file__))
|
2023-08-31 16:57:55 +08:00
|
|
|
|
|
|
|
class Protocal:
|
|
|
|
root = ''
|
|
|
|
|
|
|
|
def __init__(self, webroot = ''):
|
|
|
|
self.root = os.path.realpath(webroot)
|
|
|
|
|
|
|
|
def register(self, webview, name = 'app'):
|
|
|
|
self.protocal = name
|
|
|
|
ctx = webview.get_context()
|
|
|
|
ctx.register_uri_scheme(name, self.handle_response)
|
|
|
|
# 允许网页通知权限
|
|
|
|
ctx.initialize_notification_permissions([WebKit2.SecurityOrigin.new_for_uri('app:///index.html')], [])
|
|
|
|
|
|
|
|
|
|
|
|
def abspath(self, filepath):
|
|
|
|
return os.path.join(self.root, filepath)
|
|
|
|
|
|
|
|
|
2023-09-07 11:39:56 +08:00
|
|
|
def _get_error_page(self, tips = '404 not found!'):
|
|
|
|
data = f"""
|
|
|
|
<!doctype html>
|
|
|
|
<html lang="zh-CN">
|
|
|
|
<head>
|
|
|
|
<meta charset="utf-8">
|
|
|
|
<title>Page not found</title>
|
|
|
|
<style>body {{text-align: center;-webkit-user-select:none}} cite {{font-size:12px}}</style>
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<h1>Oops!</h1>
|
|
|
|
<h2>{tips}</h2>
|
|
|
|
<hr>
|
|
|
|
<cite>WebEngine v{version}</cite>
|
|
|
|
</body>
|
|
|
|
</html>
|
|
|
|
"""
|
|
|
|
return data
|
|
|
|
|
2023-08-31 16:57:55 +08:00
|
|
|
def handle_response(self, req):
|
|
|
|
schema = req.get_scheme()
|
|
|
|
pathname = req.get_path()[1:]
|
|
|
|
ext = pathname.split('.')[-1]
|
2023-09-07 11:39:56 +08:00
|
|
|
mimetype = get_mimetype(ext)
|
|
|
|
|
|
|
|
if pathname == ext:
|
|
|
|
pathname = 'index.html'
|
2023-08-31 16:57:55 +08:00
|
|
|
|
|
|
|
# print('----------------------------------------')
|
2023-09-07 11:39:56 +08:00
|
|
|
# print(req.get_uri(),schema, pathname, ext, mimetype)
|
2023-08-31 16:57:55 +08:00
|
|
|
# print('----------------------------------------')
|
|
|
|
|
|
|
|
if schema == self.protocal:
|
2023-09-07 11:39:56 +08:00
|
|
|
filepath = self.abspath(pathname)
|
|
|
|
if os.path.isfile(filepath):
|
|
|
|
try:
|
|
|
|
with open(filepath) as f:
|
|
|
|
data = f.read()
|
|
|
|
except Exception:
|
|
|
|
data = self._get_error_page('403 Forbidden!')
|
|
|
|
else:
|
|
|
|
data = self._get_error_page()
|
|
|
|
|
2023-08-31 16:57:55 +08:00
|
|
|
data = Gio.MemoryInputStream.new_from_data(data.encode())
|
|
|
|
|
|
|
|
# ------- 更多功能的reponse ----------------
|
|
|
|
# res = WebKit2.URISchemeResponse.new(data, -1)
|
2023-09-07 11:39:56 +08:00
|
|
|
# res.set_content_type(mimetype)
|
2023-08-31 16:57:55 +08:00
|
|
|
# res.set_http_headers('text/html')
|
|
|
|
# res.set_status(200)
|
|
|
|
# req.finish_with_response(res)
|
|
|
|
# ----------------------------------------
|
|
|
|
|
|
|
|
# 简单的response
|
2023-09-07 11:39:56 +08:00
|
|
|
req.finish(data, -1, mimetype)
|
2023-08-31 16:57:55 +08:00
|
|
|
|
|
|
|
|
|
|
|
def create_protocal(root):
|
|
|
|
proto = Protocal(root)
|
|
|
|
|
|
|
|
def wrapper(app, extra = None):
|
|
|
|
proto.register(app)
|
|
|
|
|
|
|
|
return wrapper
|