diff options
Diffstat (limited to 'src/models')
| -rw-r--r-- | src/models/entities/meta.ts | 5 | ||||
| -rw-r--r-- | src/models/repositories/drive-file.ts | 46 |
2 files changed, 44 insertions, 7 deletions
diff --git a/src/models/entities/meta.ts b/src/models/entities/meta.ts index fdd2818238..e5b189ef83 100644 --- a/src/models/entities/meta.ts +++ b/src/models/entities/meta.ts @@ -115,6 +115,11 @@ export class Meta { }) public cacheRemoteFiles: boolean; + @Column('boolean', { + default: false, + }) + public proxyRemoteFiles: boolean; + @Column('varchar', { length: 128, nullable: true diff --git a/src/models/repositories/drive-file.ts b/src/models/repositories/drive-file.ts index a20d393044..5e3c1e94b8 100644 --- a/src/models/repositories/drive-file.ts +++ b/src/models/repositories/drive-file.ts @@ -7,6 +7,9 @@ import { ensure } from '../../prelude/ensure'; import { awaitAll } from '../../prelude/await-all'; import { SchemaType } from '../../misc/schema'; import config from '../../config'; +import { query, appendQuery } from '../../prelude/url'; +import { Meta } from '../entities/meta'; +import { fetchMeta } from '../../misc/fetch-meta'; export type PackedDriveFile = SchemaType<typeof packedDriveFileSchema>; @@ -22,12 +25,39 @@ export class DriveFileRepository extends Repository<DriveFile> { ); } - public getPublicUrl(file: DriveFile, thumbnail = false): string | null { - let url = thumbnail ? (file.thumbnailUrl || file.webpublicUrl || null) : (file.webpublicUrl || file.url); - if (file.src !== null && file.userHost !== null && config.mediaProxy !== null) { - url = `${config.mediaProxy}/${thumbnail ? 'thumbnail' : ''}?url=${file.src}`; + public getPublicUrl(file: DriveFile, thumbnail = false, meta?: Meta): string | null { + // リモートかつメディアプロキシ + if (file.uri != null && file.userHost != null && config.mediaProxy != null) { + return appendQuery(config.mediaProxy, query({ + url: file.uri, + thumbnail: thumbnail ? '1' : undefined + })); } - return url; + + // リモートかつ期限切れはローカルプロキシを試みる + if (file.uri != null && file.isLink && meta && meta.proxyRemoteFiles) { + const key = thumbnail ? file.thumbnailAccessKey : file.webpublicAccessKey; + + if (key && !key.match('/')) { // 古いものはここにオブジェクトストレージキーが入ってるので除外 + let ext = ''; + + if (file.name) { + [ext] = (file.name.match(/\.(\w+)$/) || ['']); + } + + if (ext === '') { + if (file.type === 'image/jpeg') ext = '.jpg'; + if (file.type === 'image/png') ext = '.png'; + if (file.type === 'image/webp') ext = '.webp'; + if (file.type === 'image/apng') ext = '.apng'; + if (file.type === 'image/vnd.mozilla.apng') ext = '.apng'; + } + + return `/files/${key}/${key}${ext}`; + } + } + + return thumbnail ? (file.thumbnailUrl || file.webpublicUrl || null) : (file.webpublicUrl || file.url); } public async clacDriveUsageOf(user: User['id'] | User): Promise<number> { @@ -87,6 +117,8 @@ export class DriveFileRepository extends Repository<DriveFile> { const file = typeof src === 'object' ? src : await this.findOne(src).then(ensure); + const meta = await fetchMeta(); + return await awaitAll({ id: file.id, createdAt: file.createdAt.toISOString(), @@ -96,8 +128,8 @@ export class DriveFileRepository extends Repository<DriveFile> { size: file.size, isSensitive: file.isSensitive, properties: file.properties, - url: opts.self ? file.url : this.getPublicUrl(file, false), - thumbnailUrl: this.getPublicUrl(file, true), + url: opts.self ? file.url : this.getPublicUrl(file, false, meta), + thumbnailUrl: this.getPublicUrl(file, true, meta), folderId: file.folderId, folder: opts.detail && file.folderId ? DriveFolders.pack(file.folderId, { detail: true |