mirror of
https://github.com/cryptoadvance/specter-desktop.git
synced 2026-08-13 12:33:29 +02:00
move version checker to a thread (#421)
* move version checker to a thread * add binary version via version.txt * fix version comparison
This commit is contained in:
parent
5af4a809fa
commit
bd89c8c882
12 changed files with 140 additions and 47 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -13,4 +13,5 @@ key.pem
|
|||
*.dmg
|
||||
pyinstaller/specterd
|
||||
pyinstaller/release
|
||||
pyinstaller/version.txt
|
||||
.DS_Store
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
# pass version number as an argument
|
||||
|
||||
echo $1 > version.txt
|
||||
pip install -e ..
|
||||
pip install -r requirements.txt
|
||||
rm -rf build/ dist/ release/
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
# pass version number as an argument
|
||||
|
||||
echo $1 > version.txt
|
||||
pip install -e ..
|
||||
pip install -r requirements.txt
|
||||
rm -rf build/ dist/ release/
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
@ECHO OFF
|
||||
echo %1 > version.txt
|
||||
pip install -e ..
|
||||
pip install -r requirements.txt
|
||||
rmdir /s /q .\dist\
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ a = Analysis(['specter_desktop.py'],
|
|||
('../src/cryptoadvance/specter/static', 'static'),
|
||||
("./icons", "icons"),
|
||||
(mnemonic_path, 'mnemonic/wordlist'),
|
||||
("version.txt", "."),
|
||||
],
|
||||
hiddenimports=[
|
||||
'pkg_resources.py2_warn',
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ a = Analysis(['specterd.py'],
|
|||
datas=[('../src/cryptoadvance/specter/templates', 'templates'),
|
||||
('../src/cryptoadvance/specter/static', 'static'),
|
||||
(mnemonic_path, 'mnemonic/wordlist'),
|
||||
("version.txt", "."),
|
||||
],
|
||||
hiddenimports=[
|
||||
'pkg_resources.py2_warn',
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ from flask_login import login_required, login_user, logout_user, current_user
|
|||
from flask_login.config import EXEMPT_METHODS
|
||||
|
||||
|
||||
from .helpers import (alias, get_devices_with_keys_by_type,
|
||||
get_loglevel, get_version_info, run_shell, set_loglevel,
|
||||
from .helpers import (alias, get_devices_with_keys_by_type,
|
||||
get_loglevel, run_shell, set_loglevel,
|
||||
bcur2base64, get_txid, generate_mnemonic,
|
||||
get_startblock_by_chain, fslock)
|
||||
from .specter import Specter
|
||||
|
|
@ -1484,9 +1484,6 @@ def notify_upgrade():
|
|||
that there is an upgrade to specter.desktop
|
||||
:return the current version
|
||||
'''
|
||||
version_info={}
|
||||
version_info["current"], version_info["latest"], version_info["upgrade"] = get_version_info()
|
||||
app.logger.info("Upgrade? {}".format(version_info["upgrade"]))
|
||||
if version_info["upgrade"]:
|
||||
flash("There is a new version available. Consider strongly to upgrade to the new version {} with \"pip3 install cryptoadvance.specter --upgrade\"".format(version_info["latest"]), "info")
|
||||
return version_info["current"]
|
||||
if app.specter.version.upgrade:
|
||||
flash(f"Upgrade notification: new version {app.specter.version.latest} is available.", "info")
|
||||
return app.specter.version.current
|
||||
|
|
|
|||
|
|
@ -156,37 +156,6 @@ def get_loglevel(app):
|
|||
return loglevels[app.logger.getEffectiveLevel()]
|
||||
|
||||
|
||||
def get_version_info():
|
||||
''' Returns a triple of the current version (of the pip-package cryptoadvance.specter and
|
||||
the latest version and whether you should upgrade
|
||||
'''
|
||||
name="cryptoadvance.specter"
|
||||
try:
|
||||
# fail right away if it's a binary
|
||||
if getattr(sys, 'frozen', False):
|
||||
raise RuntimeError("Using frozen binary, verision unavailable")
|
||||
latest_version = str(subprocess.run([sys.executable, '-m', 'pip', 'install', '{}==random'.format(name)], capture_output=True, text=True))
|
||||
latest_version = latest_version[latest_version.find('(from versions:')+15:]
|
||||
latest_version = latest_version[:latest_version.find(')')]
|
||||
latest_version = latest_version.replace(' ','').split(',')[-1]
|
||||
|
||||
current_version = str(subprocess.run([sys.executable, '-m', 'pip', 'show', '{}'.format(name)], capture_output=True, text=True))
|
||||
current_version = current_version[current_version.find('Version:')+8:]
|
||||
current_version = current_version[:current_version.find('\\n')].replace(' ','')
|
||||
# master?
|
||||
if current_version == 'vx.y.z-get-replaced-by-release-script':
|
||||
current_version = 'custom'
|
||||
|
||||
if re.search(r"v?([\d+]).([\d+]).([\d+]).*", current_version):
|
||||
return current_version, latest_version, latest_version != current_version
|
||||
return current_version, latest_version, False
|
||||
except Exception as exc:
|
||||
# if pip is not installed or we are using python3.6 or below
|
||||
# we just don't show the version
|
||||
logger.error(exc)
|
||||
return "unknown", "unknown", False
|
||||
|
||||
|
||||
def hwi_get_config(specter):
|
||||
config = {
|
||||
'whitelisted_domains': 'http://127.0.0.1:25441/'
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ from .specter import Specter
|
|||
from .hwi_server import hwi_server
|
||||
from .user import User
|
||||
from .config import DATA_FOLDER
|
||||
from .util.version import VersionChecker
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
|
@ -51,6 +52,11 @@ def init_app(app, hwibridge=False, specter=None):
|
|||
app.logger.info("Initializing Specter")
|
||||
specter = Specter(DATA_FOLDER)
|
||||
|
||||
# version checker
|
||||
# checks for new versions once per hour
|
||||
specter.version = VersionChecker()
|
||||
specter.version.start()
|
||||
|
||||
login_manager = LoginManager()
|
||||
login_manager.init_app(app) # Enable Login
|
||||
login_manager.login_view = "login" # Enable redirects if unauthorized
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import random
|
|||
import time
|
||||
import zipfile
|
||||
from io import BytesIO
|
||||
from .helpers import deep_update, clean_psbt, get_version_info
|
||||
from .helpers import deep_update, clean_psbt
|
||||
from .rpc import autodetect_rpc_confs, get_default_datadir, RpcError
|
||||
from .rpc import BitcoinRPC
|
||||
from .device_manager import DeviceManager
|
||||
|
|
@ -470,9 +470,3 @@ class Specter:
|
|||
def restore_from_backup(self):
|
||||
pass
|
||||
|
||||
@property
|
||||
def specter_version(self):
|
||||
if not self._current_version:
|
||||
self._current_version = get_version_info()[0]
|
||||
return self._current_version
|
||||
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@
|
|||
<p class="warning mobile-only">ⓘ<br><b>Specter "Watch Only" Mode.</b><br>You are using Specter from a small-screen device for which some functionalities, including sending funds and creating new wallets are not yet supported.</p>
|
||||
<br>
|
||||
<div class="footer">
|
||||
<span>Specter Version: <strong>{{ specter.specter_version }}</strong></span>
|
||||
<span>Specter Version: <strong>{{ specter.version.current }}</strong></span>
|
||||
<a style="color: #fff; font-size: 1.1em; margin: 10px; text-align: center;" href="/about">
|
||||
About Specter<br>
|
||||
<img src="/static/img/icon.png" style="width: 35px;"/>
|
||||
|
|
|
|||
121
src/cryptoadvance/specter/util/version.py
Normal file
121
src/cryptoadvance/specter/util/version.py
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
import subprocess
|
||||
import sys
|
||||
import logging
|
||||
import re
|
||||
import threading
|
||||
import time
|
||||
import os
|
||||
import requests
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class VersionChecker:
|
||||
def __init__(self, name="cryptoadvance.specter"):
|
||||
self.name = name
|
||||
self.current = "unknown"
|
||||
self.latest = "unknown"
|
||||
self.upgrade = False
|
||||
self.running = False
|
||||
|
||||
def start(self):
|
||||
if not self.running:
|
||||
self.running = True
|
||||
self.thread = threading.Thread(target=self.loop)
|
||||
self.thread.daemon = True
|
||||
self.thread.start()
|
||||
|
||||
def stop(self):
|
||||
self.running = False
|
||||
|
||||
@property
|
||||
def info(self):
|
||||
return {
|
||||
"current": self.current,
|
||||
"latest": self.latest,
|
||||
"upgrade": self.upgrade,
|
||||
}
|
||||
|
||||
def loop(self, dt=3600):
|
||||
"""Checks for updates once per hour"""
|
||||
while self.running:
|
||||
self.current, self.latest, self.upgrade = self.get_version_info()
|
||||
logger.info(f"version checked. upgrade: {self.upgrade}")
|
||||
time.sleep(dt)
|
||||
|
||||
def get_binary_version(self):
|
||||
"""
|
||||
Get binary version: current, latest.
|
||||
Fails if version.txt is not present.
|
||||
Returns latest = "unknown" if fetch failed.
|
||||
"""
|
||||
version_file = "version.txt"
|
||||
if getattr(sys, 'frozen', False):
|
||||
version_file = os.path.join(sys._MEIPASS, 'version.txt')
|
||||
with open(version_file) as f:
|
||||
current = f.read().strip()
|
||||
try:
|
||||
releases = requests.get("https://api.github.com/repos/cryptoadvance/specter-desktop/releases").json()
|
||||
latest = releases[0]["name"]
|
||||
except:
|
||||
latest = "unknown"
|
||||
return current, latest
|
||||
|
||||
def get_pip_version(self):
|
||||
latest = str(subprocess.run([
|
||||
sys.executable, '-m', 'pip',
|
||||
'install', f'{self.name}==random'],
|
||||
capture_output=True, text=True))
|
||||
latest = latest[latest.find(
|
||||
'(from versions:')+15:]
|
||||
latest = latest[:latest.find(')')]
|
||||
latest = latest.replace(' ', '').split(',')[-1]
|
||||
|
||||
current = str(subprocess.run([
|
||||
sys.executable, '-m', 'pip',
|
||||
'show', f'{self.name}'],
|
||||
capture_output=True, text=True))
|
||||
current = current[current.find(
|
||||
'Version:')+8:]
|
||||
current = current[:current.find(
|
||||
'\\n')].replace(' ', '')
|
||||
# master?
|
||||
if current == 'vx.y.z-get-replaced-by-release-script':
|
||||
current = 'custom'
|
||||
# no need to check upgrades
|
||||
self.running = False
|
||||
return current, latest
|
||||
|
||||
def get_version_info(self):
|
||||
'''
|
||||
Returns a triple of the current version
|
||||
of the pip-package cryptoadvance.specter and
|
||||
the latest version and whether you should upgrade.
|
||||
'''
|
||||
# check if we have version.txt file
|
||||
# this is the case for binaries
|
||||
current = "unknown"
|
||||
latest = "unknown"
|
||||
# check binary version
|
||||
try:
|
||||
current, latest = self.get_binary_version()
|
||||
# if file not found
|
||||
except FileNotFoundError as exc:
|
||||
try:
|
||||
current, latest = self.get_pip_version()
|
||||
except Exception as exc:
|
||||
logger.error(exc)
|
||||
# other exceptions
|
||||
except Exception as exc:
|
||||
logger.error(exc)
|
||||
|
||||
# check that both current and latest versions match the pattern
|
||||
if (re.search(r"v?([\d+]).([\d+]).([\d+]).*", current) and
|
||||
re.search(r"v?([\d+]).([\d+]).([\d+]).*", latest)):
|
||||
return (
|
||||
current,
|
||||
latest,
|
||||
# check without leading v so v1.2.3 = 1.2.3
|
||||
latest.replace("v","") != current.replace("v","")
|
||||
)
|
||||
return current, latest, False
|
||||
Loading…
Add table
Add a link
Reference in a new issue