🪄 Adds api service with updates
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
import { user } from '$lib/stores/user';
|
||||
import { get } from 'svelte/store';
|
||||
import { Err, Ok, type Result } from './utilities';
|
||||
|
||||
export namespace api {
|
||||
export function get<TResponse>(endpoint: string, params?: RequestInit) {
|
||||
return sendRequest<TResponse>(endpoint, 'GET', null, params);
|
||||
}
|
||||
|
||||
export function post<TResponse>(endpoint: string, data?: unknown) {
|
||||
return sendRequest<TResponse>(endpoint, 'POST', data);
|
||||
}
|
||||
|
||||
export function put<TResponse>(endpoint: string, data?: unknown) {
|
||||
return sendRequest<TResponse>(endpoint, 'PUT', data);
|
||||
}
|
||||
|
||||
export function remove<TResponse>(endpoint: string) {
|
||||
return sendRequest<TResponse>(endpoint, 'DELETE');
|
||||
}
|
||||
}
|
||||
|
||||
async function sendRequest<TResponse>(
|
||||
endpoint: string,
|
||||
method: string,
|
||||
data?: unknown,
|
||||
params?: RequestInit
|
||||
): Promise<Result<TResponse, Error>> {
|
||||
const user_token = get(user).bearer_token;
|
||||
const body = data !== null && typeof data !== 'undefined' ? JSON.stringify(data) : undefined;
|
||||
|
||||
const request = {
|
||||
...params,
|
||||
method,
|
||||
body,
|
||||
headers: {
|
||||
...params?.headers,
|
||||
Authorization: user_token ? 'Bearer ' + user_token : 'Basic',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
};
|
||||
|
||||
let response;
|
||||
|
||||
try {
|
||||
response = await fetch(endpoint, request);
|
||||
} catch (error) {
|
||||
return Err.new(new Error(), 'An error has occurred');
|
||||
}
|
||||
|
||||
const isResponseOk = response.status >= 200 && response.status < 400;
|
||||
if (!isResponseOk) {
|
||||
if (response.status === 401) {
|
||||
return Err.new(new ApiError(response), 'User was not authorized');
|
||||
}
|
||||
return Err.new(new ApiError(response), 'An error has occurred');
|
||||
}
|
||||
|
||||
const contentType = response.headers.get('Content-Type') ?? response.headers.get('Content-Type');
|
||||
if (contentType && contentType.includes('application/json')) {
|
||||
const data = await response.json();
|
||||
return Ok.new(data as TResponse);
|
||||
} else {
|
||||
// Handle empty object as response
|
||||
return Ok.new(null as TResponse);
|
||||
}
|
||||
}
|
||||
|
||||
export class ApiError extends Error {
|
||||
constructor(public readonly response: Response) {
|
||||
super(`${response.status}`);
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,8 @@
|
||||
import GithubUpdateDialog from '$lib/components/GithubUpdateDialog.svelte';
|
||||
import { compareVersions } from 'compare-versions';
|
||||
import { onMount } from 'svelte';
|
||||
import { api } from '$lib/api';
|
||||
import type { GithubRelease } from '$lib/models';
|
||||
|
||||
export let update = false;
|
||||
|
||||
@@ -17,67 +19,55 @@
|
||||
let firmwareDownloadLink: string;
|
||||
|
||||
async function getGithubAPI() {
|
||||
try {
|
||||
const response = await fetch(
|
||||
'https://api.github.com/repos/' + $page.data.github + '/releases/latest',
|
||||
{
|
||||
method: 'GET',
|
||||
headers: {
|
||||
accept: 'application/vnd.github+json',
|
||||
'X-GitHub-Api-Version': '2022-11-28'
|
||||
}
|
||||
}
|
||||
);
|
||||
const results = await response.json();
|
||||
if (results.message == "Not Found") {
|
||||
console.error('Error: Could not find releases in the repository');
|
||||
return;
|
||||
const headers = {
|
||||
accept: 'application/vnd.github+json',
|
||||
'X-GitHub-Api-Version': '2022-11-28'
|
||||
}
|
||||
const result = await api.get<GithubRelease>(`https://api.github.com/repos/${$page.data.github}/releases/latest`, {headers})
|
||||
if (result.inner.message === "404" || result.inner.message == "Not Found") {
|
||||
console.warn('Error: Could not find releases in the repository');
|
||||
return
|
||||
}
|
||||
if (result.isErr()) {
|
||||
console.error('Error:', result.inner);
|
||||
return
|
||||
}
|
||||
|
||||
const results = result.inner;
|
||||
update = false;
|
||||
firmwareVersion = '';
|
||||
|
||||
if (compareVersions(results.tag_name, $page.data.features.firmware_version) === 1) {
|
||||
// iterate over assets and find the correct one
|
||||
for (let i = 0; i < results.assets.length; i++) {
|
||||
// check if the asset is of type *.bin
|
||||
if (
|
||||
results.assets[i].name.includes('.bin') &&
|
||||
results.assets[i].name.includes($page.data.features.firmware_built_target)
|
||||
) {
|
||||
update = true;
|
||||
firmwareVersion = results.tag_name;
|
||||
firmwareDownloadLink = results.assets[i].browser_download_url;
|
||||
notifications.info('Firmware update available.', 5000);
|
||||
}
|
||||
}
|
||||
|
||||
update = false;
|
||||
firmwareVersion = '';
|
||||
|
||||
if (compareVersions(results.tag_name, $page.data.features.firmware_version) === 1) {
|
||||
// iterate over assets and find the correct one
|
||||
for (let i = 0; i < results.assets.length; i++) {
|
||||
// check if the asset is of type *.bin
|
||||
if (
|
||||
results.assets[i].name.includes('.bin') &&
|
||||
results.assets[i].name.includes($page.data.features.firmware_built_target)
|
||||
) {
|
||||
update = true;
|
||||
firmwareVersion = results.tag_name;
|
||||
firmwareDownloadLink = results.assets[i].browser_download_url;
|
||||
notifications.info('Firmware update available.', 5000);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function postGithubDownload(url: string) {
|
||||
try {
|
||||
const apiResponse = await fetch('/api/downloadUpdate', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: $page.data.features.security ? 'Bearer ' + $user.bearer_token : 'Basic',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ download_url: url })
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
}
|
||||
const result = await api.post('/api/downloadUpdate', { download_url: url });
|
||||
if (result.isErr()){
|
||||
console.error('Error:', result.inner);
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
onMount(async () => {
|
||||
if ($page.data.features.download_firmware && (!$page.data.features.security || $user.admin)) {
|
||||
getGithubAPI();
|
||||
await getGithubAPI();
|
||||
const interval = setInterval(
|
||||
async () => {
|
||||
getGithubAPI();
|
||||
await getGithubAPI();
|
||||
},
|
||||
60 * 60 * 1000
|
||||
); // once per hour
|
||||
|
||||
+16
-1
@@ -7,6 +7,17 @@ export interface ControllerInput {
|
||||
speed: number;
|
||||
}
|
||||
|
||||
export type GithubRelease = {
|
||||
message: string;
|
||||
tag_name: string;
|
||||
assets: Array<{
|
||||
name: string;
|
||||
browser_download_url: string;
|
||||
}>;
|
||||
};
|
||||
|
||||
export type JWT = { access_token: string };
|
||||
|
||||
export type angles = number[] | Int16Array;
|
||||
|
||||
export type WifiStatus = {
|
||||
@@ -26,7 +37,11 @@ export type WifiStatus = {
|
||||
export type WifiSettings = {
|
||||
hostname: string;
|
||||
priority_RSSI: boolean;
|
||||
wifi_networks: networkItem[];
|
||||
wifi_networks: NetworkItem[];
|
||||
};
|
||||
|
||||
export type NetworkList = {
|
||||
networks: NetworkItem[];
|
||||
};
|
||||
|
||||
export type KnownNetworkItem = {
|
||||
|
||||
@@ -7,3 +7,30 @@ export const humanFileSize = (size: number): string => {
|
||||
export const capitalize = (str: string): string => {
|
||||
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
|
||||
};
|
||||
|
||||
export const convertSeconds = (seconds: number) => {
|
||||
// Calculate the number of seconds, minutes, hours, and days
|
||||
let minutes = Math.floor(seconds / 60);
|
||||
let hours = Math.floor(minutes / 60);
|
||||
let days = Math.floor(hours / 24);
|
||||
|
||||
// Calculate the remaining hours, minutes, and seconds
|
||||
hours = hours % 24;
|
||||
minutes = minutes % 60;
|
||||
seconds = seconds % 60;
|
||||
|
||||
// Create the formatted string
|
||||
let result = '';
|
||||
if (days > 0) {
|
||||
result += days + ' day' + (days > 1 ? 's' : '') + ' ';
|
||||
}
|
||||
if (hours > 0) {
|
||||
result += hours + ' hour' + (hours > 1 ? 's' : '') + ' ';
|
||||
}
|
||||
if (minutes > 0) {
|
||||
result += minutes + ' minute' + (minutes > 1 ? 's' : '') + ' ';
|
||||
}
|
||||
result += seconds + ' second' + (seconds > 1 ? 's' : '');
|
||||
|
||||
return result;
|
||||
};
|
||||
Reference in New Issue
Block a user