From 4823abd3a9415cea56f703854e8ea344a65f644b Mon Sep 17 00:00:00 2001 From: yumeko Date: Fri, 19 Apr 2024 03:34:25 +0300 Subject: [PATCH] Add usageHint field to DriveFile, and fill accordingly when operating on Persons --- .../migration/1713451569342-AddDriveFileUsage.ts | 15 +++++++++++++++ .../backend/src/models/entities/drive-file.ts | 7 +++++++ .../src/remote/activitypub/models/image.ts | 5 ++++- .../backend/src/remote/activitypub/models/note.ts | 4 ++-- .../src/remote/activitypub/models/person.ts | 8 ++++---- packages/backend/src/services/drive/add-file.ts | 10 ++++++++++ .../backend/src/services/drive/upload-from-url.ts | 11 +++++++++-- 7 files changed, 51 insertions(+), 9 deletions(-) create mode 100644 packages/backend/src/migration/1713451569342-AddDriveFileUsage.ts diff --git a/packages/backend/src/migration/1713451569342-AddDriveFileUsage.ts b/packages/backend/src/migration/1713451569342-AddDriveFileUsage.ts new file mode 100644 index 0000000000..c0c96fe74c --- /dev/null +++ b/packages/backend/src/migration/1713451569342-AddDriveFileUsage.ts @@ -0,0 +1,15 @@ +import type { MigrationInterface, QueryRunner } from "typeorm"; + +export class AddDriveFileUsage1713451569342 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "drive_file" ADD "usageHint" character varying(16) DEFAULT NULL`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "drive_file" DROP COLUMN "usageHint"` + ); + } +} diff --git a/packages/backend/src/models/entities/drive-file.ts b/packages/backend/src/models/entities/drive-file.ts index 3c49e89fd5..b5717d62cd 100644 --- a/packages/backend/src/models/entities/drive-file.ts +++ b/packages/backend/src/models/entities/drive-file.ts @@ -177,6 +177,13 @@ export class DriveFile { }) public isSensitive: boolean; + @Column("varchar", { + length: 16, + nullable: true, + comment: "Hint for what the file is used for.", + }) + public usageHint: string | null; + /** * 外部の(信頼されていない)URLへの直リンクか否か */ diff --git a/packages/backend/src/remote/activitypub/models/image.ts b/packages/backend/src/remote/activitypub/models/image.ts index e2072a963a..23fb720362 100644 --- a/packages/backend/src/remote/activitypub/models/image.ts +++ b/packages/backend/src/remote/activitypub/models/image.ts @@ -16,6 +16,7 @@ const logger = apLogger; export async function createImage( actor: CacheableRemoteUser, value: any, + usage: 'avatar' | 'banner' | null ): Promise { // Skip if author is frozen. if (actor.isSuspended) { @@ -43,6 +44,7 @@ export async function createImage( sensitive: image.sensitive, isLink: !instance.cacheRemoteFiles, comment: truncate(image.name, DB_MAX_IMAGE_COMMENT_LENGTH), + usageHint: usage }); if (file.isLink) { @@ -73,9 +75,10 @@ export async function createImage( export async function resolveImage( actor: CacheableRemoteUser, value: any, + usage: 'avatar' | 'banner' | null, ): Promise { // TODO // Fetch from remote server and register - return await createImage(actor, value); + return await createImage(actor, value, usage); } diff --git a/packages/backend/src/remote/activitypub/models/note.ts b/packages/backend/src/remote/activitypub/models/note.ts index ad59930457..5e1c3829a7 100644 --- a/packages/backend/src/remote/activitypub/models/note.ts +++ b/packages/backend/src/remote/activitypub/models/note.ts @@ -213,7 +213,7 @@ export async function createNote( ? ( await Promise.all( note.attachment.map( - (x) => limit(() => resolveImage(actor, x)) as Promise, + (x) => limit(() => resolveImage(actor, x, null)) as Promise, ), ) ).filter((image) => image != null) @@ -616,7 +616,7 @@ export async function updateNote(value: string | IObject, resolver?: Resolver) { fileList.map( (x) => limit(async () => { - const file = await resolveImage(actor, x); + const file = await resolveImage(actor, x, null); const update: Partial = {}; const altText = truncate(x.name, DB_MAX_IMAGE_COMMENT_LENGTH); diff --git a/packages/backend/src/remote/activitypub/models/person.ts b/packages/backend/src/remote/activitypub/models/person.ts index e91280125f..47a1152c36 100644 --- a/packages/backend/src/remote/activitypub/models/person.ts +++ b/packages/backend/src/remote/activitypub/models/person.ts @@ -362,10 +362,10 @@ export async function createPerson( //#region Fetch avatar and header image const [avatar, banner] = await Promise.all( - [person.icon, person.image].map((img) => + [person.icon, person.image].map((img, index) => img == null ? Promise.resolve(null) - : resolveImage(user!, img).catch(() => null), + : resolveImage(user!, img, index === 0 ? "avatar" : index === 1 ? "banner" : null).catch(() => null), ), ); @@ -438,10 +438,10 @@ export async function updatePerson( // Fetch avatar and header image const [avatar, banner] = await Promise.all( - [person.icon, person.image].map((img) => + [person.icon, person.image].map((img, index) => img == null ? Promise.resolve(null) - : resolveImage(user, img).catch(() => null), + : resolveImage(user, img, index === 0 ? "avatar" : index === 1 ? "banner" : null).catch(() => null), ), ); diff --git a/packages/backend/src/services/drive/add-file.ts b/packages/backend/src/services/drive/add-file.ts index 24ad9f8f02..cfb871dd93 100644 --- a/packages/backend/src/services/drive/add-file.ts +++ b/packages/backend/src/services/drive/add-file.ts @@ -65,6 +65,7 @@ function urlPathJoin( * @param type Content-Type for original * @param hash Hash for original * @param size Size for original + * @param usage Optional usage hint for file (f.e. "avatar") */ async function save( file: DriveFile, @@ -73,6 +74,7 @@ async function save( type: string, hash: string, size: number, + usage: string | null = null ): Promise { // thunbnail, webpublic を必要なら生成 const alts = await generateAlts(path, type, !file.uri); @@ -161,6 +163,7 @@ async function save( file.md5 = hash; file.size = size; file.storedInternal = false; + file.usageHint = usage ?? null; return await DriveFiles.insert(file).then((x) => DriveFiles.findOneByOrFail(x.identifiers[0]), @@ -204,6 +207,7 @@ async function save( file.type = type; file.md5 = hash; file.size = size; + file.usageHint = usage ?? null; return await DriveFiles.insert(file).then((x) => DriveFiles.findOneByOrFail(x.identifiers[0]), @@ -450,6 +454,9 @@ type AddFileArgs = { requestIp?: string | null; requestHeaders?: Record | null; + + /** Whether this file has a known use case, like user avatar or instance icon */ + usageHint?: string | null; }; /** @@ -469,6 +476,7 @@ export async function addFile({ sensitive = null, requestIp = null, requestHeaders = null, + usageHint = null, }: AddFileArgs): Promise { const info = await getFileInfo(path); logger.info(`${JSON.stringify(info)}`); @@ -581,6 +589,7 @@ export async function addFile({ file.isLink = isLink; file.requestIp = requestIp; file.requestHeaders = requestHeaders; + file.usageHint = usageHint; file.isSensitive = user ? Users.isLocalUser(user) && (instance!.markLocalFilesNsfwByDefault || profile!.alwaysMarkNsfw) @@ -639,6 +648,7 @@ export async function addFile({ info.type.mime, info.md5, info.size, + usageHint ); } diff --git a/packages/backend/src/services/drive/upload-from-url.ts b/packages/backend/src/services/drive/upload-from-url.ts index 551d3757ca..238f8714fa 100644 --- a/packages/backend/src/services/drive/upload-from-url.ts +++ b/packages/backend/src/services/drive/upload-from-url.ts @@ -13,7 +13,11 @@ const logger = driveLogger.createSubLogger("downloader"); type Args = { url: string; - user: { id: User["id"]; host: User["host"] } | null; + user: { + id: User["id"]; + host: User["host"]; + driveCapacityOverrideMb: User["driveCapacityOverrideMb"]; + } | null; folderId?: DriveFolder["id"] | null; uri?: string | null; sensitive?: boolean; @@ -22,6 +26,7 @@ type Args = { comment?: string | null; requestIp?: string | null; requestHeaders?: Record | null; + usageHint?: string | null; }; export async function uploadFromUrl({ @@ -35,6 +40,7 @@ export async function uploadFromUrl({ comment = null, requestIp = null, requestHeaders = null, + usageHint = null }: Args): Promise { const parsedUrl = new URL(url); if ( @@ -75,9 +81,10 @@ export async function uploadFromUrl({ sensitive, requestIp, requestHeaders, + usageHint }); logger.succ(`Got: ${driveFile.id}`); - return driveFile!; + return driveFile; } catch (e) { logger.error(`Failed to create drive file:\n${inspect(e)}`); throw e;