aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreug-vs <eug-vs@keemail.me>2020-08-12 18:35:10 +0300
committereug-vs <eug-vs@keemail.me>2020-08-12 18:35:10 +0300
commitf08e2a37677e711cad7397c532670913645f010a (patch)
tree60b2867a7677ba5e6243e0c7da171fd64b1c18d1
parent6d50d2ef3a64b8fe5037861cda8daab40f9a7213 (diff)
downloadwhich-api-f08e2a37677e711cad7397c532670913645f010a.tar.gz
feat: File service logic
-rw-r--r--services/files/files.class.ts59
1 files changed, 58 insertions, 1 deletions
diff --git a/services/files/files.class.ts b/services/files/files.class.ts
index e2f9df3..7e4bcbf 100644
--- a/services/files/files.class.ts
+++ b/services/files/files.class.ts
@@ -1,6 +1,10 @@
import { Application } from '@feathersjs/express';
import { Params } from '@feathersjs/feathers';
import { v4 } from 'uuid';
+import axios from 'axios';
+import fs from 'fs';
+import path from 'path';
+import { User } from 'which-types';
// Use require to avoid bug
// https://stackoverflow.com/questions/62611373/heroku-crashes-when-importing-aws-sdk
@@ -13,15 +17,68 @@ export default class Files {
bucket!: string;
async find(params: Params): Promise<string> {
+ const path = this.generateS3Path(params.user?.username);
+ return this.getUploadUrl(path);
+ }
+
+ public isS3url(url: string): boolean {
+ return url.startsWith('https://${this.bucket}.s3');
+ }
+
+ public generateS3Path(prefix='', ext='png'): string {
+ const key = v4();
+ const fileName = `${key}.${ext}`;
+ return prefix ? `${prefix}/${fileName}` : fileName;
+ }
+
+ async getUploadUrl(path: string): Promise<string> {
// Return signed upload URL
return this.s3.getSignedUrl('putObject', {
Bucket: this.bucket,
- Key: `${params.user?.username}/${v4()}.png`,
+ Key: path,
ContentType: 'image/*',
Expires: 300,
});
}
+ async getDownloadUrl(path: string): Promise<string> {
+ return this.getUploadUrl(path).then((url: string) => {
+ const queryIndex = url.indexOf('?');
+ return url.slice(0, queryIndex);
+ })
+ }
+
+ private createTmpDir() {
+ if (!fs.existsSync('tmp')) fs.mkdirSync('tmp');
+ }
+
+ async downloadFile(url: string): Promise<string> {
+ return new Promise(async (resolve, reject) => {
+ this.createTmpDir();
+ const filePath = `tmp/${v4()}`;
+ const fileStream = fs.createWriteStream(filePath);
+ const response = await axios.get(url, { responseType: 'stream' })
+ response.data.pipe(fileStream)
+ .on('error', reject)
+ .on('close', () => resolve(filePath));
+ });
+ }
+
+ async uploadFileToS3(filePath: string, s3Path: string) {
+ const fileStream = fs.createReadStream(filePath);
+ const request = this.s3.upload({
+ Bucket: this.bucket,
+ Key: s3Path,
+ Body: fileStream,
+ ContentType: 'image/png'
+ });
+ request.on('httpUploadProgress', progress => {
+ console.log('progress', progress);
+ })
+ await request.promise();
+ return this.getDownloadUrl(s3Path);
+ }
+
setup(app: Application): void {
this.app = app;
this.s3 = new S3({