WIP refactor container and queuing system (#206)

* refactor microservices to machine-learning

* Update tGithub issue template with correct task syntax

* Added microservices container

* Communicate between service based on queue system

* added dependency

* Fixed problem with having to import BullQueue into the individual service

* Added todo

* refactor server into monorepo with microservices

* refactor database and entity to library

* added simple migration

* Move migrations and database config to library

* Migration works in library

* Cosmetic change in logging message

* added user dto

* Fixed issue with testing not able to find the shared library

* Clean up library mapping path

* Added webp generator to microservices

* Update Github Action build latest

* Fixed issue NPM cannot install due to conflict witl Bull Queue

* format project with prettier

* Modified docker-compose file

* Add GH Action for Staging build:

* Fixed GH action job name

* Modified GH Action to only build & push latest when pushing to main

* Added Test 2e2 Github Action

* Added Test 2e2 Github Action

* Implemented microservice to extract exif

* Added cronjob to scan and generate webp thumbnail  at midnight

* Refactor to ireduce hit time to database when running microservices

* Added error handling to asset services that handle read file from disk

* Added video transcoding queue to process one video at a time

* Fixed loading spinner on web while loading covering the info panel

* Add mechanism to show new release announcement to web and mobile app (#209)

* Added changelog page

* Fixed issues based on PR comments

* Fixed issue with video transcoding run on the server

* Change entry point content for backward combatibility when starting up server

* Added announcement box

* Added error handling to failed silently when the app version checking is not able to make the request to GITHUB

* Added new version announcement overlay

* Update message

* Added messages

* Added logic to check and show announcement

* Add method to handle saving new version

* Added button to dimiss the acknowledge message

* Up version for deployment to the app store
This commit is contained in:
Alex 2022-06-11 16:12:06 -05:00 committed by GitHub
parent 397f8c70b4
commit a8220172f8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
192 changed files with 1823 additions and 2117 deletions

View file

@ -1,60 +1,59 @@
import { serverEndpoint } from './constants';
type ISend = {
method: string,
path: string,
data?: any,
token: string
customHeaders?: Record<string, string>,
}
method: string;
path: string;
data?: any;
token: string;
customHeaders?: Record<string, string>;
};
type IOption = {
method: string,
headers: Record<string, string>,
body: any
}
method: string;
headers: Record<string, string>;
body: any;
};
async function send({ method, path, data, token, customHeaders }: ISend) {
const opts: IOption = { method, headers: {} } as IOption;
const opts: IOption = { method, headers: {} } as IOption;
if (data) {
opts.headers['Content-Type'] = 'application/json';
opts.body = JSON.stringify(data);
}
if (data) {
opts.headers['Content-Type'] = 'application/json';
opts.body = JSON.stringify(data);
}
if (customHeaders) {
console.log(customHeaders);
// opts.headers[customHeader.$1]
}
if (customHeaders) {
console.log(customHeaders);
// opts.headers[customHeader.$1]
}
if (token) {
opts.headers['Authorization'] = `Bearer ${token}`;
}
if (token) {
opts.headers['Authorization'] = `Bearer ${token}`;
}
return fetch(`${serverEndpoint}/${path}`, opts)
.then((r) => r.text())
.then((json) => {
try {
return JSON.parse(json);
} catch (err) {
return json;
}
});
return fetch(`${serverEndpoint}/${path}`, opts)
.then((r) => r.text())
.then((json) => {
try {
return JSON.parse(json);
} catch (err) {
return json;
}
});
}
export function getRequest(path: string, token: string, customHeaders?: Record<string, string>) {
return send({ method: 'GET', path, token, customHeaders });
return send({ method: 'GET', path, token, customHeaders });
}
export function delRequest(path: string, token: string, customHeaders?: Record<string, string>) {
return send({ method: 'DELETE', path, token, customHeaders });
return send({ method: 'DELETE', path, token, customHeaders });
}
export function postRequest(path: string, data: any, token: string, customHeaders?: Record<string, string>) {
return send({ method: 'POST', path, data, token, customHeaders });
return send({ method: 'POST', path, data, token, customHeaders });
}
export function putRequest(path: string, data: any, token: string, customHeaders?: Record<string, string>) {
return send({ method: 'PUT', path, data, token, customHeaders });
}
return send({ method: 'PUT', path, data, token, customHeaders });
}

View file

@ -67,7 +67,7 @@
</video>
{#if isVideoLoading}
<div class="absolute w-full h-full bg-black/50 flex place-items-center place-content-center">
<div class="absolute flex place-items-center place-content-center">
<LoadingSpinner />
</div>
{/if}

View file

@ -0,0 +1,61 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { createEventDispatcher } from 'svelte';
import { page } from '$app/stores';
import FullScreenModal from './full-screen-modal.svelte';
export let localVersion: string;
export let remoteVersion: string;
const acknowledgeClickHandler = () => {
localStorage.setItem('appVersion', remoteVersion);
goto($page.url.pathname);
};
</script>
<div class="absolute top-0 left-0 w-screen h-screen">
<FullScreenModal on:clickOutside={() => console.log('Click outside')}>
<div class="max-w-[500px] z-[99999] border bg-immich-bg p-10 rounded-xl">
<p class="text-2xl ">🎉 NEW VERSION AVAILABLE 🎉</p>
<br />
<section class="max-h-[400px] overflow-y-auto">
<div class="font-thin">
Hi friend, there is a new release of <span class="font-immich-title text-immich-primary font-bold"
>IMMICH</span
>, please take your time to visit the
<span class="underline font-medium"
><a href="https://github.com/alextran1502/immich/releases/latest" target="_blank" rel="noopener noreferrer"
>release note</a
></span
>
and ensure your <code>docker-compose</code>, and <code>.env</code> setup is up-to-date to prevent any misconfigurations,
especially if you use WatchTower or any mechanism that handles updating your application automatically.
</div>
{#if remoteVersion == 'v1.11.0_17-dev'}
<div class="mt-2 font-thin">
This specific version <span class="font-medium">v1.11.0_17-dev</span> includes changes in the docker-compose
setup that added additional containters. Please make sure to update the docker-compose file, pull new images
and check your setup for the latest features and bug fixes.
</div>
{/if}
</section>
<div class="font-thin mt-4">Your friend, Alex</div>
<div class="text-xs mt-8">
<code>Local Version {localVersion}</code>
<br />
<code>Remote Version {remoteVersion}</code>
</div>
<div class="text-right mt-4">
<button
class="bg-immich-primary text-gray-50 hover:bg-immich-primary/90 py-2 px-4 rounded-lg font-medium shadow-lg transition-all"
on:click={acknowledgeClickHandler}>Acknowledge</button
>
</div>
</div>
</FullScreenModal>
</div>

View file

@ -11,7 +11,7 @@
out:fade={{ duration: 100 }}
class="absolute w-full h-full bg-black/40 z-[100] flex place-items-center place-content-center "
>
<div class="bg-immich-bg z-[9999] rounded-md" use:clickOutside on:outclick={() => dispatch('clickOutside')}>
<div class="z-[9999]" use:clickOutside on:outclick={() => dispatch('clickOutside')}>
<slot />
</div>
</section>

View file

@ -22,7 +22,6 @@
};
const navigateToAdmin = () => {
console.log('Navigating to admin page');
goto('/admin');
};
</script>

View file

@ -5,6 +5,7 @@
import Cloud from 'svelte-material-icons/Cloud.svelte';
import Dns from 'svelte-material-icons/Dns.svelte';
import LoadingSpinner from './loading-spinner.svelte';
import { goto } from '$app/navigation';
type ServerInfoType = {
diskAvailable: string;
@ -77,7 +78,11 @@
<div class="text-xs">
<p class="text-sm font-medium text-immich-primary">Server</p>
<input class="border p-2 rounded-md bg-gray-200 mt-2 text-immich-primary font-medium" value="{endpoint}" disabled="true">
<input
class="border p-2 rounded-md bg-gray-200 mt-2 text-immich-primary font-medium"
value={endpoint}
disabled={true}
/>
<div class="flex justify-items-center justify-between mt-2">
<p>Status</p>
@ -94,4 +99,10 @@
</div>
</div>
</div>
<!-- <div>
<hr class="ml-5 my-4" />
</div>
<button class="text-xs ml-5 underline hover:cursor-pointer text-immich-primary" on:click={() => goto('/changelog')}
>Changelog</button
> -->
</div>

View file

@ -0,0 +1,50 @@
type CheckAppVersionReponse = {
shouldShowAnnouncement: boolean;
localVersion?: string;
remoteVersion?: string;
};
type GithubRelease = {
tag_name: string;
};
export const checkAppVersion = async (): Promise<CheckAppVersionReponse> => {
const res = await fetch('https://api.github.com/repos/alextran1502/immich/releases/latest', {
headers: {
Accept: 'application/vnd.github.v3+json',
},
});
if (res.status == 200) {
const latestRelease = (await res.json()) as GithubRelease;
const appVersion = localStorage.getItem('appVersion');
if (!appVersion) {
return {
shouldShowAnnouncement: true,
remoteVersion: latestRelease.tag_name,
localVersion: 'empty',
};
}
if (appVersion != latestRelease.tag_name) {
return {
shouldShowAnnouncement: true,
remoteVersion: latestRelease.tag_name,
localVersion: appVersion,
};
}
return {
shouldShowAnnouncement: false,
remoteVersion: latestRelease.tag_name,
localVersion: appVersion,
};
} else {
return {
shouldShowAnnouncement: false,
remoteVersion: '0',
localVersion: '0',
};
}
};