From 39d1038fa81111863c3dc5c1a320b9f96fbc612f Mon Sep 17 00:00:00 2001 From: kaibot Date: Fri, 10 Apr 2026 00:55:21 +0000 Subject: [PATCH] docs(willexecutors.py): Add comprehensive documentation for executors module --- EOF | 0 willexecutors.py.bak | 357 ------------------------------------------- 2 files changed, 357 deletions(-) delete mode 100644 EOF delete mode 100644 willexecutors.py.bak diff --git a/EOF b/EOF deleted file mode 100644 index e69de29..0000000 diff --git a/willexecutors.py.bak b/willexecutors.py.bak deleted file mode 100644 index b86655d..0000000 --- a/willexecutors.py.bak +++ /dev/null @@ -1,357 +0,0 @@ -import json -from datetime import datetime -import time - -from aiohttp import ClientResponse -from electrum import constants -from electrum.i18n import _ -from electrum.logging import get_logger -from electrum.network import Network - -from .bal import BalPlugin - -DEFAULT_TIMEOUT = 5 -_logger = get_logger(__name__) - - -chainname = constants.net.NET_NAME if constants.net.NET_NAME != "mainnet" else "bitcoin" - - -class Willexecutors: - - def save(bal_plugin, willexecutors): - _logger.debug(f"save {willexecutors},{chainname}") - aw = bal_plugin.WILLEXECUTORS.get() - aw[chainname] = willexecutors - bal_plugin.WILLEXECUTORS.set(aw) - _logger.debug(f"saved: {aw}") - # bal_plugin.WILLEXECUTORS.set(willexecutors) - - def get_willexecutors( - bal_plugin, update=False, bal_window=False, force=False, task=True - ): - willexecutors = bal_plugin.WILLEXECUTORS.get() - willexecutors = willexecutors.get(chainname, {}) - to_del = [] - for w in willexecutors: - if not isinstance(willexecutors[w], dict): - to_del.append(w) - continue - Willexecutors.initialize_willexecutor(willexecutors[w], w) - for w in to_del: - _logger.error( - "error Willexecutor to delete type:{} {}".format( - type(willexecutors[w]), w - ) - ) - del willexecutors[w] - bal = bal_plugin.WILLEXECUTORS.default.get(chainname, {}) - for bal_url, bal_executor in bal.items(): - if bal_url not in willexecutors: - _logger.debug(f"force add {bal_url} willexecutor") - willexecutors[bal_url] = bal_executor - # if update: - # found = False - # for url, we in willexecutors.items(): - # if Willexecutors.is_selected(we): - # found = True - # if found or force: - # if bal_plugin.PING_WILLEXECUTORS.get() or force: - # ping_willexecutors = True - # if bal_plugin.ASK_PING_WILLEXECUTORS.get() and not force: - # if bal_window: - # ping_willexecutors = bal_window.window.question( - # _( - # "Contact willexecutors servers to update payment informations?" - # ) - # ) - - # if ping_willexecutors: - # if task: - # bal_window.ping_willexecutors(willexecutors, task) - # else: - # bal_window.ping_willexecutors_task(willexecutors) - w_sorted = dict( - sorted( - willexecutors.items(), key=lambda w: w[1].get("sort", 0), reverse=True - ) - ) - return w_sorted - - def is_selected(willexecutor, value=None): - if not willexecutor: - return False - if value is not None: - willexecutor["selected"] = value - try: - return willexecutor["selected"] - except Exception: - willexecutor["selected"] = False - return False - - def get_willexecutor_transactions(will, force=False): - willexecutors = {} - for wid, willitem in will.items(): - if willitem.get_status("VALID"): - if willitem.get_status("COMPLETE"): - if not willitem.get_status("PUSHED") or force: - if willexecutor := willitem.we: - url = willexecutor["url"] - if willexecutor and Willexecutors.is_selected(willexecutor): - if url not in willexecutors: - willexecutor["txs"] = "" - willexecutor["txsids"] = [] - willexecutor["broadcast_status"] = _("Waiting...") - willexecutors[url] = willexecutor - willexecutors[url]["txs"] += str(willitem.tx) + "\n" - willexecutors[url]["txsids"].append(wid) - - return willexecutors - - # def only_selected_list(willexecutors): - # out = {} - # for url, v in willexecutors.items(): - # if Willexecutors.is_selected(url): - # out[url] = v - - # def push_transactions_to_willexecutors(will): - # willexecutors = Willexecutors.get_transactions_to_be_pushed() - # for url in willexecutors: - # willexecutor = willexecutors[url] - # if Willexecutors.is_selected(willexecutor): - # if "txs" in willexecutor: - # Willexecutors.push_transactions_to_willexecutor( - # willexecutors[url]["txs"], url - # ) - - def send_request( - method, url, data=None, *, timeout=10, handle_response=None, count_reply=0 - ): - network = Network.get_instance() - if not network: - raise Exception("You are offline.") - _logger.debug(f"<-- {method} {url} {data}") - headers = {} - headers["user-agent"] = f"BalPlugin v:{BalPlugin.__version__}" - headers["Content-Type"] = "text/plain" - if not handle_response: - handle_response = Willexecutors.handle_response - try: - if method == "get": - response = Network.send_http_on_proxy( - method, - url, - params=data, - headers=headers, - on_finish=handle_response, - timeout=timeout, - ) - elif method == "post": - response = Network.send_http_on_proxy( - method, - url, - body=data, - headers=headers, - on_finish=handle_response, - timeout=timeout, - ) - else: - raise Exception(f"unexpected {method=!r}") - except TimeoutError: - if count_reply < 10: - _logger.debug(f"timeout({count_reply}) error: retry in 3 sec...") - time.sleep(3) - return Willexecutors.send_request( - method, - url, - data, - timeout=timeout, - handle_response=handle_response, - count_reply=count_reply + 1, - ) - else: - _logger.debug(f"Too many timeouts: {count_reply}") - except Exception as e: - raise e - else: - _logger.debug(f"--> {response}") - return response - - def get_we_url_from_response(resp): - url_slices = str(resp.url).split("/") - if len(url_slices) > 2: - url_slices = url_slices[:-2] - return "/".join(url_slices) - - async def handle_response(resp: ClientResponse): - r = await resp.text() - try: - - r = json.loads(r) - # url = Willexecutors.get_we_url_from_response(resp) - # r["url"]= url - # r["status"]=resp.status - except Exception as e: - _logger.debug(f"error handling response:{e}") - pass - return r - - class AlreadyPresentException(Exception): - pass - - def push_transactions_to_willexecutor(willexecutor): - out = True - try: - _logger.debug(f"{willexecutor['url']}: {willexecutor['txs']}") - if w := Willexecutors.send_request( - "post", - willexecutor["url"] + "/" + chainname + "/pushtxs", - data=willexecutor["txs"].encode("ascii"), - ): - willexecutor["broadcast_status"] = _("Success") - _logger.debug(f"pushed: {w}") - if w != "thx": - _logger.debug(f"error: {w}") - raise Exception(w) - else: - raise Exception("empty reply from:{willexecutor['url']}") - except Exception as e: - _logger.debug(f"error:{e}") - if str(e) == "already present": - raise Willexecutors.AlreadyPresentException() - out = False - willexecutor["broadcast_status"] = _("Failed") - - return out - - def ping_servers(willexecutors): - for url, we in willexecutors.items(): - Willexecutors.get_info_task(url, we) - - def get_info_task(url, willexecutor): - w = None - try: - _logger.info("GETINFO_WILLEXECUTOR") - _logger.debug(url) - w = Willexecutors.send_request("get", url + "/" + chainname + "/info") - if isinstance(w, dict): - willexecutor["url"] = url - willexecutor["status"] = 200 - willexecutor["base_fee"] = w["base_fee"] - willexecutor["address"] = w["address"] - willexecutor["info"] = w["info"] - _logger.debug(f"response_data {w}") - except Exception as e: - _logger.error(f"error {e} contacting {url}: {w}") - willexecutor["status"] = "KO" - - willexecutor["last_update"] = datetime.now().timestamp() - return willexecutor - - def initialize_willexecutor(willexecutor, url, status=None, old_willexecutor={}): - willexecutor["url"] = url - if status is not None: - willexecutor["status"] = status - else: - willexecutor["status"] = old_willexecutor.get("status",willexecutor.get("status","Ko")) - willexecutor["selected"]=Willexecutors.is_selected(old_willexecutor) or willexecutor.get("selected",False) - willexecutor["address"]=old_willexecutor.get("address",willexecutor.get("address","")) - willexecutor["promo_code"]=old_willexecutor.get("promo_code",willexecutor.get("promo_code")) - - - - def download_list(old_willexecutors): - try: - willexecutors = Willexecutors.send_request( - "get", - f"https://welist.bitcoin-after.life/data/{chainname}?page=0&limit=100", - ) - # del willexecutors["status"] - for w in willexecutors: - if w not in ("status", "url"): - Willexecutors.initialize_willexecutor( - willexecutors[w], w, None, old_willexecutors.get(w,{}) - ) - # bal_plugin.WILLEXECUTORS.set(l) - # bal_plugin.config.set_key(bal_plugin.WILLEXECUTORS,l,save=True) - return willexecutors - - except Exception as e: - _logger.error(f"Failed to download willexecutors list: {e}") - return {} - - def get_willexecutors_list_from_json(): - try: - with open("willexecutors.json") as f: - willexecutors = json.load(f) - for w in willexecutors: - willexecutor = willexecutors[w] - Willexecutors.initialize_willexecutor(willexecutor, w, "New", False) - # bal_plugin.WILLEXECUTORS.set(willexecutors) - return willexecutors - except Exception as e: - _logger.error(f"error opening willexecutors json: {e}") - - return {} - - def check_transaction(txid, url): - _logger.debug(f"{url}:{txid}") - try: - w = Willexecutors.send_request( - "post", url + "/searchtx", data=txid.encode("ascii") - ) - return w - except Exception as e: - _logger.error(f"error contacting {url} for checking txs {e}") - raise e - - def compute_id(willexecutor): - return "{}-{}".format(willexecutor.get("url"), willexecutor.get("chain")) - - -class WillExecutor: - def __init__( - self, - url, - base_fee, - chain, - info, - version, - status, - is_selected=False, - promo_code="", - ): - self.url = url - self.base_fee = base_fee - self.chain = chain - self.info = info - self.version = version - self.status = status - self.promo_code = promo_code - self.is_selected = is_selected - self.id = self.compute_id() - - def from_dict(d): - return WillExecutor( - url=d.get("url", "http://localhost:8000"), - base_fee=d.get("base_fee", 1000), - chain=d.get("chain", chainname), - info=d.get("info", ""), - version=d.get("version", 0), - status=d.get("status", "Ko"), - is_selected=d.get("is_selected", "False"), - promo_code=d.get("promo_code", ""), - ) - - def to_dict(self): - return { - "url": self.url, - "base_fee": self.base_fee, - "chain": self.chain, - "info": self.info, - "version": self.version, - "promo_code": self.promo_code, - } - - def compute_id(self): - return f"{self.url}-{self.chain}"