Skip to content

Commit

Permalink
Add progress on library update
Browse files Browse the repository at this point in the history
  • Loading branch information
undyingwraith committed Jan 9, 2025
1 parent 75f8240 commit 395901d
Show file tree
Hide file tree
Showing 11 changed files with 50 additions and 34 deletions.
2 changes: 1 addition & 1 deletion packages/core/src/Regexes.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const Regexes = {
VideoFile: (ext = 'mpd') => new RegExp(`^([\\w\\s':\\.\\-!]+)(?: \\((\\d{4})\\))?\\.${ext}$`),
VideoFile: (ext = 'mpd') => new RegExp(`^([\\w\\s':\\.\\-&!]+)(?: \\((\\d{4})\\))?\\.${ext}$`),
Thumbnail: /thumb\d*\.(jpg|jpeg|png)$/,
Poster: /poster\d*\.(jpg|jpeg|png)$/,
LangCheck: /^((?:(en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)|(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang))|((?:([A-Za-z]{2,3}(-(?:[A-Za-z]{3}(-[A-Za-z]{3}){0,2}))?)|[A-Za-z]{4}|[A-Za-z]{5,8})(-(?:[A-Za-z]{4}))?(-(?:[A-Za-z]{2}|[0-9]{3}))?(-(?:[A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3}))*(-(?:[0-9A-WY-Za-wy-z](-[A-Za-z0-9]{2,8})+))*(-(?:x(-[A-Za-z0-9]{1,8})+))?)|(?:x(-[A-Za-z0-9]{1,8})+))$/i // Source: https://www.regextester.com/103066
Expand Down
13 changes: 6 additions & 7 deletions packages/core/src/Services/IndexManager.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Signal } from '@preact/signals-core';
import { inject, injectable, postConstruct, preDestroy } from 'inversify';
import { IIndexManager, IIpfsService, IIpfsServiceSymbol, ILibrary, ILibraryIndex, IObjectStore, IObjectStoreSymbol, IProfile, IProfileSymbol, ITask, ITaskManager, ITaskManagerSymbol, ITranslationService, ITranslationServiceSymbol } from 'ipmc-interfaces';
import { IIndexManager, IIpfsService, IIpfsServiceSymbol, ILibrary, ILibraryIndex, IObjectStore, IObjectStoreSymbol, IOnProgress, IProfile, IProfileSymbol, ITask, ITaskManager, ITaskManagerSymbol, ITranslationService, ITranslationServiceSymbol } from 'ipmc-interfaces';
import { IIndexFetcher, MovieIndexFetcher, SeriesIndexFetcher } from './Indexer';

@injectable()
Expand Down Expand Up @@ -42,8 +42,6 @@ export class IndexManager implements IIndexManager {

public indexes = new Map<string, Signal<ILibraryIndex<any> | undefined>>();

public tasks = new Signal<ITask[]>([]);

private getIndexStorageKey(name: string) {
return `${this.profile.id}_index_${name}`;
}
Expand All @@ -52,8 +50,9 @@ export class IndexManager implements IIndexManager {
for (const library of this.libraries.values()) {
const lib = library.value;
if (!this.updates.has(lib.name)) {
this.updates.add(lib.name);
this.taskManager.runTask({
task: () => this.updateLibrary(lib),
task: (onProgress) => this.updateLibrary(lib, onProgress),
title: this.translationService.translate('UpdatingLibrary', { name: lib.name }),
onEnd: () => {
this.updates.delete(lib.name);
Expand All @@ -63,7 +62,7 @@ export class IndexManager implements IIndexManager {
}
}

private async updateLibrary(library: ILibrary): Promise<void> {
private async updateLibrary(library: ILibrary, onProgress: IOnProgress): Promise<void> {
const index = this.indexes.get(library.name);
if (library.upstream != undefined && index != undefined) {
try {
Expand All @@ -74,7 +73,7 @@ export class IndexManager implements IIndexManager {
throw new Error(`Unknown library type [${library.type}]`);
}

const newIndex = await indexer.fetchIndex(cid);
const newIndex = await indexer.fetchIndex(cid, onProgress);

index.value = {
cid: cid,
Expand All @@ -92,7 +91,7 @@ export class IndexManager implements IIndexManager {

private libraries = new Map<string, Signal<ILibrary>>();

private updates = new Map<string, Promise<void>>();
private updates = new Set<string>();

private timer: any;
}
5 changes: 3 additions & 2 deletions packages/core/src/Services/Indexer/IIndexFetcher.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { ILibrary } from 'ipmc-interfaces';
import { ILibrary, IOnProgress } from 'ipmc-interfaces';

export interface IIndexFetcher<TIndex> {
/**
* Fetches the index of the specified CID.
* @param cid cid to index.
* @param onProgress function to update progress.
*/
fetchIndex(cid: string): Promise<TIndex>;
fetchIndex(cid: string, onProgress: IOnProgress): Promise<TIndex>;

/**
* Checks wheter the indexer can handler specified {@link ILibrary}.
Expand Down
7 changes: 4 additions & 3 deletions packages/core/src/Services/Indexer/MovieIndexFetcher.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IFileInfo, IIpfsService, ILibrary, IMovieMetaData } from 'ipmc-interfaces';
import { IFileInfo, IIpfsService, ILibrary, IMovieMetaData, IOnProgress } from 'ipmc-interfaces';
import { Regexes } from '../../Regexes';
import { IIndexFetcher } from './IIndexFetcher';

Expand All @@ -8,15 +8,16 @@ export class MovieIndexFetcher implements IIndexFetcher<IMovieMetaData[]> {

public version = '0';

public async fetchIndex(cid: string): Promise<IMovieMetaData[]> {
public async fetchIndex(cid: string, onProgress: IOnProgress): Promise<IMovieMetaData[]> {
const files = (await this.node.ls(cid)).filter(f => f.type == 'dir');
const index = [];
for (const file of files) {
for (const [i, file] of files.entries()) {
try {
index.push(await this.extractMovieMetaData(this.node, file));
} catch (ex) {
console.error(ex);
}
onProgress(i, files.length);
}

return index;
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/Services/TaskManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ export class TaskManager implements ITaskManager {
title: task.title,
};
this.status.value = [...this.status.value, status];
task.task((progress) => {
this.status.value = this.status.value.map(t => t.id === status.id ? ({ ...t, progress }) : t);
task.task((progress, total) => {
this.status.value = this.status.value.map(t => t.id === status.id ? ({ ...t, progress, total }) : t);
})
.finally(() => {
this.status.value = this.status.value.filter(s => s.id !== status.id);
Expand Down
4 changes: 3 additions & 1 deletion packages/interfaces/src/Services/ITaskManager/ITask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export interface ITask {
/**
* The task to run.
*/
task: (onProgress: (progress: number) => void) => Promise<void>;
task: (onProgress: IOnProgress) => Promise<void>;

/**
* Start event handler.
Expand All @@ -19,3 +19,5 @@ export interface ITask {
*/
onEnd?: () => void | Promise<void>;
}

export type IOnProgress = (progress: number, total?: number) => void;
5 changes: 5 additions & 0 deletions packages/interfaces/src/Services/ITaskManager/ITaskStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ export interface ITaskStatus {
*/
progress?: number;

/**
* Total progress of the {@link ITask} (if available).
*/
total?: number;

/**
* Title of the {@link ITask}.
*/
Expand Down
2 changes: 1 addition & 1 deletion packages/interfaces/src/Services/ITaskManager/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export { type ITask } from './ITask';
export { type ITask, type IOnProgress } from './ITask';
export { type ITaskManager, ITaskManagerSymbol } from './ITaskManager';
export { type ITaskStatus } from './ITaskStatus';
6 changes: 4 additions & 2 deletions packages/ui/src/components/atoms/Loader.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { CircularProgress } from "@mui/material";
import React from "react";

export function Loader() {
const normalise = (value?: number, max: number = 100) => value ? (value * 100) / max : undefined;

export function Loader(props: { progress?: number, total?: number; }) {
return (
<CircularProgress />
<CircularProgress variant={props.progress ? 'determinate' : 'indeterminate'} value={normalise(props.progress, props.total)} />
);
}
33 changes: 20 additions & 13 deletions packages/ui/src/components/organisms/LibraryHomeScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,26 @@ export function LibraryHomeScreen() {
const _t = useTranslation();
const taskManager = useService<ITaskManager>(ITaskManagerSymbol);

const status = useComputed(() => taskManager.status.value.length > 0 ? (
<Card>
<CardHeader title={_t('ActiveTasks')} />
{taskManager.status.value.map(t => (
<CardContent>
<Stack direction={"row"} gap={1}>
<Loader />
<Typography>{t.title}</Typography>
</Stack>
</CardContent>
))}
</Card>
) : undefined);
const status = useComputed(() => {
const status = taskManager.status.value;
if (status.length > 0) {
return (
<Card>
<CardHeader title={_t('ActiveTasks')} />
{taskManager.status.value.map(t => (
<CardContent>
<Stack direction={"row"} gap={1}>
<Loader progress={t.progress} total={t.total} />
<Typography>{t.title}</Typography>
</Stack>
</CardContent>
))}
</Card>
);
} else {
return undefined;
}
});

return (<Box>
<Typography>{_t('Home')}</Typography>
Expand Down
3 changes: 1 addition & 2 deletions packages/ui/src/components/pages/LibraryManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@ import { IProfile, IProfileSymbol } from "ipmc-interfaces";
import React from "react";
import { Route, useLocation } from 'wouter';
import { useService } from '../../context/AppContext';
import { useTranslation } from '../../hooks/useTranslation';
import { useLinkedSignal, useTranslation } from '../../hooks';
import { ErrorBoundary } from '../atoms/ErrorBoundary';
import { Library } from '../organisms/Library';
import { LibraryAppBar } from "../organisms/LibraryAppBar";
import { LibraryHomeScreen } from '../organisms/LibraryHomeScreen';
import { useLinkedSignal } from '../../hooks';

const icons = {
movie: <MovieIcon />,
Expand Down

0 comments on commit 395901d

Please sign in to comment.