Upload files to "bal/core"

v0.6.1: get_version() + version property
This commit is contained in:
2026-07-22 13:03:32 +00:00
parent 8aa2175f15
commit 300fa89124
2 changed files with 46 additions and 16 deletions

View File

@@ -21,6 +21,7 @@ serialised together with the wallet file.
This module performs **no** GUI work and imports nothing from PyQt / electrum.gui. This module performs **no** GUI work and imports nothing from PyQt / electrum.gui.
""" """
import json
import os import os
import platform import platform
from datetime import date, datetime, timedelta from datetime import date, datetime, timedelta
@@ -33,6 +34,45 @@ from electrum.transaction import tx_from_any
_logger = get_logger(__name__) _logger = get_logger(__name__)
# --------------------------------------------------------------------------- #
# Plugin version - single source of truth
# --------------------------------------------------------------------------- #
# The version lives ONLY in bal/manifest.json (the file Electrum itself reads).
# We used to hardcode it in four files and keep them in sync with a pre-commit
# hook; reading it from the manifest removes that duplication.
#
# importlib.resources is used on purpose: it reads a data file bundled inside
# the ``bal`` package and works identically whether the plugin runs from an
# extracted directory or from INSIDE a zip (Electrum loads external plugins via
# zipimport). It never builds a path by hand, so there is no os.path.join
# backslash issue on Windows inside a zip.
_VERSION_CACHE = None
def get_version():
"""Return the plugin version from ``bal/manifest.json`` (cached).
Zip-safe and independent of the current working directory. Falls back to
``"unknown"`` if the manifest cannot be read, so importing the plugin never
fails just because of version lookup.
"""
global _VERSION_CACHE
if _VERSION_CACHE is None:
try:
import importlib.resources
data = (
importlib.resources.files("bal")
.joinpath("manifest.json")
.read_text(encoding="utf-8")
)
_VERSION_CACHE = json.loads(data)["version"]
except Exception as e: # noqa: BLE001 - never break import over version
_logger.error(f"failed to read version from manifest.json: {e}")
_VERSION_CACHE = "unknown"
return _VERSION_CACHE
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Wallet-DB registration # Wallet-DB registration
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
@@ -120,9 +160,6 @@ class BalPlugin(BasePlugin):
layer (or unit tests) can use the plugin logic without importing Qt. layer (or unit tests) can use the plugin logic without importing Qt.
""" """
_version = None
__version__ = "0.6.0" # AUTOMATICALLY GENERATED DO NOT EDIT
# Command used to open an .ics calendar file, per operating system. # Command used to open an .ics calendar file, per operating system.
default_app = { default_app = {
"Linux": "xdg-open", "Linux": "xdg-open",
@@ -138,18 +175,11 @@ class BalPlugin(BasePlugin):
# Default geometry hint for some dialogs (kept from the original code). # Default geometry hint for some dialogs (kept from the original code).
SIZE = (159, 97) SIZE = (159, 97)
@property
def version(self): def version(self):
"""Return the plugin version, read once from the ``VERSION`` file.""" """Plugin version, read from ``bal/manifest.json`` (single source of
if not self._version: truth). See :func:`get_version`."""
try: return get_version()
f = ""
with open("{}/VERSION".format(self.plugin_dir), "r") as fi:
f = str(fi.read())
self._version = f.strip()
except Exception as e:
_logger.error(f"failed to get version: {e}")
self._version = "unknown"
return self._version
def __init__(self, parent, config, name): def __init__(self, parent, config, name):
self.logger = get_logger(__name__) self.logger = get_logger(__name__)

View File

@@ -23,7 +23,7 @@ from electrum.i18n import _
from electrum.logging import get_logger from electrum.logging import get_logger
from electrum.network import Network from electrum.network import Network
from .plugin_base import BalPlugin from .plugin_base import BalPlugin, get_version
# Per-request timeout (seconds) for interactive operations (ping / info / # Per-request timeout (seconds) for interactive operations (ping / info /
# list download). These fail fast (no retries) so a dead server does not # list download). These fail fast (no retries) so a dead server does not
@@ -272,7 +272,7 @@ class Willexecutors:
raise Exception("You are offline.") raise Exception("You are offline.")
_logger.debug(f"<-- {method} {url} {data}") _logger.debug(f"<-- {method} {url} {data}")
headers = {} headers = {}
headers["user-agent"] = f"BalPlugin v:{BalPlugin.__version__}" headers["user-agent"] = f"BalPlugin v:{get_version()}"
headers["Content-Type"] = "text/plain" headers["Content-Type"] = "text/plain"
if not handle_response: if not handle_response:
handle_response = Willexecutors.handle_response handle_response = Willexecutors.handle_response