...
Code Block |
---|
|
this.allowSubmitallowSubmission(Boolean)
this.changeFormValue(field_name, new_value)
this.enableField(field_name, Boolean)
this.disableField(field_name)
this.mandatoryField(field_name, Boolean)
this.changeInputValue(field_name, value)
let
value = JSON.stringify(finalValues)
this.updateAnnotations(value)
let errorMsgs = []if(errorMsgs.length > 0) {
this.displayErrors(errorMsgs)
this.disAllowSubmit(true)
} else {
this.disAllowSubmit(false)
}
this.changeAnnotationClasses(newClass);
let inputText = inputValues[field_name]
let currentUserId = localStorage.getItem("userId")
if(currentUserLevel === 1) {
this.changeFormValue(field_name, `${currentUserId}`)
}
For NER:
let entities = _.get(annotations, "[0].value.annotations.entities", _.get(annotations, "annotations.entities", []))
To access form values in On-Change/on-Validation/On-save(also console the values coming from values and formValues then use as required):
let fieldNameValue = values["field_name"]
To access previous values in the on change code: (Useful to check if a particular field's value has changed')
let preValues = oldValues["field_name"]
To access annotations data in any annotation project
let anns = annotations |
Examples:
Audio transcription validation: No special characters allowed, tags validations, etc.
Code Block |
---|
let regexNotToMatch = {
"Add at least one space before the normal start tag.": /[^ ]<[^\/]*[^\/]*>/g,
"Add at least one space after the normal end tag.": /<\/\s*[^>]*>[^ ]/g,
"Add at least one space before and after a single tag.": /[^ ]<[^>]*\/>[^ ]|[^ ]<[^>]*\/>|<[^>]*\/>[^ ]/g,
"Numbers are not allowed.": /[0-9]/g,
"Special character: ^ ( ) { } [ ] ; : $ % * = are not allowed.": /[\^(){}\[\];:$%*=]/g,
"New line/Enter is not allowed.": /\n/g,
};
this.setState({ audioRegexNotToMatch: regexNotToMatch }); |
2. Generate 100 segments of transcription on load of a task:
Code Block |
---|
|
let finalValues =[]
let i=0
while(i < 100 ) {
i = i + 1
finalValues.push( {
"id": i,
"curTime": 0,
"endTime": i + 1,
"startTime": i ,
"UIstartTime": i + 1,
"UIendTime": i,
"split": 0,
"audiourl": "",
"pos": 0,
"transliterationData": "abc def ghi jxy lzg".split(" ").map(w => ({
"word": w,
"tags": [],
"languageTag": "",
"editedText": ""
}))
})
}
let x = JSON.stringify(finalValues)
this.updateAnnotations(x) |
3. Load classes for annotation projects using custom code:
...
...
hideOutputField(["field_name1", "field_name2"],"template_name")
this.unHideOutputField(["field_name1", "field_name2"],"template_name")
this.hideInputField(["field_name1", "field_name2"],"template_name")
this.unHideInputField(["field_name1", "field_name2"],"template_name")
this.hideUserBulkTaskButtons(["button 1 name", "button 2 name", …n])
this.unHideUserBulkTaskButtons(["button 1 name", "button 2 name", …n])
let value = JSON.stringify(finalValues)
this.updateAnnotations(value)
let errorMsgs = []if(errorMsgs.length > 0) {
this.displayErrors(errorMsgs)
this.disAllowSubmit(true)
} else {
this.disAllowSubmit(false)
}
this.changeAnnotationClasses(newClass);
let inputText = inputValues[field_name]
let currentUserId = localStorage.getItem("userId")
if(currentUserLevel === 1) {
this.changeFormValue(field_name, `${currentUserId}`)
}
For NER:
let entities = _.get(annotations, "[0].value.annotations.entities", _.get(annotations, "annotations.entities", []))
To access form values in On-Change/on-Validation/On-save(also console the values coming from values and formValues then use as required):
let fieldNameValue = values["field_name"]
To access previous values in the on change code: (Useful to check if a particular field's value has changed')
let preValues = oldValues["field_name"]
To access annotations data in any annotation project
let anns = annotations
|
Examples:
Audio transcription validation: No special characters allowed, tags validations, etc.
Code Block |
---|
let regexNotToMatch = {
"Add at least one space before the normal start tag.": /[^ ]<[^\/]*[^\/]*>/g,
"Add at least one space after the normal end tag.": /<\/\s*[^>]*>[^ ]/g,
"Add at least one space before and after a single tag.": /[^ ]<[^>]*\/>[^ ]|[^ ]<[^>]*\/>|<[^>]*\/>[^ ]/g,
"Numbers are not allowed.": /[0-9]/g,
"Special character: ^ ( ) { } [ ] ; : $ % * = are not allowed.": /[\^(){}\[\];:$%*=]/g,
"New line/Enter is not allowed.": /\n/g,
};
this.setState({ audioRegexNotToMatch: regexNotToMatch }); |
2. Generate 100 segments of transcription on load of a task:
Code Block |
---|
|
let finalValues =[]
let i=0
while(i < 100 ) {
i = i + 1
finalValues.push( {
"id": i,
"curTime": 0,
"endTime": i + 1,
"startTime": i ,
"UIstartTime": i + 1,
"UIendTime": i,
"split": 0,
"audiourl": "",
"pos": 0,
"transliterationData": "abc def ghi jxy lzg".split(" ").map(w => ({
"nameword": "Price"w,
"fieldTypetags": "Text"[],
"mandatoryFieldlanguageTag": false"",
"possible_value": [
editedText": ""
}))
})
}
],
let x = "default_value": ""
}
]
}),
CarJSON.stringify(finalValues)
this.updateAnnotations(x) |
3. Load classes for annotation projects using custom code:
Code Block |
---|
|
let newClass = {
Books: JSON.stringify({
"color": "#FF000#FFEBE8",
"hotkey": "c",
"attributes": [
{
"name": "attr1Price",
"fieldType": "DropDownText",
"mandatoryField": false,
"possible_value": [
"attr1_v1",
],
"attr1_v2" "default_value": ""
], }
]
}),
Car: JSON.stringify({
"default_value "color": "attr1_v1"#FF000",
"hotkey": "c",
},"attributes": [
{
"name": "attr2attr1",
"fieldType": "DropDown",
"mandatoryField": false,
"possible_value": [
"attr2attr1_v1",
"attr2attr1_v2"
],
"default_value": "attr2attr1_v1"
},
] }), {
Quills: JSON.stringify({ "color": "#C23456", "hotkeyname": "qattr2",
"attributes": [ {
"name": "Colour",
""fieldType": "TextDropDown",
"mandatoryField": false,
"possible_value": [
"Blueattr2_v1",
"Greenattr2_v2",
"Yellow"],
"default_value": "Redattr2_v1",
}
]
"White"}),
Quills: JSON.stringify({
"color": "#C23456",
"hotkey": "Orangeq",
"attributes": [
], {
"default_valuename": "blueColour",
} "fieldType": "Text",
] }), Tree: JSON.stringify({ "colormandatoryField": "#CCC"false,
"hotkey": "t", "attributespossible_value": [
{ "Blue",
"name": "attr1", "fieldType": "MultiDropDown",Green",
"mandatoryField": false,Yellow",
"possible_value": [Red",
"attr1_v1White",
"attr1_v2Orange"
],
"default_value": "blue"
},
]
}),
{ Tree: JSON.stringify({
"color": "#CCC",
"namehotkey": "attr2t",
"attributes": [
"fieldType": "Text", {
"mandatoryFieldname": false"attr1",
"possible_valuefieldType": ["MultiDropDown",
"mandatoryField": false,
"" "possible_value": [
], "defaultattr1_valuev1":,
"" } ]"attr1_v2"
}), Van: JSON.stringify({ "color": "#F24110", ],
"hotkeydefault_value": "v",
"attributes": [ },
{
"name": "Vansattr2",
"fieldType": "DropDownText",
"mandatoryField": false,
"possible_value": [
"Ferrari",
],
"Kia", "default_value": ""
"MG" }
]
}),
],
Van: JSON.stringify({
"color": "#F24110",
"default_valuehotkey": "v",
"attributes": [
} ] {
}) }; this.changeAnnotationClasses(newClass); |
4. Add groups for image and video annotation using custom code:
Code Block |
---|
|
let groupList = ["a", "b", "c", "d"]
localStorage.setItem("groups", JSON.stringify(groupList)) |
5. Load pre-annotations and classes from YOLO data
Code Block |
---|
|
let yoloData = inputValues["yolo-data"]
// split yolo annotation data to array of individual anno data
let re = /\b[\w.]+(?:[^\w\n]+[\w.]+){0,4}\b/g
let arrYoloAnno = yoloData.match(re);
/* Start: configure unique classes from custom code*/
// let yoloClasses = []
// arrYoloAnno.forEach(y => {
// let currentClass = y.substr(0, y.indexOf(" "))
// if(!yoloClasses.includes(currentClass)){
// yoloClasses.push(currentClass)
// }
// })
// make class data
// let newClass = {}
// yoloClasses.forEach(c => {
// let classValue = {
// "color": '#'+(0x1000000+Math.random()*0xffffff).toString(16).substr(1,6), // random color
// "hotkey": "",
// "attributes": []
// }
// newClass[c] = JSON.stringify(classValue)
// })
// this.changeAnnotationClasses(newClass);
/* End */
/* Class data*/
let newClass = {
"0": "Person",
"1": "Class1",
"2": "Class2",
"3": "Class3",
"4": "Class4",
"5": "Class5",
"6": "Class6",
"7": "Class7",
"8": "Class8",
"9": "Class9",
"99": "Face"
}
/**/
/* Start: convert yolo data to TM anno format and setting it as pre anno */
/*
The format of the YOLO label file is
Label_ID_1 X_CENTER_NORM Y_CENTER_NORM WIDTH_NORM HEIGHT_NORM
*/
let preAnno = arrYoloAnno.map((singleYoloAnno, ind) => {
let singleAnnoSplitData = singleYoloAnno.split(" ")
let X_CENTER = parseFloat(singleAnnoSplitData[1])
let Y_CENTER = parseFloat(singleAnnoSplitData[2])
let WIDTH_NORM = parseFloat(singleAnnoSplitData[3])/2
let HEIGHT_NORM = parseFloat(singleAnnoSplitData[4])/2
let firstPoint = [X_CENTER - WIDTH_NORM, Y_CENTER - HEIGHT_NORM]
let secondPoint = [X_CENTER + WIDTH_NORM, Y_CENTER - HEIGHT_NORM]
let thirdPoint = [X_CENTER + WIDTH_NORM, Y_CENTER + HEIGHT_NORM]
let fourthPoint = [X_CENTER - WIDTH_NORM, Y_CENTER + HEIGHT_NORM]
return ({
"id":ind,
"label":[newClass[singleAnnoSplitData[0]]],
"shape":"rectangle",
"points":[firstPoint,secondPoint,thirdPoint,fourthPoint],
"notes":"",
"annotationGroups":"",
"attributes":{},
"imageWidth":undefined,
"imageHeight":undefined
})
})
/* End */
let x = JSON.stringify(preAnno)
this.updateAnnotations(x) |
6. Load pre-annotations from an input field (When imported from cloud json files)
Code Block |
---|
|
let preAnno = inputValues["Preannotations"]
if(!isNaN(currentUserLevel) && currentUserLevel == 1 && Array.isArray(annotations) && annotations.length > 0){
let annoData = []
let preAnnoArr = _.get(preAnno, "document.page[0].block", [])
let tmAnnoFormat = preAnnoArr.map((val, i) => {
return ({
"id":i,
"label":["car"],
"shape":"rectangle",
"points":[firstPoint,secondPoint,thirdPoint,fourthPoint],
"notes":"",
"annotationGroups":"",
"attributes":{},
"imageWidth":undefined,
"imageHeight":undefined
})
})
let x = JSON.stringify(tmAnnoFormat)
this.updateAnnotations(x)
}
|
7. Group label mandatory check for all objects
Code Block |
---|
|
/* START */
let alertMessage = []
annotations.forEach(anno => {
if(!_.get(anno, "annotationGroups") && !_.get(anno, "label", []).includes("other_value_text")) {
this.allowSubmit = false
alertMessage.push(`One of the objects of class ${_.get(anno, "label", [])[0]} of shape ${_.get(anno, "shape", "")} has not been added to a group.`)
}
})
if(alertMessage.length){
this.displayErrors(alertMessage)
} else {
this.allowSubmit = true
}
/* END */ |
8. NER: Load pre-annotations
Code Block |
---|
|
let x = {"text":"Ceci","start":1,"end":5,"id":0,"ws":true}
var anns = {}
anns["version"] = 2
anns["annotations"] = {}
anns["annotations"]["entities"] = []
anns["annotations"]["entities"].push({
"uuid": "1",
"start_offset": x["start"],
"end": x["end"],
"entity_pos":"",
"text": x["text"],
"attributes":{},
"taskId":"3517133",
"entity_type":"ORG"
})
let updateAnnoData = [{
"key": "3517133",
"value": anns
}]
console.log('preanns', updateAnnoData)
this.updateAnnotations(updateAnnoData) |
9. Track QC rejections using custom field.
Code Block |
---|
let currentUserId = localStorage.getItem("userId")
if(currentUserLevel === 1){
this.changeFormValue("annotator_id", `${currentUserId}`)
}
if(currentUserLevel === 2){
this.changeFormValue("QA_id", `${currentUserId}`)
if(rejectTaskDetails.commentHistory.length > 0){
console.log("QA_Flag set to true on load")
this.changeFormValue("QA_Flag", true)
}
} |
10. Format the NER output to plain text and write to an output field.
Code Block |
---|
|
/* O/P format: "gemini(brand),100 grams(quantity) */
let entities = _.get(annotations, "[0].value.annotations.entities", _.get(annotations, "annotations.entities", []))
if (entities.length > 0) {
entities.sort((a,b) => a.start_offset - b.start_offset)
var requiredOp = entities.reduce((accumulator, currentValue) => accumulator + `${currentValue.text}(${currentValue.entity_type}),`, "")
if(requiredOp[requiredOp.length - 1] == ","){
requiredOp = requiredOp.slice(0, requiredOp.length-1)
}
this.changeFormValue("tagged_output", requiredOp) |
11. Convert SRT to Taskmonk JSON and load pre-annotation for audio transcription.
Code Block |
---|
|
function time2sec(dateTime) {
let ms = dateTime.split(',')[1]
let hh = dateTime.split(':')[0]
let mm = dateTime.split(':')[1]
let ss = dateTime.split(':')[2].split(',')[0]
let ts = (parseInt(hh) * 3600) + (parseInt(mm) * 60) + parseInt(ss) + (parseInt(ms) / 1000)
return ts
}
let finalValues = []
let inputArray = inputValues["TEXT"].split(/\n\s*\n/)
let i=0
while(i < inputArray.length) {
i = i + 1
if(inputArray[i]) {
let startTime = time2sec(inputArray[i].split('\n')[1].split('-->')[0])
let endTime = time2sec(inputArray[i].split('\n')[1].split('-->')[1])
finalValues.push( {
"id": i,
"curTime": 0,
"endTime": endTime,
"startTime": startTime ,
"UIstartTime": startTime,
"UIendTime": endTime,
"split": 0,
"audiourl": "",
"pos": 0,
"transliterationData": inputArray[i].split('\n')[2].split(" ").map(w => ({
"word": w,
"tags": [],
"languageTag": "",
"editedText": ""
}))
})
}
}
let x = JSON.stringify(finalValues)
this.updateAnnotations(x) |
12. On load custom code to convert gdrive sharing urls to viewing url.
Code Block |
---|
|
function getIdFromUrl(url) { return url.match(/[-\w]{25,}/); }
let inputUrl = getIdFromUrl(inputValues["image"])[0]
this.changeInputValue("image", "https://drive.google.com/uc?export=view&id="+inputUrl) |
13. Excel view: Update all visible tasks based on changes in one task
Code Block |
---|
|
function getDupProdIds(tId, selectedInputValues, that) {
let dupProdIds = []
let selectedItemId = selectedInputValues["CATLG_ITEM_ID"]
for (let i = 0; i < allTasks.length; i++) {
let currentTaskInput = that.getInputValueByID(allTasks[i].taskValues.taskId)
let currentTaskItemId = currentTaskInput["CATLG_ITEM_ID"]
if(currentTaskItemId == selectedItemId)
dupProdIds.push(currentTaskInput["productID"])
}
return dupProdIds
}
let that = this
let tIdsInputValues = this.getInputValueByID(tID)
let val = values["Select Action"];
if(val == "Duplicate"){
let dpValuIds = getDupProdIds(tID, tIdsInputValues, that)
//dpValuIds()
console.log("dup", dpValuIds)
this.changeFormValue("dup_productID", dpValuIds.join(), tID)
} else {
this.changeFormValue("dup_productID", tIdsInputValues["productID"], tID)
} |
14. Enable/Disable Buttons:
The following custom code can be plugged in to disable/enable a few actions buttons conditionally.
...
Code Block |
---|
this.hideUserTaskButtons(["button 1 name", "button 2 name", …n]) |
ii. To unhide user action buttons
Code Block |
---|
this.unhideUserTaskButtons(["button 1 name", "button 2 name", …n]) |
Available options for button names:
Code Block |
---|
|
"SUBMIT & GET NEXT TASK"
"SAVE & EXIT"
"SKIP & GET NEXT TASK"
"SUBMIT TASK & EXIT" |
15. Enable/Disable fields in Excel View/Bulk tasks.
Code Block |
---|
let intentValue = values["Field_name"]
if (intentValue == "Field_name")
{
this.enableField("Field_name",tID)
this.enableField("Field_name",tID)
this.mandatoryField("Field_name",true,tID)
this.mandatoryField("Field_name",true,tID)
}
else if (intentValue == "Field_value" || intentValue == "Field_value" || intentValue == "Field_value" || intentValue == "Field_value" || intentValue == "Field_value" )
{
this.disableField("Field_name",tID)
this.disableField("Field_name",tID)
this.changeFormValue("Field_name", " ",tID)
this.changeFormValue("Field_name", " ",tID)
} |
16. Extract ASIN,customID and keywords from Amazon URL’s
Code Block |
---|
|
let getUrl = values["Competitor Exact URL"]
function ExtractASIN(url){
var ASINreg = new RegExp(/(?:\/)([A-Z0-9]{10})(?:$|\/|\?)/)
var cMatch = url.match(ASINreg)
if(cMatch == null){
return null
}
return cMatch[1]
}
function ExtractCID(urls){
var CustomCID = new RegExp(/customId=([A-Za-z0-9]+)/)
var cMatch1 = (urls).match(CustomCID)
if(cMatch1 == null){
return null
}
return cMatch1[1]
}
function ExtractKeywords(url) {
const regex = /keywords=([^&]+)/;
const match = url.match(regex);
const keywords = match ? decodeURIComponent(match[1].replace(/\+/g, ' ')) : null;
return keywords.replace(/\+/g, ' ');;
}
this.changeFormValue("Comp_ASIN", ExtractASIN(getUrl))
if (ExtractCID(getUrl)== null){
this.changeFormValue("CustomID", "Not available")
}
else{
this.changeFormValue("CustomID", ExtractCID(getUrl))
}
if (ExtractKeywords(getUrl)== null){
this.changeFormValue("Source_Of_Search", "Not available")
}
else {
this.changeFormValue("Source_Of_Search", ExtractKeywords(getUrl))
} |
17. Generate rows in a name-value pair field
...
...
"name": "Vans",
"fieldType": "DropDown",
"mandatoryField": false,
"possible_value": [
"Ferrari",
"Kia",
"MG"
],
"default_value": ""
}
]
})
};
this.changeAnnotationClasses(newClass); |
4. Add groups for image and video annotation using custom code:
Code Block |
---|
|
let groupList = ["a", "b", "c", "d"]
localStorage.setItem("groups", JSON.stringify(groupList)) |
5. Load pre-annotations and classes from YOLO data
Code Block |
---|
|
let yoloData = inputValues["yolo-data"]
// split yolo annotation data to array of individual anno data
let re = /\b[\w.]+(?:[^\w\n]+[\w.]+){0,4}\b/g
let arrYoloAnno = yoloData.match(re);
/* Start: configure unique classes from custom code*/
// let yoloClasses = []
// arrYoloAnno.forEach(y => {
// let currentClass = y.substr(0, y.indexOf(" "))
// if(!yoloClasses.includes(currentClass)){
// yoloClasses.push(currentClass)
// }
// })
// make class data
// let newClass = {}
// yoloClasses.forEach(c => {
// let classValue = {
// "color": '#'+(0x1000000+Math.random()*0xffffff).toString(16).substr(1,6), // random color
// "hotkey": "",
// "attributes": []
// }
// newClass[c] = JSON.stringify(classValue)
// })
// this.changeAnnotationClasses(newClass);
/* End */
/* Class data*/
let newClass = {
"0": "Person",
"1": "Class1",
"2": "Class2",
"3": "Class3",
"4": "Class4",
"5": "Class5",
"6": "Class6",
"7": "Class7",
"8": "Class8",
"9": "Class9",
"99": "Face"
}
/**/
/* Start: convert yolo data to TM anno format and setting it as pre anno */
/*
The format of the YOLO label file is
Label_ID_1 X_CENTER_NORM Y_CENTER_NORM WIDTH_NORM HEIGHT_NORM
*/
let preAnno = arrYoloAnno.map((singleYoloAnno, ind) => {
let singleAnnoSplitData = singleYoloAnno.split(" ")
let X_CENTER = parseFloat(singleAnnoSplitData[1])
let Y_CENTER = parseFloat(singleAnnoSplitData[2])
let WIDTH_NORM = parseFloat(singleAnnoSplitData[3])/2
let HEIGHT_NORM = parseFloat(singleAnnoSplitData[4])/2
let firstPoint = [X_CENTER - WIDTH_NORM, Y_CENTER - HEIGHT_NORM]
let secondPoint = [X_CENTER + WIDTH_NORM, Y_CENTER - HEIGHT_NORM]
let thirdPoint = [X_CENTER + WIDTH_NORM, Y_CENTER + HEIGHT_NORM]
let fourthPoint = [X_CENTER - WIDTH_NORM, Y_CENTER + HEIGHT_NORM]
return ({
"id":ind,
"label":[newClass[singleAnnoSplitData[0]]],
"shape":"rectangle",
"points":[firstPoint,secondPoint,thirdPoint,fourthPoint],
"notes":"",
"annotationGroups":"",
"attributes":{},
"imageWidth":undefined,
"imageHeight":undefined
})
})
/* End */
let x = JSON.stringify(preAnno)
this.updateAnnotations(x) |
6. Load pre-annotations from an input field (When imported from cloud json files)
Code Block |
---|
|
let preAnno = inputValues["Preannotations"]
if(!isNaN(currentUserLevel) && currentUserLevel == 1 && Array.isArray(annotations) && annotations.length > 0){
let annoData = []
let preAnnoArr = _.get(preAnno, "document.page[0].block", [])
let tmAnnoFormat = preAnnoArr.map((val, i) => {
return ({
"id":i,
"label":["car"],
"shape":"rectangle",
"points":[firstPoint,secondPoint,thirdPoint,fourthPoint],
"notes":"",
"annotationGroups":"",
"attributes":{},
"imageWidth":undefined,
"imageHeight":undefined
})
})
let x = JSON.stringify(tmAnnoFormat)
this.updateAnnotations(x)
}
|
7. Group label mandatory check for all objects
Code Block |
---|
|
/* START */
let alertMessage = []
annotations.forEach(anno => {
if(!_.get(anno, "annotationGroups") && !_.get(anno, "label", []).includes("other_value_text")) {
this.allowSubmit = false
alertMessage.push(`One of the objects of class ${_.get(anno, "label", [])[0]} of shape ${_.get(anno, "shape", "")} has not been added to a group.`)
}
})
if(alertMessage.length){
this.displayErrors(alertMessage)
} else {
this.allowSubmit = true
}
/* END */ |
8. NER: Load pre-annotations
Code Block |
---|
|
let x = {"text":"Ceci","start":1,"end":5,"id":0,"ws":true}
var anns = {}
anns["version"] = 2
anns["annotations"] = {}
anns["annotations"]["entities"] = []
anns["annotations"]["entities"].push({
"uuid": "1",
"start_offset": x["start"],
"end": x["end"],
"entity_pos":"",
"text": x["text"],
"attributes":{},
"taskId":"3517133",
"entity_type":"ORG"
})
let updateAnnoData = [{
"key": "3517133",
"value": anns
}]
console.log('preanns', updateAnnoData)
this.updateAnnotations(updateAnnoData) |
9. Track QC rejections using custom field.
Code Block |
---|
let currentUserId = localStorage.getItem("userId")
if(currentUserLevel === 1){
this.changeFormValue("annotator_id", `${currentUserId}`)
}
if(currentUserLevel === 2){
this.changeFormValue("QA_id", `${currentUserId}`)
if(rejectTaskDetails.commentHistory.length > 0){
console.log("QA_Flag set to true on load")
this.changeFormValue("QA_Flag", true)
}
} |
10. Format the NER output to plain text and write to an output field.
Code Block |
---|
|
/* O/P format: "gemini(brand),100 grams(quantity) */
let entities = _.get(annotations, "[0].value.annotations.entities", _.get(annotations, "annotations.entities", []))
if (entities.length > 0) {
entities.sort((a,b) => a.start_offset - b.start_offset)
var requiredOp = entities.reduce((accumulator, currentValue) => accumulator + `${currentValue.text}(${currentValue.entity_type}),`, "")
if(requiredOp[requiredOp.length - 1] == ","){
requiredOp = requiredOp.slice(0, requiredOp.length-1)
}
this.changeFormValue("tagged_output", requiredOp) |
11. Convert SRT to Taskmonk JSON and load pre-annotation for audio transcription.
Code Block |
---|
|
function time2sec(dateTime) {
let ms = dateTime.split(',')[1]
let hh = dateTime.split(':')[0]
let mm = dateTime.split(':')[1]
let ss = dateTime.split(':')[2].split(',')[0]
let ts = (parseInt(hh) * 3600) + (parseInt(mm) * 60) + parseInt(ss) + (parseInt(ms) / 1000)
return ts
}
let finalValues = []
let inputArray = inputValues["TEXT"].split(/\n\s*\n/)
let i=0
while(i < inputArray.length) {
i = i + 1
if(inputArray[i]) {
let startTime = time2sec(inputArray[i].split('\n')[1].split('-->')[0])
let endTime = time2sec(inputArray[i].split('\n')[1].split('-->')[1])
finalValues.push( {
"id": i,
"curTime": 0,
"endTime": endTime,
"startTime": startTime ,
"UIstartTime": startTime,
"UIendTime": endTime,
"split": 0,
"audiourl": "",
"pos": 0,
"transliterationData": inputArray[i].split('\n')[2].split(" ").map(w => ({
"word": w,
"tags": [],
"languageTag": "",
"editedText": ""
}))
})
}
}
let x = JSON.stringify(finalValues)
this.updateAnnotations(x) |
12. On load custom code to convert gdrive sharing urls to viewing url.
Code Block |
---|
|
function getIdFromUrl(url) { return url.match(/[-\w]{25,}/); }
let inputUrl = getIdFromUrl(inputValues["image"])[0]
this.changeInputValue("image", "https://drive.google.com/uc?export=view&id="+inputUrl) |
13. Excel view: Update all visible tasks based on changes in one task
Code Block |
---|
|
function getDupProdIds(tId, selectedInputValues, that) {
let dupProdIds = []
let selectedItemId = selectedInputValues["CATLG_ITEM_ID"]
for (let i = 0; i < allTasks.length; i++) {
let currentTaskInput = that.getInputValueByID(allTasks[i].taskValues.taskId)
let currentTaskItemId = currentTaskInput["CATLG_ITEM_ID"]
if(currentTaskItemId == selectedItemId)
dupProdIds.push(currentTaskInput["productID"])
}
return dupProdIds
}
let that = this
let tIdsInputValues = this.getInputValueByID(tID)
let val = values["Select Action"];
if(val == "Duplicate"){
let dpValuIds = getDupProdIds(tID, tIdsInputValues, that)
//dpValuIds()
console.log("dup", dpValuIds)
this.changeFormValue("dup_productID", dpValuIds.join(), tID)
} else {
this.changeFormValue("dup_productID", tIdsInputValues["productID"], tID)
} |
14. Enable/Disable Buttons:
The following custom code can be plugged in to disable/enable a few actions buttons conditionally.
i. To hide user action buttons
Code Block |
---|
this.hideUserTaskButtons(["button 1 name", "button 2 name", …n]) |
ii. To unhide user action buttons
Code Block |
---|
this.unhideUserTaskButtons(["button 1 name", "button 2 name", …n]) |
Available options for button names:
Code Block |
---|
|
"SUBMIT & GET NEXT TASK"
"SAVE & EXIT"
"SKIP & GET NEXT TASK"
"SUBMIT TASK & EXIT" |
15. Enable/Disable fields in Excel View/Bulk tasks.
Code Block |
---|
let intentValue = values["Field_name"]
if (intentValue == "Field_name")
{
this.enableField("Field_name",tID)
this.enableField("Field_name",tID)
this.mandatoryField("Field_name",true,tID)
this.mandatoryField("Field_name",true,tID)
}
else if (intentValue == "Field_value" || intentValue == "Field_value" || intentValue == "Field_value" || intentValue == "Field_value" || intentValue == "Field_value" )
{
this.disableField("Field_name",tID)
this.disableField("Field_name",tID)
this.changeFormValue("Field_name", " ",tID)
this.changeFormValue("Field_name", " ",tID)
} |
16. Extract ASIN,customID and keywords from Amazon URL’s
Code Block |
---|
|
let getUrl = values["Competitor Exact URL"]
function ExtractASIN(url){
var ASINreg = new RegExp(/(?:\/)([A-Z0-9]{10})(?:$|\/|\?)/)
var cMatch = url.match(ASINreg)
if(cMatch == null){
return null
}
return cMatch[1]
}
function ExtractCID(urls){
var CustomCID = new RegExp(/customId=([A-Za-z0-9]+)/)
var cMatch1 = (urls).match(CustomCID)
if(cMatch1 == null){
return null
}
return cMatch1[1]
}
function ExtractKeywords(url) {
const regex = /keywords=([^&]+)/;
const match = url.match(regex);
const keywords = match ? decodeURIComponent(match[1].replace(/\+/g, ' ')) : null;
return keywords.replace(/\+/g, ' ');;
}
this.changeFormValue("Comp_ASIN", ExtractASIN(getUrl))
if (ExtractCID(getUrl)== null){
this.changeFormValue("CustomID", "Not available")
}
else{
this.changeFormValue("CustomID", ExtractCID(getUrl))
}
if (ExtractKeywords(getUrl)== null){
this.changeFormValue("Source_Of_Search", "Not available")
}
else {
this.changeFormValue("Source_Of_Search", ExtractKeywords(getUrl))
} |
17. Generate rows in a name-value pair field
Code Block |
---|
|
let lineItems = []
let i = 0
/* To generate two empty rows */
while(i < 2) {
lineItems.push({
"weight": "",
"unit": ""
})
i += 1
}
/* Variant is the field name */
if(Array.isArray(lineItems)){
this.changeFormValue("Variant", JSON.stringify(lineItems))
} |
Calculation of IOU at level 3 for rejection logic
Code Block |
---|
|
if(currentUserLevel == 3) {
let totalIOU = 0
let totalAnnotations = annotations.length
for (let step = 0; step < totalAnnotations; step++) {
// Current level annotation points for a box
let ann1 = annotations[step]["points"]
// Get previous level annotation points for the same box
let ann2 = JSON.parse(initialValues["Annotations"])[step]["points"]
let x1 = ann1[0][0]
let x2 = ann1[2][0]
let x3 = ann2[0][0]
let x4 = ann2[2][0]
let y1 = ann1[0][1]
let y2 = ann1[2][1]
let y3 = ann2[0][1]
let y4 = ann2[2][1]
let x_inter1 = Math.max(x1, x3)
let x_inter2 = Math.min(x2, x4)
let y_inter1 = Math.max(y1, y3)
let y_inter2 = Math.min(y2, y4)
console.log(x_inter1, y_inter2)
let width = x_inter2 -x_inter1
let height = y_inter2 - y_inter1
let area_inter = width * height
let width_box1 = x2 - x1
let width_box2 = x4 - x3
let height_box1 = y2 - y1
let height_box2 = y4 - y3
let area_box1 = width_box1 * height_box1
let area_box2 = width_box2 * height_box2
let area_union = area_box1 + area_box2 - area_inter
let iou = area_inter / area_union
totalIOU = totalIOU + iou
}
//Average IOU between level 3 and previous level annotations
let avgIOU = totalIOU/totalAnnotations
if (avgIOU < 0.90) {
alert("IOU dropped below 0.9")
}
} |