-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #60 from Open-Webtoon-Reader/feature/s3-support
Merge S3 support to Main
- Loading branch information
Showing
16 changed files
with
557 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import {Module} from "@nestjs/common"; | ||
import {FileService} from "./file.service"; | ||
import {MiscModule} from "../misc/misc.module"; | ||
|
||
@Module({ | ||
exports: [FileService], | ||
imports: [MiscModule], | ||
providers: [FileService] | ||
}) | ||
export class FileModule{} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import {Injectable, NotFoundException} from "@nestjs/common"; | ||
import {ConfigService} from "@nestjs/config"; | ||
import {PrismaService} from "../misc/prisma.service"; | ||
import {MiscService} from "../misc/misc.service"; | ||
import {Saver} from "./saver/saver"; | ||
import {S3Saver} from "./saver/s3.saver"; | ||
import {FileSaver} from "./saver/file.saver"; | ||
|
||
@Injectable() | ||
export class FileService{ | ||
|
||
private readonly saver: Saver; | ||
|
||
constructor( | ||
private readonly configService: ConfigService, | ||
private readonly prismaService: PrismaService, | ||
private readonly cipherService: MiscService, | ||
){ | ||
if(this.configService.get("FILESYSTEM") === "s3") | ||
this.saver = this.getS3Saver(); | ||
else | ||
this.saver = this.getFileSaver(); | ||
} | ||
|
||
getS3Saver(){ | ||
return new S3Saver( | ||
this.configService.get("S3_ENDPOINT"), | ||
this.configService.get("S3_PORT"), | ||
this.configService.get("S3_USE_SSL") === "true", | ||
this.configService.get("S3_REGION"), | ||
this.configService.get("S3_ACCESS_KEY"), | ||
this.configService.get("S3_SECRET_KEY"), | ||
this.configService.get("S3_BUCKET_NAME") | ||
); | ||
} | ||
|
||
getFileSaver(){ | ||
return new FileSaver("images"); | ||
} | ||
|
||
async saveImage(data: Buffer): Promise<string>{ | ||
const sum = this.cipherService.getSum(data); | ||
await this.saver.saveFile(data, sum); | ||
return sum; | ||
} | ||
|
||
async loadImage(sum: string): Promise<Buffer>{ | ||
try{ | ||
const stream = await this.saver.getFile(sum); | ||
return await new Promise<Buffer>((resolve, reject) => { | ||
const chunks: Buffer[] = []; | ||
stream.on("data", (chunk: Buffer) => chunks.push(chunk)); | ||
stream.on("end", () => resolve(Buffer.concat(chunks))); | ||
stream.on("error", reject); | ||
}); | ||
}catch(e){ | ||
throw new NotFoundException("Image not found"); | ||
} | ||
} | ||
|
||
async removeImage(sum: string): Promise<void>{ | ||
await this.saver.removeFile(sum); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import {Saver} from "./saver"; | ||
import * as fs from "fs"; | ||
import {createReadStream, ReadStream} from "fs"; | ||
|
||
export class FileSaver implements Saver{ | ||
|
||
private readonly uploadFolderName: string; | ||
|
||
constructor(uploadFolderName: string){ | ||
this.uploadFolderName = uploadFolderName; | ||
} | ||
|
||
async saveFile(data: Buffer, sum: string): Promise<void>{ | ||
const path = `./${this.uploadFolderName}/${sum.substring(0, 2)}`; | ||
if(!fs.existsSync(path)){ | ||
fs.mkdirSync(path, { | ||
recursive: true | ||
}); | ||
} | ||
fs.writeFileSync(`${path}/${sum}.webp`, data); | ||
} | ||
|
||
async getFile(sum: string): Promise<ReadStream>{ | ||
return createReadStream(`./${this.uploadFolderName}/${sum.substring(0, 2)}/${sum}.webp`); | ||
} | ||
|
||
async removeFile(sum: string): Promise<void>{ | ||
fs.unlinkSync(`./${this.uploadFolderName}/${sum.substring(0, 2)}/${sum}.webp`); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import {Readable} from "stream"; | ||
import * as Minio from "minio"; | ||
import {Saver} from "./saver"; | ||
import {ReadStream} from "fs"; | ||
|
||
export class S3Saver implements Saver{ | ||
|
||
private readonly s3Client: Minio.Client; | ||
private readonly bucketName: string; | ||
private bucketExists: boolean = false; | ||
|
||
constructor(endpoint: string, port: number, useSSL: boolean, region: string, accessKey: string, secretKey: string, bucketName: string){ | ||
this.s3Client = new Minio.Client({ | ||
endPoint: endpoint, | ||
port, | ||
useSSL, | ||
accessKey, | ||
secretKey, | ||
region, | ||
}); | ||
this.bucketName = bucketName; | ||
} | ||
|
||
public async createBucketIfNotExists(): Promise<void>{ | ||
if(this.bucketExists) | ||
return; | ||
try{ | ||
const bucketExists = await this.s3Client.bucketExists(this.bucketName); | ||
if(!bucketExists) | ||
await this.s3Client.makeBucket(this.bucketName); | ||
}catch (e){ | ||
console.log(e); | ||
} | ||
this.bucketExists = true; | ||
} | ||
|
||
async saveFile(data: Buffer, sum: string): Promise<void>{ | ||
await this.createBucketIfNotExists(); | ||
await this.s3Client.putObject(this.bucketName, `${sum.substring(0, 2)}/${sum}.webp`, data); | ||
} | ||
async getFile(sum: string): Promise<ReadStream>{ | ||
await this.createBucketIfNotExists(); | ||
const readable: Readable = await this.s3Client.getObject(this.bucketName, `${sum.substring(0, 2)}/${sum}.webp`); | ||
return readable as ReadStream; | ||
} | ||
|
||
async removeFile(sum: string): Promise<void>{ | ||
await this.createBucketIfNotExists(); | ||
await this.s3Client.removeObject(this.bucketName, `${sum.substring(0, 2)}/${sum}.webp`); | ||
} | ||
|
||
async clearBucket(){ | ||
const objectsList = []; | ||
|
||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-expect-error | ||
const objectsStream = this.s3Client.listObjects(this.bucketName, "", true, {IncludeVersion: true}); | ||
objectsStream.on("data", function(obj){ | ||
objectsList.push(obj); | ||
}); | ||
objectsStream.on("error", function(e){ | ||
return console.log(e); | ||
}); | ||
objectsStream.on("end", async() => { | ||
console.log(`Clearing ${objectsList.length} objects from the bucket`); | ||
await this.s3Client.removeObjects(this.bucketName, objectsList); | ||
console.log("Bucket cleared"); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import {ReadStream} from "fs"; | ||
|
||
export interface Saver{ | ||
saveFile(data: Buffer, fileName: string): Promise<void>; | ||
getFile(fileName: string): Promise<ReadStream>; | ||
removeFile(fileName: string): Promise<void>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.