2024-03-14 04:39:32 +01:00
|
|
|
import { S3Client } from "@jsr/bradenmacdonald__s3-lite-client";
|
2024-04-07 07:30:49 +02:00
|
|
|
import type { Config } from "config-manager";
|
|
|
|
|
import { MediaBackend, MediaBackendType, MediaHasher } from "..";
|
2024-03-09 00:14:45 +01:00
|
|
|
import type { ConvertableMediaFormats } from "../media-converter";
|
|
|
|
|
import { MediaConverter } from "../media-converter";
|
|
|
|
|
|
|
|
|
|
export class S3MediaBackend extends MediaBackend {
|
2024-04-07 07:30:49 +02:00
|
|
|
constructor(
|
|
|
|
|
config: Config,
|
|
|
|
|
private s3Client = new S3Client({
|
|
|
|
|
endPoint: config.s3.endpoint,
|
|
|
|
|
useSSL: true,
|
|
|
|
|
region: config.s3.region || "auto",
|
|
|
|
|
bucket: config.s3.bucket_name,
|
|
|
|
|
accessKey: config.s3.access_key,
|
|
|
|
|
secretKey: config.s3.secret_access_key,
|
|
|
|
|
}),
|
|
|
|
|
) {
|
|
|
|
|
super(config, MediaBackendType.S3);
|
|
|
|
|
}
|
2024-03-09 00:14:45 +01:00
|
|
|
|
2024-04-07 07:30:49 +02:00
|
|
|
public async addFile(file: File) {
|
|
|
|
|
let convertedFile = file;
|
|
|
|
|
if (this.shouldConvertImages(this.config)) {
|
|
|
|
|
const fileExtension = file.name.split(".").pop();
|
|
|
|
|
const mediaConverter = new MediaConverter(
|
|
|
|
|
fileExtension as ConvertableMediaFormats,
|
|
|
|
|
this.config.media.conversion
|
|
|
|
|
.convert_to as ConvertableMediaFormats,
|
|
|
|
|
);
|
|
|
|
|
convertedFile = await mediaConverter.convert(file);
|
|
|
|
|
}
|
2024-03-09 00:14:45 +01:00
|
|
|
|
2024-04-07 07:30:49 +02:00
|
|
|
const hash = await new MediaHasher().getMediaHash(convertedFile);
|
2024-03-09 00:14:45 +01:00
|
|
|
|
2024-04-07 07:30:49 +02:00
|
|
|
await this.s3Client.putObject(
|
|
|
|
|
convertedFile.name,
|
|
|
|
|
convertedFile.stream(),
|
|
|
|
|
{
|
|
|
|
|
size: convertedFile.size,
|
|
|
|
|
},
|
|
|
|
|
);
|
2024-03-09 00:14:45 +01:00
|
|
|
|
2024-04-07 07:30:49 +02:00
|
|
|
return {
|
|
|
|
|
uploadedFile: convertedFile,
|
|
|
|
|
hash: hash,
|
|
|
|
|
};
|
|
|
|
|
}
|
2024-03-09 00:14:45 +01:00
|
|
|
|
2024-04-07 07:30:49 +02:00
|
|
|
public async getFileByHash(
|
|
|
|
|
hash: string,
|
|
|
|
|
databaseHashFetcher: (sha256: string) => Promise<string | null>,
|
|
|
|
|
): Promise<File | null> {
|
|
|
|
|
const filename = await databaseHashFetcher(hash);
|
2024-03-09 00:14:45 +01:00
|
|
|
|
2024-04-07 07:30:49 +02:00
|
|
|
if (!filename) return null;
|
2024-03-09 00:14:45 +01:00
|
|
|
|
2024-04-07 07:30:49 +02:00
|
|
|
return this.getFile(filename);
|
|
|
|
|
}
|
2024-03-09 00:14:45 +01:00
|
|
|
|
2024-04-07 07:30:49 +02:00
|
|
|
public async getFile(filename: string): Promise<File | null> {
|
|
|
|
|
try {
|
|
|
|
|
await this.s3Client.statObject(filename);
|
|
|
|
|
} catch {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2024-03-09 00:14:45 +01:00
|
|
|
|
2024-04-07 07:30:49 +02:00
|
|
|
const file = await this.s3Client.getObject(filename);
|
2024-03-09 00:14:45 +01:00
|
|
|
|
2024-04-07 07:30:49 +02:00
|
|
|
return new File([await file.arrayBuffer()], filename, {
|
|
|
|
|
type: file.headers.get("Content-Type") || "undefined",
|
|
|
|
|
});
|
|
|
|
|
}
|
2024-03-09 00:14:45 +01:00
|
|
|
}
|