Bug fixes, logic polishing

This commit is contained in:
MrFry 2020-01-25 17:37:24 +01:00
parent 2c2fc762ba
commit 692c41bb7f

View file

@ -62,7 +62,7 @@
// forcing pages for testing. unless you test, do not set these to true!
// only one of these should be true for testing
const forceTestPage = true
const forceTestPage = false
const forceResultPage = false
const forceDefaultPage = false
const logElementGetting = false
@ -110,7 +110,6 @@
const commonUselessStringParts = [',', '\\.', ':', '!', '\\+']
const specialChars = [ '&', '\\+' ]
const lengthDiffMultiplier = 10 /* Percent minus for length difference */
const notSameDataTypePenalty = 30 // substracted from match percent if 2 questions are not same type
const assert = (val) => {
if (!val) { throw new Error('Assertion failed') }
@ -270,85 +269,6 @@
const SUtils = new StringUtils()
class Question {
constructor (q, a, data) {
this.Q = SUtils.SimplifyQuestion(q)
this.A = SUtils.SimplifyAnswer(a)
this.data = { ...data }
}
toString () {
if (this.data.type !== 'simple') {
return '?' + this.Q + '\n!' + this.A + '\n>' + JSON.stringify(this.data)
} else {
return '?' + this.Q + '\n!' + this.A
}
}
HasQuestion () {
return this.Q !== undefined
}
HasAnswer () {
return this.A !== undefined
}
HasImage () {
return this.data.type === 'image'
}
IsComplete () {
return this.HasQuestion() && this.HasAnswer()
}
CompareToQuestionObj (q2) {
const qmatchpercent = SUtils.CompareString(this.Q, q2.Q)
const amatchpercent = SUtils.CompareString(this.A, q2.A)
if (this.data.images !== undefined) {
const imatchpercent = this.data.images === undefined ? SUtils.CompareString(this.data.images.join(' '), q2.data.images.join(
' ')) : 0
return (qmatchpercent + amatchpercent + imatchpercent) / 3
} else {
return (qmatchpercent + amatchpercent) / 2
}
}
CompareImage (data2) {
return SUtils.CompareString(this.data.images.join(' '), data2.images.join(' '))
}
CompareToQuestionString (q2, data) {
assert(data)
let qmatchpercent = SUtils.CompareString(this.Q, q2)
let dataMatchPercent = 0
if (data.type === this.data.type) { // both questins are same type
if (data.type === 'simple') {
return qmatchpercent
} else if (data.type === 'image') {
dataMatchPercent = this.CompareImage(data)
}
return (qmatchpercent + dataMatchPercent) / 2
} else { // question types are not the same
dataMatchPercent = 0
qmatchpercent -= notSameDataTypePenalty
if (qmatchpercent < 0) { return 0 } else { return qmatchpercent }
}
}
Compare (q2, data) {
assert(q2)
if (typeof q2 === 'string') {
return this.CompareToQuestionString(q2, data)
} else {
return this.CompareToQuestionObj(q2)
}
}
}
// : }}}
// : DOM getting stuff {{{
@ -713,7 +633,9 @@
for (let j = 0; j < items.length; j++) {
let cn = items[j].className
if (cn.includes('correct') && !cn.includes('incorrect')) { return items[j].innerText }
if (cn.includes('correct') && !cn.includes('incorrect')) {
return items[j].getElementsByTagName('label')[0].innerText
}
}
if (items.length === 2) {
for (let j = 0; j < items.length; j++) {
@ -801,6 +723,7 @@
if (forceTestPage || forceResultPage || forceDefaultPage) {
if (document.getElementById('scriptMessage')) { document.getElementById('scriptMessage').style.background = 'green' }
}
ShowMenuList() // TODO: remove
}
// : }}}
@ -838,9 +761,10 @@
}
VersionActions()
if (!url.includes('.pdf')) { ShowMenu() }
GetXHRVersion().then((version) => {
lastestVersion = version
cwith(version)
GetXHRInfos().then((inf) => {
lastestVersion = inf.version
motd = inf.motd
cwith()
})
}
@ -882,17 +806,11 @@
}
var greetMsg = '' // message to show at the end
var timeout = null // the timeout. if null, it wont be hidden
// no new version, nothing loaded
var showSplash = (getVal('showSplash') === undefined) || getVal('showSplash') // getting value, if splash screen should be shown. Its true, if its undefined, or true
// no new version, everything loaded, and show splash is enabled. otherwise something happened, so showing it
if (!newVersion && showSplash) { // ------------------------------------------------------------------------------------------------
if (lastestVersion !== undefined && info().script.version !== lastestVersion) {
timeout = 5
greetMsg = 'Moodle/Elearning/KMOOC segéd v. ' + info().script.version + '. '
if (lastestVersion !== undefined && info().script.version !== lastestVersion) {
greetMsg += 'Új verzió elérhető: ' + lastestVersion + '\n'
timeout = undefined
}
greetMsg += 'Új verzió elérhető: ' + lastestVersion
timeout = undefined
}
if (newVersion) { // --------------------------------------------------------------------------------------------------------------
greetMsg = 'Moodle/Elearning/KMOOC segéd v. ' + info().script.version + '. Verzió frissítve ' + info().script.version + '-re. Changelog:\n' + texts.lastChangeLog
@ -936,19 +854,17 @@
var imgNodes = q.imgnodes
// ------------------------------------------------------------------------------------------------------
let promises = []
// TODO: test multiple promises
questions.forEach((x) => {
let question = SUtils.EmptyOrWhiteSpace(x) ? '' : SUtils.RemoveUnnecesarySpaces(x) // simplifying question
promises.push(GetXHRQuestionAnswer({
q: question,
data: GetImageDataFromImgNodes(imgNodes),
subj: '' // MPM.GetCurrentSubjectName() // TODO: set subj to '' if no result as backup plan
subj: MPM.GetCurrentSubjectName()
}))
})
// TODO: check answer order!
// FIXME: promise.all promise resolve order same as original?
Promise.all(promises).then((res) => {
console.log('All data recieved', res) // TODO: delete
let answers = []
res.forEach((result, j) => {
@ -1007,30 +923,26 @@
// : Quiz saving {{{
function HandleResults (url) {
var d = SaveQuiz(GetQuiz()) // saves the quiz questions and answers
if (d) { ShowSaveQuizDialog(d.addedQ, d.allQ, d.allOutput, d.output, d.sendSuccess, d.sentData) }
SaveQuiz(
GetQuiz(),
ShowSaveQuizDialog
) // saves the quiz questions and answers
}
function ShowSaveQuizDialog (addedQ, allQ, allOutput, output, sendSuccess, sentData) {
function ShowSaveQuizDialog (sendResult, sentData, newQuestions) {
// FIXME: normal string building with localisation :/
var msg = ''
if (addedQ > 0) {
msg = 'Klikk ide a nyers adatokhoz. ' + addedQ + ' új kérdés!'
if (!sendSuccess) { msg += ' Nem sikerült kérdéseket elküldeni szervernek. Ha gondolod utánanézhetsz.' } else { msg += 'Az új kérdések elküldve.' }
if (sendResult) {
msg = 'Kérdések elküldve, katt az elküldött adatokért. ' + newQuestions + ' új kérdés'
} else {
msg = 'A kérdőívben nincsen új kérdés. Ha mégis le akarod menteni klikk ide.'
// TODO if (!data) { msg += ' Lehet azért, mert nincs kérdés betöltve.' }
msg = 'Szerver nem elérhető, vagy egyéb hiba kérdések elküldésénél! (F12 -> Console)'
}
// showing a message wit the click event, and the generated page
ShowMessage({
m: msg,
isSimple: true
}, null, function () {
var towrite = '<h3>' + sentData.subj + '<br>TXT-ben nem szereplő kérdések: ' + addedQ + '/' + allQ + '</h3><br>' + output.replace(/\n/g, '<br>') + '<br><h3>Összes kérdés/válasz:</h3>' + allOutput.replace(
/\n/g, '<br>')
let towrite = ''
try {
towrite += '</p>Elküldött adatok:</p> ' + JSON.stringify(sentData)
} catch (e) {
@ -1086,32 +998,12 @@
}
// saves the current quiz. questionData contains the active subjects questions
function SaveQuiz (quiz) {
function SaveQuiz (quiz, next) {
try {
let sentData = {}
if (quiz.length === 0) {
throw new Error('quiz length is zero!')
}
var output = '' // thefinal output
var allOutput = '' // thefinal output with all questions
var allQ = 0
var addedQ = 0
var newQuestions = []
for (var i = 0; i < quiz.length; i++) {
// searching for same questions in questionData
var toAdd = '' // this will be added to some variable depending on if its already in the database
toAdd += '?' + SUtils.RemoveUnnecesarySpaces(quiz[i].Q) + '\n' // adding quiz question
toAdd += '!' + SUtils.RemoveUnnecesarySpaces(quiz[i].A) + '\n' // adding quiz answer
// TODO: hasimage
// if (quiz[i].HasImage()) {
// let imgString = quiz[i].data.images.join(', ')
// toAdd += '>' + imgString + '\n' // adding quiz image if there is any
// }
// TODO: search same question removed
allOutput += toAdd // adding to all
allQ++
}
var sendSuccess = false
var sentData = {}
try {
try {
sentData.subj = MPM.GetCurrentSubjectName()
@ -1119,24 +1011,16 @@
sentData.subj = 'NOSUBJ'
Log('unable to get subject name :c')
}
sentData.allData = quiz
sentData.data = newQuestions
sentData.version = info().script.version
sentData.id = GetId()
sentData.quiz = quiz
Log('SENT DATA', sentData)
SendXHRMessage('datatoadd=' + JSON.stringify(sentData))
sendSuccess = true
SendXHRMessage('datatoadd=' + JSON.stringify(sentData)).then((res) => {
next(res.success, sentData, res.newQuestions)
})
} catch (e) {
Exception(e, 'error at sending data to server.')
}
return {
addedQ: addedQ,
allQ: allQ,
allOutput: allOutput,
output: output,
sendSuccess: sendSuccess,
sentData: sentData
}
} catch (e) {
Exception(e, 'script error at saving quiz')
}
@ -1151,17 +1035,17 @@
var question = {} // the current question
// QUESTION --------------------------------------------------------------------------------------------------------------------
var q = RPM.GetQuestionFromResult(i)
if (q !== undefined) { question.q = SUtils.SimplifyQuestion(q) }
if (q !== undefined) { question.Q = SUtils.SimplifyQuestion(q) }
// RIGHTANSWER ---------------------------------------------------------------------------------------------------------------------
var a = RPM.GetRightAnswerFromResultv2(i)
if (a === undefined) { a = RPM.GetRightAnswerFromResult(i) }
if (a !== undefined) { question.a = SUtils.SimplifyAnswer(a) }
if (a !== undefined) { question.A = SUtils.SimplifyAnswer(a) }
// DATA ---------------------------------------------------------------------------------------------------------------------
question.data = GetDataFormResult(i)
if (question.a !== undefined) {
quiz.push(new Question(question.q, question.a, question.data)) // adding current question to quiz
if (question.A !== undefined) {
quiz.push(question) // adding current question to quiz
} else {
Log('error getting queston, no correct answer given, or its incorrect')
Log(question)
@ -1323,7 +1207,7 @@
var simpleMessageText = ''
if (msgItem.isSimple) { // parsing msgItem for easier use
simpleMessageText = msgItem.m
if (simpleMessageText === '') {
if (simpleMessageText === '') { // if msg is empty
return
}
msgItem = [
@ -1534,7 +1418,7 @@
var menuButtonDiv = document.createElement('div')
SetStyle(menuButtonDiv, {
width: buttonWidth + 'px',
height: buttonHeight + 'px',
// height: buttonHeight + 'px',
top: (window.innerHeight - buttonHeight * 1.5) + 'px',
left: window.innerWidth - buttonWidth * 1.5 + 'px',
zIndex: 999999,
@ -1644,167 +1528,17 @@
width: '98%'
})
// if (data && data.length > 0) {
// let grouped = data.Subjects.reduce((res, s) => {
// let sName = s.getSubjNameWithoutYear()
// if (sName) {
// if (!res[sName]) {
// res[sName] = []
// }
// res[sName].push(s)
// } else {
// res.others.push(s)
// }
// return res
// }, {
// others: []
// })
var scrollDiv = document.createElement('div')
scrollDiv.appendChild(subjTable)
scrollDiv.style.textAlign = 'center'
var subjtblrow = tbl.insertRow()
var subjtbltd = subjtblrow.insertCell()
subjtbltd.appendChild(scrollDiv)
// const ordered = {}
// Object.keys(grouped).sort().forEach((key) => {
// ordered[key] = grouped[key]
// })
// grouped = ordered
// let collapsibles = []
// // --------------------------------------------------------------------------------
// let searchBar = CreateNodeWithText(subjTable, '', 'input')
// SetStyle(searchBar, {
// backgroundColor: '#222d32',
// color: '#ffffff',
// width: '100%',
// border: 'none'
// })
// searchBar.placeholder = texts.search
// searchBar.addEventListener('keyup', function (e) {
// collapsibles.forEach((x) => {
// if (x.innerText.toLowerCase().includes(this.value.toLowerCase())) {
// x.style.display = ''
// } else {
// x.style.display = 'none'
// }
// })
// }) // adding click
// Object.entries(grouped).forEach(([subjName, subjGroup], i) => {
// let b = CreateNodeWithText(subjTable, subjName, 'div')
// SetStyle(b, {
// backgroundColor: '#222d32',
// color: '#ffffff',
// cursor: 'pointer',
// padding: '5px',
// width: '100%',
// border: 'none',
// textAlign: 'left',
// outline: 'none'
// })
// b.setAttribute('id', 'subjectGroup' + i)
// collapsibles.push(b)
// let content = document.createElement('div')
// SetStyle(content, {
// padding: '0 18px',
// overflow: 'hidden',
// backgroundColor: '#222d32',
// borderColor: '#212127',
// borderStyle: 'solid',
// borderWidth: '2px'
// })
// content.addEventListener('click', function (e) {
// e.stopPropagation()
// })
// let ifGroupActive = subjGroup.some((x) => {
// return x.getIfActive()
// })
// content.style.display = ifGroupActive ? 'block' : 'none'
// b.appendChild(content)
// let tbl = document.createElement('table')
// content.appendChild(tbl)
// subjGroup.forEach((subj) => {
// var row = tbl.insertRow()
// let td = row.insertCell()
// let text = subj.getYear() || subj.Name
// if (subj.length !== 0) { text += ' [ ' + subj.length + 'db ]' }
// CreateNodeWithText(td, text)
// td = row.insertCell()
// let checkbox = document.createElement('input') // new paragraph
// checkbox.type = 'checkbox'
// checkbox.style.background = 'white'
// checkbox.style.margin = '5px 5px 5px 5px' // fancy margin
// td.appendChild(checkbox) // adding text box to main td
// checkbox.checked = subj.active
// let i = subj.getIndex()
// checkbox.setAttribute('id', 'HelperTextNode' + i)
// checkbox.addEventListener('click', function () {
// var checked = document.getElementById('HelperTextNode' + i).checked
// data.ChangeActive(subj.Name, checked)
// }) // adding click
// })
// b.addEventListener('click', function (e) {
// this.classList.toggle('active')
// if (content.style.display === 'block') {
// content.style.display = 'none'
// } else {
// content.style.display = 'block'
// }
// })
// })
// var scrollDiv = document.createElement('div')
// scrollDiv.style.width = '100%'
// scrollDiv.style.height = window.innerHeight - (window.innerHeight * 0.4) + 'px'
// scrollDiv.style.overflow = 'auto'
// scrollDiv.appendChild(subjTable)
// var subjtblrow = tbl.insertRow()
// var subjtbltd = subjtblrow.insertCell()
// subjtbltd.appendChild(scrollDiv)
// } else { // if no data
// var noDataRow = tbl.insertRow()
// var noDataRowCell = noDataRow.insertCell()
// let textBox
// if (getVal('skipLoad')) {
// textBox = CreateNodeWithText(noDataRowCell,
// texts.passiveModeActivePopupMenuText
// )
// } else {
// textBox = CreateNodeWithText(noDataRowCell,
// texts.couldntLoadDataPopupMenuText
// )
// }
// textBox.style.margin = fiveMargin // fancy margin
// }
// show splash tickbox -----------------------------------------------------------------------------------------------------------------------------
var splasTickboxRow = tbl.insertRow()
var splashTickboxCell = splasTickboxRow.insertCell()
var splashTickBox = document.createElement('input')
SetStyle(splashTickBox, {
position: '',
left: 10 + 'px',
margin: '5px 5px 5px 5px',
top: menuDiv.offsetHeight + 'px'
// TODO: something in menubox
GetXHRSubjCount(true).then((res) => {
CreateNodeWithText(scrollDiv, `${res.subjects} tárgy, ${res.questions} kérdés`, 'div')
})
splashTickBox.type = 'checkbox'
splashTickBox.checked = getVal('showSplash') || false
splashTickboxCell.appendChild(splashTickBox) // adding to main div
splashTickBox.addEventListener('click', function () {
setVal('showSplash', splashTickBox.checked)
}) // adding clicktextNode
CreateNodeWithText(splashTickboxCell, texts.showGreetingOnEveryPage, 'span')
// setting up buttons
var buttonRow = tbl.insertRow()
@ -1910,12 +1644,30 @@
return paragraphElement
}
function GetXHRVersion () {
function GetXHRSubjCount () {
let url = 'datacount'
return new Promise((resolve, reject) => {
xmlhttpRequest({
method: 'GET',
url: serverAdress + 'version',
url: serverAdress + url,
onload: function (response) {
resolve(JSON.parse(response.responseText))
},
onerror: (e) => {
console.log('GET ERROR', e)
reject(new Error('get error'))
}
})
})
}
function GetXHRInfos () {
return new Promise((resolve, reject) => {
xmlhttpRequest({
method: 'GET',
url: serverAdress + 'infos?version=true&motd=true',
onload: function (response) {
// resolve(JSON.parse(response.responseText))
resolve(response.responseText)
},
onerror: (e) => {
@ -1927,7 +1679,6 @@
}
function GetXHRQuestionAnswer (question) {
console.log('sentquestion:', question) // TODO: remove
return new Promise((resolve, reject) => {
let url = serverAdress + 'q?'
let params = []
@ -1960,16 +1711,23 @@
function SendXHRMessage (message) {
var url = serverAdress + 'isAdding'
xmlhttpRequest({
method: 'POST',
url: url,
data: message,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
onerror: function (response) {
Log('XMLHTTP request POST error')
}
return new Promise((resolve, reject) => {
xmlhttpRequest({
method: 'POST',
url: url,
data: message,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
onerror: function (response) {
Log('XMLHTTP request POST error')
reject(new Error('unhandled error'))
},
onload: (resp) => {
console.log(resp.responseText)
resolve(JSON.parse(resp.responseText))
}
})
})
}