Skip to content

Commit

Permalink
Add ability to request the API to update itself.
Browse files Browse the repository at this point in the history
  • Loading branch information
ibz committed Feb 14, 2024
1 parent dd60340 commit 38abf47
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 9 deletions.
26 changes: 25 additions & 1 deletion api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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():
Expand Down
5 changes: 5 additions & 0 deletions api/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
22 changes: 16 additions & 6 deletions web/backoffice/src/lib/components/settings/Version.svelte
Original file line number Diff line number Diff line change
@@ -1,20 +1,29 @@
<script lang="ts">
import { onMount } from 'svelte';
import { page } from "$app/stores";
import { getStatus } from "$lib/services/api";
import { ErrorHandler, getStatus, putUpdate } from "$lib/services/api";
import { Info, token } from "$sharedLib/stores";
export let onSave: () => void = () => {};
let updateButtonActive = false;
let version: string | null = null;
let lastVersion: string | null = null;
let version;
let saving = false;
let inRequest = false;
function update() {
inRequest = true;
putUpdate($token,
() => {
Info.set("Update requested!");
inRequest = false;
},
new ErrorHandler(true, () => inRequest = false));
}
let updateButtonActive = version !== lastVersion && !inRequest;
onMount(async () => {
getStatus((v) => { version = v; });
getStatus((v, lv) => { version = v; });
});
</script>

Expand All @@ -31,6 +40,7 @@

<div class="w-full flex items-center justify-center mt-8">
<p class="text-2xl">You are currently running Plebeian Market {version}.</p>
<p class="text-2xl">The last available version is {lastVersion}.</p>
</div>

<div class="flex justify-center items-center mt-4 h-15">
Expand Down
18 changes: 16 additions & 2 deletions web/backoffice/src/lib/services/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 38abf47

Please sign in to comment.