Fixed 267U.pre2
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
import { db } from "../../db/postgre.js";
|
||||
import { DriveFile } from "../entities/drive-file.js";
|
||||
import { toPuny } from "../../misc/convert-host.js";
|
||||
import { awaitAll } from "../../prelude/await-all.js";
|
||||
import config from "../../config/index.js";
|
||||
import { appendQuery, query } from "../../prelude/url.js";
|
||||
import { DriveFolders, Users } from "../index.js";
|
||||
import { deepClone } from "../../misc/clone.js";
|
||||
import { fetchMetaSync } from "../../misc/fetch-meta.js";
|
||||
export const DriveFileRepository = db.getRepository(DriveFile).extend({
|
||||
validateFileName (name) {
|
||||
return name.trim().length > 0 && name.length <= 200 && name.indexOf("\\") === -1 && name.indexOf("/") === -1 && name.indexOf("..") === -1;
|
||||
},
|
||||
getPublicProperties (file) {
|
||||
if (file.properties.orientation != null) {
|
||||
const properties = deepClone(file.properties);
|
||||
if (file.properties.orientation >= 5) {
|
||||
[properties.width, properties.height] = [
|
||||
properties.height,
|
||||
properties.width
|
||||
];
|
||||
}
|
||||
properties.orientation = undefined;
|
||||
return properties;
|
||||
}
|
||||
return file.properties;
|
||||
},
|
||||
isImage (file) {
|
||||
return !!file.type && [
|
||||
"image/png",
|
||||
"image/apng",
|
||||
"image/gif",
|
||||
"image/jpeg",
|
||||
"image/webp",
|
||||
"image/svg+xml",
|
||||
"image/avif"
|
||||
].includes(file.type);
|
||||
},
|
||||
isStreamableMedia (file) {
|
||||
return file.type.startsWith("video/") || file.type.startsWith("audio/");
|
||||
},
|
||||
withStreamQuery (file, url) {
|
||||
if (url == null || file.allowDownload || !this.isStreamableMedia(file)) return url;
|
||||
return appendQuery(url, query({
|
||||
stream: "1"
|
||||
}));
|
||||
},
|
||||
getPublicUrl (file, thumbnail = false) {
|
||||
// リモートかつメディアプロキシ
|
||||
if (file.uri != null && file.userHost != null && config.mediaProxy != null) {
|
||||
return appendQuery(config.mediaProxy, query({
|
||||
url: file.uri,
|
||||
thumbnail: thumbnail ? "1" : undefined
|
||||
}));
|
||||
}
|
||||
if (file.isLink && config.proxyRemoteFiles) {
|
||||
const url = this.getDatabasePrefetchUrl(file, thumbnail);
|
||||
if (url != null) return `${config.url}/proxy/${encodeURIComponent(new URL(url).pathname)}?${query({
|
||||
url: url
|
||||
})}`;
|
||||
}
|
||||
const url = thumbnail ? file.thumbnailUrl || (this.isImage(file) ? file.webpublicUrl || file.url : null) : file.webpublicUrl || file.url;
|
||||
return thumbnail ? url : this.withStreamQuery(file, url);
|
||||
},
|
||||
getDatabasePrefetchUrl (file, thumbnail = false) {
|
||||
return thumbnail ? file.thumbnailUrl ?? file.webpublicUrl ?? file.url : file.webpublicUrl ?? file.url;
|
||||
},
|
||||
getFinalUrl (url) {
|
||||
if (!config.proxyRemoteFiles) return url;
|
||||
if (!url.startsWith('https://') && !url.startsWith('http://')) return url;
|
||||
if (url.startsWith(`${config.url}/files`)) return url;
|
||||
if (url.startsWith(`${config.url}/static-assets`)) return url;
|
||||
if (url.startsWith(`${config.url}/identicon`)) return url;
|
||||
if (url.startsWith(`${config.url}/avatar`)) return url;
|
||||
const meta = fetchMetaSync();
|
||||
const baseUrl = meta ? meta.objectStorageBaseUrl ?? `${meta.objectStorageUseSSL ? "https" : "http"}://${meta.objectStorageEndpoint}${meta.objectStoragePort ? `:${meta.objectStoragePort}` : ""}/${meta.objectStorageBucket}` : null;
|
||||
if (baseUrl !== null && url.startsWith(baseUrl)) return url;
|
||||
return `${config.url}/proxy/${encodeURIComponent(new URL(url).pathname)}?${query({
|
||||
url: url
|
||||
})}`;
|
||||
},
|
||||
getFinalUrlMaybe (url) {
|
||||
if (url == null) return null;
|
||||
return this.getFinalUrl(url);
|
||||
},
|
||||
async calcDriveUsageOf (user) {
|
||||
const id = typeof user === "object" ? user.id : user;
|
||||
const { sum } = await this.createQueryBuilder("file").where("file.userId = :id", {
|
||||
id: id
|
||||
}).andWhere("file.isLink = FALSE").andWhere("file.isDatabase = FALSE").select("SUM(file.size)", "sum").getRawOne();
|
||||
return parseInt(sum, 10) || 0;
|
||||
},
|
||||
async calcDatabaseUsageOf (user) {
|
||||
const id = typeof user === "object" ? user.id : user;
|
||||
const { sum } = await this.createQueryBuilder("file").where("file.userId = :id", {
|
||||
id: id
|
||||
}).andWhere("file.isLink = FALSE").andWhere("file.isDatabase = TRUE").select("SUM(file.size)", "sum").getRawOne();
|
||||
return parseInt(sum, 10) || 0;
|
||||
},
|
||||
async calcDriveUsageOfHost (host) {
|
||||
const { sum } = await this.createQueryBuilder("file").where("file.userHost = :host", {
|
||||
host: toPuny(host)
|
||||
}).andWhere("file.isLink = FALSE").andWhere("file.isDatabase = FALSE").select("SUM(file.size)", "sum").getRawOne();
|
||||
return parseInt(sum, 10) || 0;
|
||||
},
|
||||
async calcDriveUsageOfLocal () {
|
||||
const { sum } = await this.createQueryBuilder("file").where("file.userHost IS NULL").andWhere("file.isLink = FALSE").andWhere("file.isDatabase = FALSE").select("SUM(file.size)", "sum").getRawOne();
|
||||
return parseInt(sum, 10) || 0;
|
||||
},
|
||||
async calcDriveUsageOfRemote () {
|
||||
const { sum } = await this.createQueryBuilder("file").where("file.userHost IS NOT NULL").andWhere("file.isLink = FALSE").andWhere("file.isDatabase = FALSE").select("SUM(file.size)", "sum").getRawOne();
|
||||
return parseInt(sum, 10) || 0;
|
||||
},
|
||||
async pack (src, options) {
|
||||
const opts = Object.assign({
|
||||
detail: false,
|
||||
self: false
|
||||
}, options);
|
||||
const file = typeof src === "object" ? src : await this.findOneByOrFail({
|
||||
id: src
|
||||
});
|
||||
return await awaitAll({
|
||||
id: file.id,
|
||||
createdAt: file.createdAt.toISOString(),
|
||||
name: file.name,
|
||||
type: file.type,
|
||||
md5: file.md5,
|
||||
size: file.size,
|
||||
isSensitive: file.isSensitive,
|
||||
allowDownload: file.allowDownload,
|
||||
isDatabase: file.isDatabase,
|
||||
blurhash: file.blurhash,
|
||||
properties: opts.self ? file.properties : this.getPublicProperties(file),
|
||||
url: opts.self ? file.url : this.getPublicUrl(file, false),
|
||||
thumbnailUrl: this.getPublicUrl(file, true),
|
||||
comment: file.comment,
|
||||
folderId: file.folderId,
|
||||
folder: opts.detail && file.folderId ? DriveFolders.pack(file.folderId, {
|
||||
detail: true
|
||||
}) : null,
|
||||
userId: opts.withUser ? file.userId : null,
|
||||
user: opts.withUser && file.userId ? Users.pack(file.userId) : null
|
||||
});
|
||||
},
|
||||
async packNullable (src, options) {
|
||||
const opts = Object.assign({
|
||||
detail: false,
|
||||
self: false
|
||||
}, options);
|
||||
const file = typeof src === "object" ? src : await this.findOneBy({
|
||||
id: src
|
||||
});
|
||||
if (file == null) return null;
|
||||
return await awaitAll({
|
||||
id: file.id,
|
||||
createdAt: file.createdAt.toISOString(),
|
||||
name: file.name,
|
||||
type: file.type,
|
||||
md5: file.md5,
|
||||
size: file.size,
|
||||
isSensitive: file.isSensitive,
|
||||
allowDownload: file.allowDownload,
|
||||
isDatabase: file.isDatabase,
|
||||
blurhash: file.blurhash,
|
||||
properties: opts.self ? file.properties : this.getPublicProperties(file),
|
||||
url: opts.self ? file.url : this.getPublicUrl(file, false),
|
||||
thumbnailUrl: this.getPublicUrl(file, true),
|
||||
comment: file.comment,
|
||||
folderId: file.folderId,
|
||||
folder: opts.detail && file.folderId ? DriveFolders.pack(file.folderId, {
|
||||
detail: true
|
||||
}) : null,
|
||||
userId: opts.withUser ? file.userId : null,
|
||||
user: opts.withUser && file.userId ? Users.pack(file.userId) : null
|
||||
});
|
||||
},
|
||||
async packMany (files, options) {
|
||||
const items = await Promise.all(files.map((f)=>this.packNullable(f, options)));
|
||||
return items.filter((x)=>x != null);
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user