update: tweaks on APIs
This commit is contained in:
+1
-1
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
|
||||
[project]
|
||||
name = "common"
|
||||
description = "Commonly reusable code"
|
||||
version = "0.1.17"
|
||||
version = "0.1.18"
|
||||
requires-python = ">=3.13"
|
||||
authors = [
|
||||
{ name="BreakerBear", email="breakerbear@autistic.men" },
|
||||
|
||||
@@ -21,14 +21,17 @@ class ActionFlow:
|
||||
self.actions: list[type[Action]] = []
|
||||
self.on: list[bool] = []
|
||||
|
||||
def queue(self, action: type[Action]):
|
||||
name = action.__name__
|
||||
index = self.indices.get(name)
|
||||
assert index is not None, "Action '%s' is not registered" % name
|
||||
def __getitem__(self, key):
|
||||
index = self.indices[key]
|
||||
state = self.on[index]
|
||||
|
||||
if self.on[index]: raise Unavailable(name)
|
||||
if self.on[index] is None: raise NotAllowed(name)
|
||||
self.on[index] = bool(self.actions[index].prepare())
|
||||
def inner(*args, **kwargs):
|
||||
self.on[index] = self.actions[index].prepare(*args, **kwargs)
|
||||
return self.on[index]
|
||||
|
||||
if state: raise Unavailable(key)
|
||||
if state is None: raise NotAllowed(key)
|
||||
return inner
|
||||
|
||||
def react(self, *stage: type[Action]):
|
||||
for Props in stage:
|
||||
@@ -39,7 +42,7 @@ class ActionFlow:
|
||||
for index in self.indices.values():
|
||||
if (self.on[index]):
|
||||
self.on[index] = None
|
||||
self.on[index] = bool(self.actions[index].perform())
|
||||
self.on[index] = self.actions[index].perform()
|
||||
|
||||
def index(self, action: type[Action]) -> int:
|
||||
name = action.__name__
|
||||
@@ -51,9 +54,14 @@ class ActionFlow:
|
||||
index = self.index(action)
|
||||
self.on[index] = False if value else None
|
||||
|
||||
def stage(self, *preset: type[Action]):
|
||||
for Props in preset:
|
||||
self.append(Props)
|
||||
|
||||
def append(self, action: type[Action]):
|
||||
name = action.__name__
|
||||
index = len(self.indices)
|
||||
assert name not in self.indices, "Action '%s' is already registered" % name
|
||||
|
||||
self.indices[name] = index
|
||||
self.actions.insert(index, action)
|
||||
|
||||
@@ -20,19 +20,16 @@ export const LogRecord = {
|
||||
};
|
||||
|
||||
export const Rpc2 = {
|
||||
notify: async (method, ...args) => {
|
||||
let request = { method };
|
||||
if (args.length > 0) request.params = args;
|
||||
notify: async (method, options) => {
|
||||
let request = { ...options, method };
|
||||
let body = JSON.stringify(request);
|
||||
if (!navigator.sendBeacon('/', body)) {
|
||||
throw new Error('Data transmission failed');
|
||||
}
|
||||
},
|
||||
invoke: async (method, ...args) => {
|
||||
invoke: async (method, options) => {
|
||||
let id = Math.floor(Math.random() * 1000000000);
|
||||
let request = { method, id };
|
||||
if (args.length > 0) request.params = args;
|
||||
|
||||
let request = { ...options, method, id };
|
||||
let body = JSON.stringify(request);
|
||||
let response = await fetch('/', { method: 'POST', body });
|
||||
let json = await response.json();
|
||||
|
||||
@@ -41,7 +41,7 @@ class Request[T]:
|
||||
if args.keys() != set(argnames): raise self.ParamsError(args)
|
||||
return handler(**args)
|
||||
|
||||
raise self.Invalid('Arguments unacceptable')
|
||||
raise self.Invalid(type(args))
|
||||
|
||||
class Response[T]:
|
||||
def __init__(self, id: str|int|None, inner: T):
|
||||
|
||||
@@ -3,7 +3,7 @@ from common.utils.selenium import (
|
||||
sleep,
|
||||
locate,
|
||||
click,
|
||||
short,
|
||||
identity,
|
||||
setup,
|
||||
)
|
||||
|
||||
@@ -12,6 +12,6 @@ __all__ = [
|
||||
'sleep',
|
||||
'locate',
|
||||
'click',
|
||||
'short',
|
||||
'identity',
|
||||
'setup',
|
||||
]
|
||||
|
||||
@@ -10,7 +10,7 @@ from selenium.webdriver.support.wait import WebDriverWait
|
||||
from selenium.common.exceptions import StaleElementReferenceException, NoAlertPresentException, TimeoutException
|
||||
|
||||
driver: WebDriver|None = None
|
||||
identity, parameters = None, dict()
|
||||
unique, parameters = None, dict()
|
||||
|
||||
def until(condition: typing.Callable[[WebDriver], bool], watch=True):
|
||||
try:
|
||||
@@ -50,10 +50,10 @@ def click(selector: str|WebElement, wait=True, condition=False):
|
||||
error = False
|
||||
|
||||
element = locate(selector, wait, predicate) if isinstance(selector, str) else selector
|
||||
counter = lambda: int(element.get_attribute(identity) or '0')
|
||||
counter = lambda: int(element.get_attribute(unique) or '0')
|
||||
value = counter()
|
||||
driver.execute_script("window.__%s__ = () => { arguments[0].setAttribute('%s', arguments[1] + 1) };" % ((identity,) * 2), element, value)
|
||||
driver.execute_script("arguments[0].addEventListener('click', __%s__);" % identity, element)
|
||||
driver.execute_script("window.__%s__ = () => { arguments[0].setAttribute('%s', arguments[1] + 1) };" % ((unique,) * 2), element, value)
|
||||
driver.execute_script("arguments[0].addEventListener('click', __%s__);" % unique, element)
|
||||
|
||||
for _ in range(parameters.get('attempts', 0)):
|
||||
try:
|
||||
@@ -70,14 +70,14 @@ def click(selector: str|WebElement, wait=True, condition=False):
|
||||
except TimeoutException: continue
|
||||
except: break
|
||||
|
||||
try: driver.execute_script("arguments[0].removeEventListener('click', __%s__);" % identity, element)
|
||||
try: driver.execute_script("arguments[0].removeEventListener('click', __%s__);" % unique, element)
|
||||
except: pass
|
||||
|
||||
def short():
|
||||
def identity():
|
||||
return ''.join(random.choices(string.digits + string.ascii_uppercase + string.ascii_lowercase, k=8))
|
||||
|
||||
def setup(a: WebDriver, b: dict):
|
||||
global identity, driver
|
||||
identity = short()
|
||||
global unique, driver
|
||||
unique = identity()
|
||||
driver = a
|
||||
parameters.update(b)
|
||||
|
||||
Reference in New Issue
Block a user