Skip to content

Commit

Permalink
multiple file sharing init
Browse files Browse the repository at this point in the history
  • Loading branch information
abhipatel0211 committed Mar 31, 2024
1 parent 54fcaab commit 17a8a77
Show file tree
Hide file tree
Showing 17 changed files with 1,329 additions and 356 deletions.
92 changes: 78 additions & 14 deletions apps/meteor/app/api/server/lib/getUploadFormData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,59 +26,118 @@ export async function getUploadFormData<
validate?: V;
sizeLimit?: number;
} = {},
): Promise<UploadResult<K>> {
): Promise<(UploadResult<K> | undefined)[]> {
// const sizeLimit = options.sizeLimit || 1024 * 1024 * 1024; // 1GB limit
console.log("options from getUploadFormData", options.field +" " + options.validate+" "+options.sizeLimit);
const limits = {
files: 1,
files: 6,
...(options.sizeLimit && options.sizeLimit > -1 && { fileSize: options.sizeLimit }),
};

const bb = busboy({ headers: request.headers, defParamCharset: 'utf8', limits });
console.log("inside getUploadFormData", limits);

const bb = busboy({ headers: request.headers, defParamCharset: 'utf8', limits ,highWaterMark: 2 * 1024 * 1024 });
const fields = Object.create(null) as K;
console.log("fields from getUploadFormData", fields);

let uploadedFile: UploadResult<K> | undefined;

let returnResult = (_value: UploadResult<K>) => {
// noop
};
let uploadedArray: (UploadResult<K> | undefined)[] = [];



// // let uploadedFile: (UploadResult<K> | undefined) = {};
// const uploadResultArray = Object.values(uploadedFile);

let returnResult = (values: (UploadResult<K> | undefined)[] ) => {
// Your implementation here
};

let returnError = (_error?: Error | string | null | undefined) => {
// noop
};

function onField(fieldname: keyof K, value: K[keyof K]) {
console.log("key value form getUploadFormData", fieldname, value)
console.log("value form getUploadFormData", value)
if(Array.isArray(value)) {
for(let i = 0; i < value.length; i++) {
console.log("value form getUploadFormData", value[i])
// onField(fieldname, value[i]);
}
}
console.log("onfield called from the getuploadformdaata");
fields[fieldname] = value;
}

console.log("fields from getUploadFormData2 ", fields);
function onEnd() {
if (!uploadedFile) {
console.log("onend from getUploadFormData");
uploadedArray.forEach((file) => {
if (!file) {
console.log("error from getUploadFormData uploadedfile");
return returnError(new MeteorError('No file uploaded'));
}
if (options.validate !== undefined && !options.validate(fields)) {
console.log("error from getUploadFormData", options.validate.errors?.join(', '));
return returnError(new MeteorError(`Invalid fields ${options.validate.errors?.join(', ')}`));
}
return returnResult(uploadedFile);
console.log("returnResult from getUploadFormData");
console.log(file);
})
if (!uploadedFile) {
console.log("error from getUploadFormData uploadedfile");
return returnError(new MeteorError('No file uploaded'));
}
// if (options.validate !== undefined && !options.validate(fields)) {
// console.log("error from getUploadFormData", options.validate.errors?.join(', '));
// return returnError(new MeteorError(`Invalid fields ${options.validate.errors?.join(', ')}`));
// }
console.log("return very last Result from getUploadFormData ");

// if (uploadedArray.length > 0) {
// const validResults = uploadedArray.filter((result): result is UploadResult<K> => result !== undefined);
// return returnResult(validResults);
// }
// if(uploadedArray.length > 0) {
// return returnResult(uploadedArray);
// }
// console.log(uploadedFile);
if(uploadedArray.length < 1){
return returnError(new MeteorError('No file uploaded'));
}
console.log("return result from the getuploadformdata "+ uploadedArray[0]);
return returnResult(uploadedArray);
}



function onFile(
fieldname: string,
file: Readable & { truncated: boolean },
{ filename, encoding, mimeType: mimetype }: { filename: string; encoding: string; mimeType: string },
) {
// here only single file comes in the array format
console.log(`onFile: ${fieldname}, ${filename}, ${encoding}, ${mimetype}`);
console.log("file from getuploadformdata", file);

console.log("key value form the onfile in gertuploadformdata",file,filename);
if (options.field && fieldname !== options.field) {
file.resume();
return returnError(new MeteorError('invalid-field'));
}

console.log("from onfield ");
const fileChunks: Uint8Array[] = [];
file.on('data', (chunk) => {
fileChunks.push(chunk);
console.log("chunks here");
});
console.log("made chunks from getuploadformdata.ts " + fileChunks);

file.on('end', () => {
if (file.truncated) {
fileChunks.length = 0;
return returnError(new MeteorError('error-file-too-large'));
}

uploadedFile = {
file,
filename,
Expand All @@ -88,6 +147,9 @@ export async function getUploadFormData<
fields,
fileBuffer: Buffer.concat(fileChunks),
};
console.log("inside onend from getuploadformdata.ts" + uploadedFile);
uploadedArray.push(uploadedFile);
console.log(uploadedArray.length);
});
}

Expand All @@ -102,18 +164,20 @@ export async function getUploadFormData<
bb.on('close', cleanup);
bb.on('end', onEnd);
bb.on('finish', onEnd);

bb.on('error', (err: Error) => {
console.log('bb error', err);
returnError(err);
});

bb.on('partsLimit', () => {
console.log('bb partsLimit');
returnError();
});
bb.on('filesLimit', () => {
returnError('Just 1 file is allowed');
returnError(`Just ${limits.files} file is allowed`);
});
bb.on('fieldsLimit', () => {
console.log('bb fieldsLimit');
returnError();
});

Expand Down
163 changes: 136 additions & 27 deletions apps/meteor/app/api/server/v1/rooms.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Media } from '@rocket.chat/core-services';
import type { IRoom } from '@rocket.chat/core-typings';
import type { IRoom, IUpload, IMessage } from '@rocket.chat/core-typings';
import { Messages, Rooms, Users } from '@rocket.chat/models';
import type { Notifications } from '@rocket.chat/rest-typings';
import { isGETRoomsNameExists } from '@rocket.chat/rest-typings';
Expand Down Expand Up @@ -141,52 +141,161 @@ API.v1.addRoute(
{ authRequired: true },
{
async post() {
console.log('1 Uploading file to room from rooms.ts : ', this.urlParams.rid);
// console.log("this from rooms.ts : "+this.request.body.file);

if (Array.isArray(this.request.body.file)) {
console.log('file is array from rooms.ts : ' + this.request.body.file.length);
}
// for(var x of this.entries()){
// console.log((x[0]+":"+x[1]));
// // console.log("x from rooms.ts : "+x);
// }
// console.log("this from rooms.ts file first: "+this.urlParams);
// console.log("this from rooms.ts filename first: "+this.urlParams);

if (!(await canAccessRoomIdAsync(this.urlParams.rid, this.userId))) {
console.log('1. inside if Uploading file to room from rooms.ts : ', this.urlParams.rid);
return API.v1.unauthorized();
}

const file = await getUploadFormData(
console.log('2 Uploading file to room from rooms.ts : ', this.urlParams.rid);
const files = await getUploadFormData(
{
request: this.request,
},
{ field: 'file', sizeLimit: settings.get<number>('FileUpload_MaxFileSize') },
);

if (!file) {
throw new Meteor.Error('invalid-field');
}
console.log('3 Uploading complete and response from file to room from rooms.ts : ', files);
let uploadedArray: Partial<IUpload>[] = [];
let message: IMessage | null = null;
var fieldarr: Record<string, string>[] = [];

const { fields } = file;
let { fileBuffer } = file;

const details = {
name: file.filename,
size: fileBuffer.length,
type: file.mimetype,
rid: this.urlParams.rid,
userId: this.userId,
};

const stripExif = settings.get('Message_Attachments_Strip_Exif');
if (stripExif) {
// No need to check mime. Library will ignore any files without exif/xmp tags (like BMP, ico, PDF, etc)
fileBuffer = await Media.stripExifFromBuffer(fileBuffer);
}
for (let i = 0; i < files.length; i++) {
const file = files[i];
console.log('1 file from rooms.ts : ', file);

const fileStore = FileUpload.getStore('Uploads');
const uploadedFile = await fileStore.insert(details, fileBuffer);
if (!file) {
console.log('no file found');
throw new Meteor.Error('invalid-field');
}

uploadedFile.description = fields.description;
const { fields } = file;
let { fileBuffer } = file;

delete fields.description;
const details = {
name: file.filename,
size: fileBuffer.length,
type: file.mimetype,
rid: this.urlParams.rid,
userId: this.userId,
};

await sendFileMessage(this.userId, { roomId: this.urlParams.rid, file: uploadedFile, msgData: fields });
console.log('Details from rooms.ts : ', details);

const message = await Messages.getMessageByFileIdAndUsername(uploadedFile._id, this.userId);
const stripExif = settings.get('Message_Attachments_Strip_Exif');
if (stripExif) {
// No need to check mime. Library will ignore any files without exif/xmp tags (like BMP, ico, PDF, etc)
console.log('stripExif indide if from rooms.ts : ', stripExif);
fileBuffer = await Media.stripExifFromBuffer(fileBuffer);
console.log('fileBuffer from rooms.ts : ', fileBuffer);
}
console.log('stripExif indide if from rooms.ts : ', stripExif);

const fileStore = FileUpload.getStore('Uploads');
console.log('fileStore from rooms.ts : ', fileStore);
let uploadedFile = await fileStore.insert(details, fileBuffer);
uploadedArray.push(uploadedFile);
// it store the file to db
console.log('uploadedFile from rooms.ts : ', uploadedFile, ' uploadedfile _id from rooms.ts : ' + uploadedFile._id);

uploadedFile.description = fields.description;
console.log('uploadedarray from rooms.ts : ' + uploadedArray.length + ' uploadedarray _id from rooms.ts : ' + uploadedArray[0]._id);
fieldarr.push(fields);
delete fields.description;


if (i === files.length-1) {
await sendFileMessage(this.userId, { roomId: this.urlParams.rid, file: uploadedArray, msgData: fieldarr[0] });
console.log("before msg from room.ts : id is ",uploadedArray[0]._id ? uploadedArray[0]._id : uploadedFile._id, this.userId );
message = await Messages.getMessageByFileIdAndUsername(uploadedArray[0]._id ? uploadedArray[0]._id : uploadedFile._id, this.userId);
console.log('upload file _id from rooms.ts : ' + uploadedFile._id + message);

return API.v1.success({
message,
});
}
}
// files.forEach(async (file) => {
// console.log("1 file from rooms.ts : ", file);

// if (!file) {
// console.log("no file found");
// throw new Meteor.Error('invalid-field');
// }

// const { fields } = file;
// let { fileBuffer } = file;

// const details = {
// name: file.filename,
// size: fileBuffer.length,
// type: file.mimetype,
// rid: this.urlParams.rid,
// userId: this.userId,
// };

// console.log("Details from rooms.ts : ", details);

// const stripExif = settings.get('Message_Attachments_Strip_Exif');
// if (stripExif) {
// // No need to check mime. Library will ignore any files without exif/xmp tags (like BMP, ico, PDF, etc)
// console.log("stripExif indide if from rooms.ts : ", stripExif);
// fileBuffer = await Media.stripExifFromBuffer(fileBuffer);
// console.log("fileBuffer from rooms.ts : ", fileBuffer);
// }
// console.log("stripExif indide if from rooms.ts : ", stripExif);

// const fileStore = FileUpload.getStore('Uploads');
// console.log("fileStore from rooms.ts : ", fileStore);
// const uploadedFile = await fileStore.insert(details, fileBuffer);
// // it store the file to db
// console.log("uploadedFile from rooms.ts : ", uploadedFile , " uploadedfile _id from rooms.ts : "+uploadedFile._id);

// uploadedFile.description = fields.description;
// uploadedArray.push(uploadedFile)
// console.log("uploadedarray from rooms.ts : "+uploadedArray.length+" uploadedarray _id from rooms.ts : "+uploadedArray[0]._id);
// fieldarr.push(fields);
// delete fields.description;

// message =await Messages.getMessageByFileIdAndUsername(uploadedFile?._id, this.userId);
// // await sendFileMessage(this.userId, { roomId: this.urlParams.rid, file: uploadedFile, msgData: fields });
// // console.log("message from rooms.ts : "+message);
// })
// const uploadedFile =uploadedArray[0];

// await sendFileMessage(this.userId, { roomId: this.urlParams.rid, file: uploadedArray, msgData: fieldarr[0] });
// await sendFileMessage(this.userId, { roomId: this.urlParams.rid, file: uploadedFile, msgData: fields });

// message =await Messages.getMessageByFileIdAndUsername(uploadedArray[0]?._id, this.userId);

console.log('upload file _id from rooms.ts : ' + uploadedArray[0]._id + message);

// const message = await Messages.getMessageByFileIdAndUsername(uploadedFile._id, this.userId);
// const fields

// await sendFileMessage(this.userId, { roomId: this.urlParams.rid, file: uploadedFile, msgData: fields });

return API.v1.success({
message,
});

// const message = await Messages.getMessageByFileIdAndUsername(uploadedFile._id, this.userId);

// return API.v1.success({
// message,
// });
},
},
);
Expand Down
2 changes: 2 additions & 0 deletions apps/meteor/app/file-upload/server/config/GridFS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ const readFromGridFS = async function (
const store = UploadFS.getStore(storeName);
const rs = await store.getReadStream(fileId, file);
const ws = new stream.PassThrough();
console.log("from gridfs",file);


[rs, ws].forEach((stream) =>
stream.on('error', (err) => {
Expand Down
Loading

0 comments on commit 17a8a77

Please sign in to comment.