bigbluebutton-Github/bigbluebutton-html5/imports/api/captions/server/handlers/captionUpdate.js
2017-02-01 15:37:31 +00:00

182 lines
7.1 KiB
JavaScript

import Captions from '/imports/api/captions';
import Logger from '/imports/startup/server/logger';
import { check } from 'meteor/check';
import addCaption from '../modifiers/addCaption';
export default function handleCaptionUpdate({ payload }) {
const SERVER_CONFIG = Meteor.settings.app;
const CAPTION_CHUNK_LENGTH = SERVER_CONFIG.captionsChunkLength || 1000;
const meetingId = payload.meeting_id;
const locale = payload.locale;
check(meetingId, String);
check(locale, String);
let captionsObjects = Captions.find({
meetingId,
locale,
}, {
sort: {
locale: 1,
'captionHistory.index': 1,
},
}).fetch();
let objectsToUpdate = [];
if (captionsObjects != null) {
let startIndex;
let endIndex;
let length = 0;
let current = captionsObjects[0];
//looking for a start index and end index
//(end index only for the case when they are in the same block)
while (current != null) {
length += current.captionHistory.captions.length;
//if length is bigger than start index - we found our start index
if (length >= payload.start_index && startIndex == undefined) {
//check if it's a new character somewhere in the middle of captions text
if (length - 1 >= payload.start_index) {
startIndex = payload.start_index - (length - current.captionHistory.captions.length);
//check to see if the end_index is in the same object as start_index
if (length - 1 >= payload.end_index) {
endIndex = payload.end_index - (length - current.captionHistory.captions.length);
let _captions = current.captionHistory.captions;
current.captionHistory.captions = _captions.slice(0, startIndex) +
payload.text +
_captions.slice(endIndex);
objectsToUpdate.push(current);
break;
//end index is not in the same object as start_index, we will find it later
} else {
current.captionHistory.captions = current.captionHistory.captions.slice(0, startIndex) +
payload.text;
objectsToUpdate.push(current);
break;
}
//separate case for appending new characters to the very end of the string
} else if (current.captionHistory.next == null &&
length == payload.start_index &&
length == payload.start_index) {
startIndex = 1;
endIndex = 1;
current.captionHistory.captions += payload.text;
objectsToUpdate.push(current);
}
}
current = captionsObjects[current.captionHistory.next];
}
//looking for end index here if it wasn't in the same object as start index
if (startIndex != undefined && endIndex == undefined) {
current = captionsObjects[current.captionHistory.next];
while (current != null) {
length += current.captionHistory.captions.length;
//check to see if the end_index is in the current object
if (length - 1 >= payload.end_index) {
endIndex = payload.end_index - (length - current.captionHistory.captions.length);
current.captionHistory.captions = current.captionHistory.captions.slice(endIndex);
objectsToUpdate.push(current);
break;
//if end_index wasn't in the current object, that means this whole object was deleted
//initializing string to ''
} else {
current.captionHistory.captions = '';
objectsToUpdate.push(current);
}
current = captionsObjects[current.captionHistory.next];
}
}
//looking for the strings which exceed the limit and split them into multiple objects
let maxIndex = captionsObjects.length - 1;
for (i = 0; i < objectsToUpdate.length; i++) {
if (objectsToUpdate[i].captionHistory.captions.length > CAPTION_CHUNK_LENGTH) {
//string is too large. Check if the next object exists and if it can
//accomodate the part of the string that exceeds the limits
let _nextIndex = objectsToUpdate[i].captionHistory.next;
if (_nextIndex != null &&
captionsObjects[_nextIndex].captionHistory.captions.length < CAPTION_CHUNK_LENGTH) {
let extraString = objectsToUpdate[i].captionHistory.captions.slice(CAPTION_CHUNK_LENGTH);
//could assign it directly, but our linter complained
let _captions = objectsToUpdate[i].captionHistory.captions;
_captions = _captions.slice(0, CAPTION_CHUNK_LENGTH);
objectsToUpdate[i].captionHistory.captions = _captions;
//check to see if the next object was added to objectsToUpdate array
if (objectsToUpdate[i + 1] != null &&
objectsToUpdate[i].captionHistory.next == objectsToUpdate[i + 1].captionHistory.index) {
objectsToUpdate[i + 1].captionHistory.captions = extraString +
objectsToUpdate[i + 1].captionHistory.captions;
//next object wasn't added to objectsToUpdate array, adding it from captionsObjects array.
} else {
let nextObj = captionsObjects[objectsToUpdate[i].captionHistory.next];
nextObj.captionHistory.captions = extraString + nextObj.captionHistory.captions;
objectsToUpdate.push(nextObj);
}
//next object was full already, so we create another and insert it in between them
} else {
//need to take a current object out of the objectsToUpdate and add it back after
//every other object, so that Captions collection could be updated in a proper order
let tempObj = objectsToUpdate.splice(i, 1);
let extraString = tempObj[0].captionHistory.captions.slice(CAPTION_CHUNK_LENGTH);
tempObj[0].captionHistory.captions = tempObj[0].captionHistory.captions.slice(0, CAPTION_CHUNK_LENGTH);
maxIndex += 1;
let tempIndex = tempObj[0].captionHistory.next;
tempObj[0].captionHistory.next = maxIndex;
while (extraString.length != 0) {
let entry = {
meetingId: meetingId,
locale: locale,
captionHistory: {
locale: locale,
ownerId: tempObj[0].captionHistory.ownerId,
captions: extraString.slice(0, CAPTION_CHUNK_LENGTH),
index: maxIndex,
next: null,
},
};
maxIndex += 1;
extraString = extraString.slice(CAPTION_CHUNK_LENGTH);
if (extraString.length > 0) {
entry.captionHistory.next = maxIndex;
} else {
entry.captionHistory.next = tempIndex;
}
objectsToUpdate.push(entry);
}
objectsToUpdate.push(tempObj[0]);
}
}
}
}
let captionsAdded = [];
objectsToUpdate.forEach(entry => {
const { _id, meetingId, locale, captionHistory } = entry;
captionsAdded.push(addCaption(meetingId, locale, captionHistory, _id));
});
return captionsAdded;
};