clan-app: changed webui to webview lib
This commit is contained in:
0
pkgs/clan-app/clan_app/deps/webview/__init__.py
Normal file
0
pkgs/clan-app/clan_app/deps/webview/__init__.py
Normal file
134
pkgs/clan-app/clan_app/deps/webview/_webview_ffi.py
Normal file
134
pkgs/clan-app/clan_app/deps/webview/_webview_ffi.py
Normal file
@@ -0,0 +1,134 @@
|
||||
import ctypes
|
||||
import sys
|
||||
import os
|
||||
import platform
|
||||
import urllib.request
|
||||
from pathlib import Path
|
||||
from ctypes import c_int, c_char_p, c_void_p, CFUNCTYPE
|
||||
import ctypes.util
|
||||
|
||||
def _encode_c_string(s: str) -> bytes:
|
||||
return s.encode("utf-8")
|
||||
|
||||
def _get_webview_version():
|
||||
"""Get webview version from environment variable or use default"""
|
||||
return os.getenv("WEBVIEW_VERSION", "0.8.1")
|
||||
|
||||
def _get_lib_names():
|
||||
"""Get platform-specific library names."""
|
||||
system = platform.system().lower()
|
||||
machine = platform.machine().lower()
|
||||
|
||||
if system == "windows":
|
||||
if machine == "amd64" or machine == "x86_64":
|
||||
return ["webview.dll", "WebView2Loader.dll"]
|
||||
elif machine == "arm64":
|
||||
raise Exception("arm64 is not supported on Windows")
|
||||
elif system == "darwin":
|
||||
if machine == "arm64":
|
||||
return ["libwebview.aarch64.dylib"]
|
||||
else:
|
||||
return ["libwebview.x86_64.dylib"]
|
||||
else: # linux
|
||||
return ["libwebview.so"]
|
||||
|
||||
def _get_download_urls():
|
||||
"""Get the appropriate download URLs based on the platform."""
|
||||
version = _get_webview_version()
|
||||
return [f"https://github.com/webview/webview_deno/releases/download/{version}/{lib_name}"
|
||||
for lib_name in _get_lib_names()]
|
||||
|
||||
def _be_sure_libraries():
|
||||
"""Ensure libraries exist and return paths."""
|
||||
if getattr(sys, 'frozen', False):
|
||||
if hasattr(sys, '_MEIPASS'):
|
||||
base_dir = Path(sys._MEIPASS)
|
||||
else:
|
||||
base_dir = Path(sys.executable).parent / '_internal'
|
||||
else:
|
||||
base_dir = Path(__file__).parent
|
||||
|
||||
lib_dir = base_dir / "lib"
|
||||
lib_names = _get_lib_names()
|
||||
lib_paths = [lib_dir / lib_name for lib_name in lib_names]
|
||||
|
||||
# Check if any library is missing
|
||||
missing_libs = [path for path in lib_paths if not path.exists()]
|
||||
if not missing_libs:
|
||||
return lib_paths
|
||||
|
||||
# Download missing libraries
|
||||
download_urls = _get_download_urls()
|
||||
system = platform.system().lower()
|
||||
|
||||
lib_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
for url, lib_path in zip(download_urls, lib_paths):
|
||||
if lib_path.exists():
|
||||
continue
|
||||
|
||||
print(f"Downloading library from {url}")
|
||||
try:
|
||||
req = urllib.request.Request(
|
||||
url,
|
||||
headers={'User-Agent': 'Mozilla/5.0'}
|
||||
)
|
||||
with urllib.request.urlopen(req) as response, open(lib_path, 'wb') as out_file:
|
||||
out_file.write(response.read())
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Failed to download library: {e}")
|
||||
|
||||
return lib_paths
|
||||
|
||||
class _WebviewLibrary:
|
||||
def __init__(self):
|
||||
lib_names=_get_lib_names()
|
||||
try:
|
||||
library_path = ctypes.util.find_library(lib_names[0])
|
||||
if not library_path:
|
||||
library_paths = _be_sure_libraries()
|
||||
self.lib = ctypes.cdll.LoadLibrary(str(library_paths[0]))
|
||||
except Exception as e:
|
||||
print(f"Failed to load webview library: {e}")
|
||||
raise
|
||||
# Define FFI functions
|
||||
self.webview_create = self.lib.webview_create
|
||||
self.webview_create.argtypes = [c_int, c_void_p]
|
||||
self.webview_create.restype = c_void_p
|
||||
|
||||
self.webview_destroy = self.lib.webview_destroy
|
||||
self.webview_destroy.argtypes = [c_void_p]
|
||||
|
||||
self.webview_run = self.lib.webview_run
|
||||
self.webview_run.argtypes = [c_void_p]
|
||||
|
||||
self.webview_terminate = self.lib.webview_terminate
|
||||
self.webview_terminate.argtypes = [c_void_p]
|
||||
|
||||
self.webview_set_title = self.lib.webview_set_title
|
||||
self.webview_set_title.argtypes = [c_void_p, c_char_p]
|
||||
|
||||
self.webview_set_size = self.lib.webview_set_size
|
||||
self.webview_set_size.argtypes = [c_void_p, c_int, c_int, c_int]
|
||||
|
||||
self.webview_navigate = self.lib.webview_navigate
|
||||
self.webview_navigate.argtypes = [c_void_p, c_char_p]
|
||||
|
||||
self.webview_init = self.lib.webview_init
|
||||
self.webview_init.argtypes = [c_void_p, c_char_p]
|
||||
|
||||
self.webview_eval = self.lib.webview_eval
|
||||
self.webview_eval.argtypes = [c_void_p, c_char_p]
|
||||
|
||||
self.webview_bind = self.lib.webview_bind
|
||||
self.webview_bind.argtypes = [c_void_p, c_char_p, c_void_p, c_void_p]
|
||||
|
||||
self.webview_unbind = self.lib.webview_unbind
|
||||
self.webview_unbind.argtypes = [c_void_p, c_char_p]
|
||||
|
||||
self.webview_return = self.lib.webview_return
|
||||
self.webview_return.argtypes = [c_void_p, c_char_p, c_int, c_char_p]
|
||||
|
||||
self.CFUNCTYPE = CFUNCTYPE
|
||||
|
||||
_webview_lib = _WebviewLibrary()
|
||||
92
pkgs/clan-app/clan_app/deps/webview/webview.py
Normal file
92
pkgs/clan-app/clan_app/deps/webview/webview.py
Normal file
@@ -0,0 +1,92 @@
|
||||
from enum import IntEnum
|
||||
from typing import Optional, Callable, Any
|
||||
import json
|
||||
import ctypes
|
||||
from ._webview_ffi import _webview_lib, _encode_c_string
|
||||
|
||||
class SizeHint(IntEnum):
|
||||
NONE = 0
|
||||
MIN = 1
|
||||
MAX = 2
|
||||
FIXED = 3
|
||||
|
||||
class Size:
|
||||
def __init__(self, width: int, height: int, hint: SizeHint):
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.hint = hint
|
||||
|
||||
class Webview:
|
||||
def __init__(self, debug: bool = False, size: Optional[Size] = None, window: Optional[int] = None):
|
||||
self._handle = _webview_lib.webview_create(int(debug), window)
|
||||
self._callbacks = {}
|
||||
|
||||
if size:
|
||||
self.size = size
|
||||
|
||||
@property
|
||||
def size(self) -> Size:
|
||||
return self._size
|
||||
|
||||
@size.setter
|
||||
def size(self, value: Size):
|
||||
_webview_lib.webview_set_size(self._handle, value.width, value.height, value.hint)
|
||||
self._size = value
|
||||
|
||||
@property
|
||||
def title(self) -> str:
|
||||
return self._title
|
||||
|
||||
@title.setter
|
||||
def title(self, value: str):
|
||||
_webview_lib.webview_set_title(self._handle, _encode_c_string(value))
|
||||
self._title = value
|
||||
|
||||
def destroy(self):
|
||||
for name in list(self._callbacks.keys()):
|
||||
self.unbind(name)
|
||||
_webview_lib.webview_terminate(self._handle)
|
||||
_webview_lib.webview_destroy(self._handle)
|
||||
self._handle = None
|
||||
|
||||
def navigate(self, url: str):
|
||||
_webview_lib.webview_navigate(self._handle, _encode_c_string(url))
|
||||
|
||||
def run(self):
|
||||
_webview_lib.webview_run(self._handle)
|
||||
self.destroy()
|
||||
|
||||
def bind(self, name: str, callback: Callable[..., Any]):
|
||||
def wrapper(seq: bytes, req: bytes, arg: int):
|
||||
args = json.loads(req.decode())
|
||||
try:
|
||||
result = callback(*args)
|
||||
success = True
|
||||
except Exception as e:
|
||||
result = str(e)
|
||||
success = False
|
||||
self.return_(seq.decode(), 0 if success else 1, json.dumps(result))
|
||||
|
||||
c_callback = _webview_lib.CFUNCTYPE(None, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_void_p)(wrapper)
|
||||
self._callbacks[name] = c_callback
|
||||
_webview_lib.webview_bind(self._handle, _encode_c_string(name), c_callback, None)
|
||||
|
||||
def unbind(self, name: str):
|
||||
if name in self._callbacks:
|
||||
_webview_lib.webview_unbind(self._handle, _encode_c_string(name))
|
||||
del self._callbacks[name]
|
||||
|
||||
def return_(self, seq: str, status: int, result: str):
|
||||
_webview_lib.webview_return(self._handle, _encode_c_string(seq), status, _encode_c_string(result))
|
||||
|
||||
def eval(self, source: str):
|
||||
_webview_lib.webview_eval(self._handle, _encode_c_string(source))
|
||||
|
||||
def init(self, source: str):
|
||||
_webview_lib.webview_init(self._handle, _encode_c_string(source))
|
||||
|
||||
if __name__ == "__main__":
|
||||
wv = Webview()
|
||||
wv.title = "Hello, World!"
|
||||
wv.navigate("https://www.google.com")
|
||||
wv.run()
|
||||
@@ -1,56 +0,0 @@
|
||||
{ lib
|
||||
, buildPythonPackage
|
||||
, fetchFromGitHub
|
||||
|
||||
# build-system dependencies
|
||||
, setuptools
|
||||
, wheel
|
||||
, webview-wrapper
|
||||
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "python-webui";
|
||||
version = "main";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "webui-dev";
|
||||
repo = "python-webui";
|
||||
rev = "fa961b5ee0752c9408ac01519097f5481a0fcecf"; # Replace with specific commit hash for reproducibility
|
||||
# sha256 = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; # Replace with actual hash via nix-prefetch-git
|
||||
};
|
||||
|
||||
sourceRoot = "PyPI/Package";
|
||||
|
||||
# Indicate this is a recent Python project with PEP 517 support (pyproject.toml)
|
||||
pyproject = true;
|
||||
|
||||
# Declare the build system (setuptools and wheel are common)
|
||||
buildInputs = [
|
||||
setuptools
|
||||
wheel
|
||||
];
|
||||
|
||||
# Declare required Python package dependencies
|
||||
propagatedBuildInputs = [
|
||||
|
||||
];
|
||||
|
||||
# Native inputs for testing, if tests are included
|
||||
nativeCheckInputs = [
|
||||
|
||||
];
|
||||
|
||||
# If tests don't work out of the box or need adjustments, patches can be applied here
|
||||
postPatch = ''
|
||||
# Example: Modify or patch some test files
|
||||
echo "No postPatch modifications applied yet."
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
description = "A Python library for webui-dev";
|
||||
homepage = "https://github.com/webui-dev/python-webui";
|
||||
license = licenses.mit;
|
||||
maintainers = [ maintainers.yourname ];
|
||||
};
|
||||
}
|
||||
@@ -1,39 +1,32 @@
|
||||
{ pkgs }:
|
||||
|
||||
pkgs.stdenv.mkDerivation rec {
|
||||
pname = "webui";
|
||||
pkgs.stdenv.mkDerivation {
|
||||
pname = "webview";
|
||||
version = "nigthly";
|
||||
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "webui-dev";
|
||||
repo = "python-webui";
|
||||
rev = "0ff3b1351b9e24be4463b1baf2c26966caeae74a"; # Use a specific commit sha or tag for reproducibility
|
||||
sha256 = "sha256-xSOnCkW4iZkSSLKzk6r3hewC3bPJlV7L6aoGEchyEys="; # Replace with actual sha256
|
||||
owner = "webview";
|
||||
repo = "webview";
|
||||
rev = "83a4b4a5bbcb4b0ba2ca3ee226c2da1414719106";
|
||||
sha256 = "sha256-5R8kllvP2EBuDANIl07fxv/EcbPpYgeav8Wfz7Kt13c=";
|
||||
};
|
||||
|
||||
outputs = [ "out" "dev" ];
|
||||
|
||||
# Dependencies used during the build process, if any
|
||||
buildInputs = [
|
||||
pkgs.gnumake
|
||||
buildInputs = with pkgs; [
|
||||
gnumake
|
||||
cmake
|
||||
pkg-config
|
||||
webkitgtk_6_0
|
||||
gtk4
|
||||
];
|
||||
|
||||
# Commands to build and install the project
|
||||
buildPhase = ''
|
||||
make
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/lib
|
||||
mkdir -p $out/include
|
||||
cp -r dist/* $out/lib
|
||||
cp -r include/* $out/include
|
||||
'';
|
||||
|
||||
meta = with pkgs.lib; {
|
||||
description = "Webui is a UI library for C/C++/Go/Rust to build portable desktop/web apps using WebView";
|
||||
homepage = "https://github.com/webui-dev/webui";
|
||||
description = "Tiny cross-platform webview library for C/C++. Uses WebKit (GTK/Cocoa) and Edge WebView2 (Windows)";
|
||||
homepage = "https://github.com/webview/webview";
|
||||
license = licenses.mit;
|
||||
platforms = platforms.linux ++ platforms.darwin; # Adjust if needed
|
||||
platforms = platforms.linux ++ platforms.darwin;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user