From f31ccf2d6aa9eb0e81e8759527195b7754eb7df3 Mon Sep 17 00:00:00 2001 From: Manuel <30572287+manuel-rw@users.noreply.github.com> Date: Mon, 4 Nov 2024 10:02:54 +0100 Subject: [PATCH] feat: #1408 add local icon repository (#1413) --- packages/cron-jobs/src/jobs/icons-updater.ts | 2 +- packages/icons/package.json | 1 + packages/icons/src/icons-fetcher.ts | 2 ++ .../repositories/github.icon-repository.ts | 7 ++--- .../repositories/jsdelivr.icon-repository.ts | 2 +- .../src/repositories/local.icon-repository.ts | 26 +++++++++++++++++++ packages/icons/src/types/repository-icon.ts | 2 +- pnpm-lock.yaml | 7 +++-- 8 files changed, 39 insertions(+), 10 deletions(-) create mode 100644 packages/icons/src/repositories/local.icon-repository.ts diff --git a/packages/cron-jobs/src/jobs/icons-updater.ts b/packages/cron-jobs/src/jobs/icons-updater.ts index 0529e2e52..9c4aca75d 100644 --- a/packages/cron-jobs/src/jobs/icons-updater.ts +++ b/packages/cron-jobs/src/jobs/icons-updater.ts @@ -62,7 +62,7 @@ export const iconsUpdaterJob = createCronJob("iconsUpdater", EVERY_WEEK, { id: createId(), checksum: icon.checksum, name: icon.fileNameWithExtension, - url: icon.imageUrl.href, + url: icon.imageUrl, iconRepositoryId: repositoryIconGroupId, }); countInserted++; diff --git a/packages/icons/package.json b/packages/icons/package.json index c0a85a18a..2e556df70 100644 --- a/packages/icons/package.json +++ b/packages/icons/package.json @@ -23,6 +23,7 @@ "prettier": "@homarr/prettier-config", "dependencies": { "@homarr/common": "workspace:^0.1.0", + "@homarr/db": "workspace:^0.1.0", "@homarr/log": "workspace:^0.1.0" }, "devDependencies": { diff --git a/packages/icons/src/icons-fetcher.ts b/packages/icons/src/icons-fetcher.ts index ba60296a7..d1be6a75a 100644 --- a/packages/icons/src/icons-fetcher.ts +++ b/packages/icons/src/icons-fetcher.ts @@ -1,5 +1,6 @@ import { GitHubIconRepository } from "./repositories/github.icon-repository"; import { JsdelivrIconRepository } from "./repositories/jsdelivr.icon-repository"; +import { LocalIconRepository } from "./repositories/local.icon-repository"; import type { RepositoryIconGroup } from "./types"; const repositories = [ @@ -43,6 +44,7 @@ const repositories = [ new URL("https://data.jsdelivr.com/v1/packages/gh/loganmarchione/homelab-svg-assets@main?structure=flat"), "https://cdn.jsdelivr.net/gh/loganmarchione/homelab-svg-assets/{0}", ), + new LocalIconRepository(), ]; export const fetchIconsAsync = async (): Promise => { diff --git a/packages/icons/src/repositories/github.icon-repository.ts b/packages/icons/src/repositories/github.icon-repository.ts index eb5e92b90..2152a450b 100644 --- a/packages/icons/src/repositories/github.icon-repository.ts +++ b/packages/icons/src/repositories/github.icon-repository.ts @@ -35,11 +35,8 @@ export class GitHubIconRepository extends IconRepository { .map(({ path, size: sizeInBytes, sha: checksum }) => { const file = parse(path); const fileNameWithExtension = file.base; - const imageUrl = new URL( - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - this.repositoryBlobUrlTemplate!.replace("{0}", path).replace("{1}", file.name), - ); - + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const imageUrl = this.repositoryBlobUrlTemplate!.replace("{0}", path).replace("{1}", file.name); return { imageUrl, fileNameWithExtension, diff --git a/packages/icons/src/repositories/jsdelivr.icon-repository.ts b/packages/icons/src/repositories/jsdelivr.icon-repository.ts index c611fcd7e..2b9bd944b 100644 --- a/packages/icons/src/repositories/jsdelivr.icon-repository.ts +++ b/packages/icons/src/repositories/jsdelivr.icon-repository.ts @@ -33,7 +33,7 @@ export class JsdelivrIconRepository extends IconRepository { const fileNameWithExtension = file.base; return { - imageUrl: new URL(this.repositoryBlobUrlTemplate.replace("{0}", path).replace("{1}", file.name)), + imageUrl: this.repositoryBlobUrlTemplate.replace("{0}", path).replace("{1}", file.name), fileNameWithExtension, local: false, sizeInBytes, diff --git a/packages/icons/src/repositories/local.icon-repository.ts b/packages/icons/src/repositories/local.icon-repository.ts new file mode 100644 index 000000000..7fc7c74d9 --- /dev/null +++ b/packages/icons/src/repositories/local.icon-repository.ts @@ -0,0 +1,26 @@ +import { createHash } from "crypto"; + +import { db } from "@homarr/db"; + +import type { RepositoryIconGroup } from "../types"; +import { IconRepository } from "./icon-repository"; + +export class LocalIconRepository extends IconRepository { + constructor() { + super("Local", "local", undefined, undefined, undefined, undefined); + } + protected async getAllIconsInternalAsync(): Promise { + const medias = await db.query.medias.findMany(); + return { + success: true, + icons: medias.map((media) => ({ + local: true, + fileNameWithExtension: media.name, + imageUrl: `/api/user-medias/${media.id}`, + checksum: createHash("md5").update(media.content).digest("hex"), + sizeInBytes: media.size, + })), + slug: "local", + }; + } +} diff --git a/packages/icons/src/types/repository-icon.ts b/packages/icons/src/types/repository-icon.ts index cb5884603..681a7beda 100644 --- a/packages/icons/src/types/repository-icon.ts +++ b/packages/icons/src/types/repository-icon.ts @@ -1,7 +1,7 @@ export interface RepositoryIcon { fileNameWithExtension: string; sizeInBytes?: number; - imageUrl: URL; + imageUrl: string; local: boolean; checksum: string; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9ea519c02..10e234ad9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,7 +24,7 @@ importers: version: 4.3.3(vite@5.4.5(@types/node@22.8.7)(sass@1.80.6)(sugarss@4.0.1(postcss@8.4.47))(terser@5.32.0)) '@vitest/coverage-v8': specifier: ^2.1.4 - version: 2.1.4(vitest@2.1.4) + version: 2.1.4(vitest@2.1.4(@types/node@22.8.7)(@vitest/ui@2.1.4)(jsdom@25.0.1)(sass@1.80.6)(sugarss@4.0.1(postcss@8.4.47))(terser@5.32.0)) '@vitest/ui': specifier: ^2.1.4 version: 2.1.4(vitest@2.1.4) @@ -952,6 +952,9 @@ importers: '@homarr/common': specifier: workspace:^0.1.0 version: link:../common + '@homarr/db': + specifier: workspace:^0.1.0 + version: link:../db '@homarr/log': specifier: workspace:^0.1.0 version: link:../log @@ -10338,7 +10341,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitest/coverage-v8@2.1.4(vitest@2.1.4)': + '@vitest/coverage-v8@2.1.4(vitest@2.1.4(@types/node@22.8.7)(@vitest/ui@2.1.4)(jsdom@25.0.1)(sass@1.80.6)(sugarss@4.0.1(postcss@8.4.47))(terser@5.32.0))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3