Skip to content

Commit

Permalink
fix: out_dir modified
Browse files Browse the repository at this point in the history
  • Loading branch information
yatharthagoenka committed Apr 11, 2023
1 parent 2cd8c60 commit 2d6021f
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 79 deletions.
11 changes: 3 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ docker-compose up -d
```
> Note: `-d flag` is used to run the container in background
- This will start two app container instances, one db instance and an Nginx container acting as a load balancer for the two NestJS app containers. The configuration maps port 3000 of the host machine to the ports 3001 and 3002 which are in turn connected to the same ports of each app instances' docker containers, so we can access the load balancer by navigating to http://<ip_address>:<port> in your web browser.

> If the NestJS applications fail to connect with the mongodb service inside the containers, try disabling your system firewall using:
```
sudo ufw disable
Expand All @@ -47,15 +49,8 @@ docker ps -a
docker images
```

## Running docker image for nginx-lb

- This will start an Nginx container acting as a load balancer for the two NestJS app containers. The configuration maps port 3000 of the host machine to the ports 3001 and 3002 which are in turn connected to the same ports of each app instances' docker containers, so we can access the load balancer by navigating to http://<ip_address>:<port> in your web browser.
## Configuring nginx

```
docker compose up
docker compose up -d --> To run the container in background
```
- To change the protocol for load-balancing between the server instances, add one of the methods in the `upstream` block of [nginx.conf](load-balancer/nginx.conf) file.

```
Expand Down
10 changes: 0 additions & 10 deletions load-balancer/Dockerfile

This file was deleted.

13 changes: 0 additions & 13 deletions load-balancer/docker-compose.yml

This file was deleted.

19 changes: 0 additions & 19 deletions load-balancer/nginx.conf

This file was deleted.

3 changes: 3 additions & 0 deletions server/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,8 @@ ADD . /app

ENV NODE_ENV=dev

EXPOSE 3001
EXPOSE 3002

CMD ["npm", "run", "start"]

70 changes: 70 additions & 0 deletions server/schema.validations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// import Joi from 'joi';

// export function validateRegister(body) {
// const schema = Joi.object({
// email: Joi.string().email().min(3).required(),
// password: Joi.string().min(6).max(20).required(),
// name: Joi.string().min(3).max(24).required(),
// language: Joi.string().valid('tr', 'en').required(),
// platform: Joi.string().valid('Android', 'IOS').required(),
// timezone: Joi.number().required(),
// deviceId: Joi.string().min(4).required()
// });
// return schema.validate(body);
// }

// export function validateLogin(body) {
// const schema = Joi.object({
// email: Joi.string().email().min(3).required(),
// password: Joi.string().min(6).max(20).required()
// });
// return schema.validate(body);
// }

// export function validateSendVerificationCode(body) {
// const schema = Joi.object({
// email: Joi.string().email().min(3).required()
// });
// return schema.validate(body);
// }

// export function validateVerifyEmail(body) {
// const schema = Joi.object({
// token: Joi.string().min(10).required(),
// code: Joi.string().length(4).required()
// });
// return schema.validate(body);
// }

// export function validateRefreshToken(body) {
// const schema = Joi.object({
// refreshToken: Joi.string().min(10).required()
// });
// return schema.validate(body);
// }

// export function validateForgotPassword(body) {
// const schema = Joi.object({
// password: Joi.string().min(6).max(20).required()
// });
// return schema.validate(body);
// }

// export function validateChangePassword(body) {
// const schema = Joi.object({
// oldPassword: Joi.string().min(6).max(20).required(),
// newPassword: Joi.string().min(6).max(20).required()
// });
// return schema.validate(body);
// }

// export function validateEditUser(body) {
// const schema = Joi.object({
// name: Joi.string().min(3).max(24),
// username: Joi.string().min(3).max(15),
// language: Joi.string().valid('tr', 'en'),
// gender: Joi.string().valid('male', 'female', 'other'),
// birthDate: Joi.date()
// });
// return schema.validate(body);
// }
6 changes: 2 additions & 4 deletions server/src/files/files.controller.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Controller, Get, Post, Put, Delete, UseGuards, Res, HttpStatus, Query, UploadedFiles, Param, Body } from '@nestjs/common';
import { Controller, Get, Post, Delete, UseGuards, Res, HttpStatus, Query, UploadedFiles, Param, Body } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ValidateObjectId } from '../shared/validate-object-id.pipes';
import { FileDTO, IRole } from 'src/interfaces';
import { FilesService } from './files.service';
import { UploadedFile, UseInterceptors } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
Expand Down Expand Up @@ -46,10 +45,9 @@ export class FilesController {
async deleteFile(
@Query('fileID', new ValidateObjectId()) fileID,
@Res() res,
// @CheckUserRole({ userIDKey: 'userID', fileIDKey: 'fileID', requiredRole: IRole.OWNER }) userFile: { userID: string; fileID: string },
) {
try {
await this.filesService.deleteFolder(fileID, 'all');
await this.filesService.delete(fileID, 'all');
return res.status(HttpStatus.OK).json({ message: 'File deleted successfully' });
} catch (error) {
return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ message: 'Error deleting file' });
Expand Down
34 changes: 18 additions & 16 deletions server/src/files/files.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,7 @@ export class FilesService {

async divideFile(savedFile){
const pythonScriptPath = 'src/files/scripts/divider.py';
const gemsFolderPath = path.join(__dirname, '..', '..', 'uploads/',`${savedFile.originalname}-${uuidv4()}${savedFile.extension}`);
const fileSize = (path.join(__dirname, '..', '..', 'uploads/',`${savedFile.fileName}`));
const { stdout, stderr } = await execPromise(`python3 ${pythonScriptPath} ${savedFile.fileName} ${savedFile.extension}`) as child_process.ChildProcessWithoutNullStreams;
const { stdout, stderr } = await execPromise(`python3 ${pythonScriptPath} ${savedFile.fileName}`) as child_process.ChildProcessWithoutNullStreams;
if(stderr) {
this.loggerService.error(`divider.py: ${stderr}`);
return stderr;
Expand All @@ -63,15 +61,14 @@ export class FilesService {
return gems;
}

async combineFiles(fileName, originalname) : Promise<string> {
const folderPath = path.join(__dirname, '..', '..', 'uploads', fileName);
async combineFiles(url: string, originalname: string) : Promise<string> {
const folderPath = path.join(__dirname, '..', '..', 'uploads', url);
const fileGems = await fs.promises.readdir(folderPath);
const outputFilePath = path.join(folderPath, `${originalname}`);

fileGems.sort((a, b) => Number(a.split('-').shift()) - Number(b.split('-').shift()));

const outputStream = fs.createWriteStream(outputFilePath);

fileGems.sort((a, b) => Number(a.split('-').shift()) - Number(b.split('-').shift()));

for (const gem of fileGems) {
const gemPath = path.join(folderPath, gem);
const readStream = fs.createReadStream(gemPath);
Expand Down Expand Up @@ -118,7 +115,7 @@ export class FilesService {
});
// creating gems and deleting temp image
gems = await this.divideFile(savedFile);
this.deleteFile(`uploads/${savedFile.fileName}`)
this.deleteFileUtil(`uploads/${savedFile.fileName}`)

this.loggerService.info(`createFile: File ${savedFile.fileName} saved to server`);
}catch(error){
Expand All @@ -129,12 +126,12 @@ export class FilesService {
// Saving to db
try{
const createFileDTO = {
originalname: savedFile.originalname,
url: `${savedFile.fileName}${savedFile.extension}`,
originalname: `${savedFile.originalname}${savedFile.extension}`,
url: `${savedFile.fileName}.dir`,
ownerID: userID,
gems: [{
index: 0,
url: savedFile.fileName, //to be changed
url: `${savedFile.fileName}.dir`, //to be changed
enc: "none"
}]
}
Expand All @@ -150,7 +147,7 @@ export class FilesService {
await this.userService.addFileToUser(userID.toString(), userFileRecord);
this.loggerService.info(`File ${savedFile.fileName} added to db and user profile.`);
}catch(error){
this.deleteFile(`uploads/${savedFile.fileName}`)
this.deleteFileUtil(`uploads/${savedFile.fileName}`)
await deleteFolderUtil(`uploads/${savedFile.fileName}${savedFile.extension}`, { recursive: true });
this.loggerService.error(`Unable to add file : ${savedFile.fileName} to db. Deleted from server. `);
return error;
Expand All @@ -168,10 +165,15 @@ export class FilesService {
this.loggerService.info('Original file already exists, returning from cache.');
return path.join(__dirname, '..', '..', 'uploads', file.url, file.originalname);
}
return this.combineFiles(file.url, file.originalname);
try{
this.combineFiles(file.url, file.originalname);
}catch(err){
this.loggerService.error(`downloadFile: ${err}`);
}

}

async deleteFile(url: string): Promise<string> {
async deleteFileUtil(url: string): Promise<string> {
return new Promise(() => {
fs.unlink(url, (error) => {
if (error) {
Expand All @@ -183,7 +185,7 @@ export class FilesService {
});
}

async deleteFolder(fileID: ObjectId, location: string): Promise<string> {
async delete(fileID: ObjectId, location: string): Promise<string> {
const file = await this.fileModel.findById(fileID.toString());
if(!file) {
this.loggerService.error(`File with ID ${fileID} does not exist`)
Expand Down
7 changes: 3 additions & 4 deletions server/src/files/scripts/divider.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,17 @@
import math
import json

if len(sys.argv) < 3:
print('Usage: python divider.py <fileName> <extension>')
if len(sys.argv) < 2:
print('Usage: python divider.py <fileName>')
sys.exit(1)

file_name = sys.argv[1]
extension = sys.argv[2]
file_size = os.path.getsize(os.path.join('uploads', os.path.basename(file_name)))
file_path = os.path.join('uploads', file_name)

gem_size = 1024 * 1024
num_gems = math.ceil(file_size / gem_size)
output_dir = os.path.join('uploads', os.path.basename(file_name + extension))
output_dir = os.path.join('uploads', os.path.basename(file_name+".dir"))

os.makedirs(output_dir, exist_ok=True)

Expand Down
11 changes: 6 additions & 5 deletions server/src/user/schema/user.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ export const userFileRecord = new mongoose.Schema({
required:true,
},
fileID:{
type: mongoose.Schema.Types.ObjectId,
required: true,
type: mongoose.Schema.Types.ObjectId,
ref: 'Files',
required: true,
},
role: [{
type: String,
enum: [IRole.VIEWER, IRole.EDITOR, IRole.OWNER],
required: true,
type: String,
enum: [IRole.VIEWER, IRole.EDITOR, IRole.OWNER],
required: true,
}]
});

Expand Down

0 comments on commit 2d6021f

Please sign in to comment.