diff --git a/api/api.py b/api/api.py index 29fcbb03..1f870676 100644 --- a/api/api.py +++ b/api/api.py @@ -10,7 +10,9 @@ import json import jwt import lnurl +import os import pyqrcode +import requests import secrets from sqlalchemy import desc from sqlalchemy.exc import IntegrityError @@ -28,7 +30,29 @@ @api_blueprint.route('/api/status', methods=['GET']) def status(): - return jsonify({'running': True, 'version': app.config['RELEASE_VERSION']}) + github_releases = requests.get(f"https://api.github.com/repos/{app.config['GITHUB_OWNER']}/{app.config['GITHUB_REPO']}/releases").json() + last_release = max(github_releases, key=lambda r: r['tag_name']) + return jsonify({'running': True, + 'release_version': app.config['RELEASE_VERSION'], + 'last_release_version': last_release['tag_name'] if last_release else ""}) + +@api_blueprint.route('/api/update', methods=['PUT']) +@user_required +def update(_user: m.User): + # TODO: not every user should be able to perform the update + + if not app.config['RELEASE_VERSION']: + # this would happen if the app was not installed from a GitHub build, but in some other way, + # like a "git clone" and performing a local build using for example `./scripts/prod.sh` + return jsonify({'message': "Unknown release version. Cannot request update."}), 400 + + if os.path.isfile(app.config['UPDATE_REQUESTED_FILE']): + return jsonify({'message': "Update already requested."}), 400 + + with open(app.config['UPDATE_REQUESTED_FILE'], 'w') as _f: + pass + + return jsonify({}) @api_blueprint.route('/api/login/lnurl', methods=['GET']) def auth_lnurl(): diff --git a/api/config.py b/api/config.py index 916261d7..54589ad0 100644 --- a/api/config.py +++ b/api/config.py @@ -3,6 +3,11 @@ RELEASE_VERSION = os.environ.get('RELEASE_VERSION', "") +GITHUB_OWNER = 'PlebeianTech' +GITHUB_REPO = 'plebeian-market' + +UPDATE_REQUESTED_FILE = "/state/UPDATE_REQUESTED" + SQLALCHEMY_TRACK_MODIFICATIONS = False DEBUG = bool(int(os.environ.get("DEBUG", 0))) PROPAGATE_EXCEPTIONS = False diff --git a/web/backoffice/src/lib/components/settings/Version.svelte b/web/backoffice/src/lib/components/settings/Version.svelte index 9c0fb5a7..d48f6aae 100644 --- a/web/backoffice/src/lib/components/settings/Version.svelte +++ b/web/backoffice/src/lib/components/settings/Version.svelte @@ -1,20 +1,29 @@ @@ -31,6 +40,7 @@

You are currently running Plebeian Market {version}.

+

The last available version is {lastVersion}.

diff --git a/web/backoffice/src/lib/services/api.ts b/web/backoffice/src/lib/services/api.ts index 99cc0320..20907da9 100644 --- a/web/backoffice/src/lib/services/api.ts +++ b/web/backoffice/src/lib/services/api.ts @@ -66,12 +66,26 @@ async function fetchAPIAsync(path, method, tokenValue, body, contentType) { return await fetch(`${API_BASE}${path}`, getFetchOptions(method, tokenValue, body, contentType)); } -export function getStatus(successCB: (version: string) => void, errorHandler = new ErrorHandler()) { +export function getStatus(successCB: (releaseVersion: string, lastReleaseVersion: string) => void, errorHandler = new ErrorHandler()) { fetchAPI("/status", 'GET', null, null, null, response => { if (response.status === 200) { response.json().then(data => { - successCB(data['version']); + successCB(data['release_version'], data['last_release_version']); + }); + } else { + errorHandler.handle(response); + } + }); +} + +export function putUpdate(tokenValue, successCB: () => void, errorHandler = new ErrorHandler()) { + fetchAPI("/update", 'PUT', tokenValue, + JSON.stringify({}), "application/json", + response => { + if (response.status === 200) { + response.json().then(_ => { + successCB(); }); } else { errorHandler.handle(response);