diff --git a/stable.js b/stable.js index 1372c51..388535a 100644 --- a/stable.js +++ b/stable.js @@ -21,7 +21,7 @@ // ==UserScript== // @name Moodle/Elearning/KMOOC test help -// @version 1.6.3.3 +// @version 1.6.4.0 // @description Online Moodle/Elearning/KMOOC test help // @author MrFry // @match https://elearning.uni-obuda.hu/main/* @@ -36,7 +36,6 @@ // @license GNU General Public License v3.0 or later // @supportURL qmining.frylabs.net // @contributionURL qmining.frylabs.net -// @resource data file:/// // @namespace https://greasyfork.org/users/153067 // ==/UserScript== @@ -47,14 +46,13 @@ function getVal (name) { return GM_getValue(name) } function setVal (name, val) { return GM_setValue(name, val) } function openInTab (address, options) { GM_openInTab(address, options) } - function getResourceText (name) { return GM_getResourceText(name) } function xmlhttpRequest (opts) { GM_xmlhttpRequest(opts) } function info () { return GM_info } /* eslint-enable */ var data // all data, which is in the resource txt var addEventListener // add event listener function - const lastChangeLog = 'Félév szerinti csoportosítás menüben' + const lastChangeLog = 'Kérdés parsolás bugfixek, old school fálj beolvasás kiszedése, részletesebb hibajelentés és egyéb fixek' const serverAdress = 'https://qmining.frylabs.net/' // forcing pages for testing. unless you test, do not set these to true! @@ -73,9 +71,33 @@ const minResultMatchPercent = 99 /* Minimum ammount to consider that two questions match during saving */ const lengthDiffMultiplier = 10 /* Percent minus for length difference */ + // ------------------------------------------------------------------------------ + // Other constants + // ------------------------------------------------------------------------------ + const commonUselessAnswerParts = [ + 'A helyes válasz az ', + 'A helyes válasz a ', + 'A helyes válaszok: ', + 'A helyes válaszok:', + 'A helyes válasz: ', + 'A helyes válasz:', + 'The correct answer is:', + '\'' + ] + const commonUselessStringParts = [',', '\\.', ':', '!'] + // ------------------------------------------------------------------------------ + // : Class descriptions {{{ class StringUtils { + RemoveStuff (value, removableStrings) { + removableStrings.forEach((x) => { + var regex = new RegExp(x, 'g') + value = value.replace(regex, '') + }) + return value + } + SimplifyQuery (q) { assert(q) @@ -102,7 +124,7 @@ var toremove = this.NormalizeSpaces(val) var regex = new RegExp(char, 'g') - toremove.replace(regex, ' ') + toremove = toremove.replace(regex, ' ') return this.RemoveUnnecesarySpaces(toremove) } @@ -123,12 +145,13 @@ assert(value) value = this.RemoveUnnecesarySpaces(value).toLowerCase() - var removableChars = [',', '.', ':', '!'] - for (var i = 0; i < removableChars.length; i++) { - var regex = new RegExp(removableChars[i], 'g') - value.replace(regex, '') - } - return value + return this.RemoveStuff(value, commonUselessStringParts) + } + + RemoveSpecialChars (value) { + assert(value) + + return this.RemoveStuff(value, ['&']) } // if the value is empty, or whitespace @@ -149,6 +172,10 @@ assert(s1) assert(s2) + if (s1 === '' || s2 === '') { + return 0 + } + s1 = this.SimplifyStringForComparison(s1).split(' ') s2 = this.SimplifyStringForComparison(s2).split(' ') var match = 0 @@ -161,12 +188,81 @@ if (percent < 0) { percent = 0 } return percent } + + AnswerPreProcessor (value) { + assert(value) + + return this.RemoveStuff( + value, commonUselessAnswerParts) + } + + // 'a. pécsi sör' -> 'pécsi sör' + RemoveAnswerLetters (value) { + assert(value) + + let s = value.split('. ') + if (s[0].length < 2 && s.length > 1) { + return s.shift() + } else { + return value + } + } + + SimplifyQA (value, mods) { + if (!value) { return } + + const reducer = (res, fn) => { + return fn(res) + } + + return mods.reduce(reducer, value) + } + + SimplifyAnswer (value) { + return this.SimplifyQA( + value, + [ + this.RemoveSpecialChars.bind(this), + this.RemoveUnnecesarySpaces.bind(this), + this.AnswerPreProcessor.bind(this), + this.RemoveAnswerLetters.bind(this) + ]) + } + + SimplifyQuestion (value) { + return this.SimplifyQA( + value, + [ + this.RemoveSpecialChars.bind(this), + this.RemoveUnnecesarySpaces.bind(this) + ]) + } + + SimplifyStack (stack) { + stack = this.SimplifyQuery(stack) + let ns = '' + let adding = true + stack.split('').forEach((c) => { + if (c === '(') { + adding = false + } + + if (adding) { + ns += c + } + + if (c === ')') { + adding = true + } + }) + return ns + } } class Question { constructor (q, a, i) { - this.Q = q - this.A = a + this.Q = SUtils.SimplifyQuestion(q) + this.A = SUtils.SimplifyAnswer(a) this.I = i } @@ -625,15 +721,6 @@ return this.GetFormCFOfResult(results[i]).getElementsByTagName('img') } - GetOnlyImageQuestionResult (i) { - console.log('############################################################') - console.log(i) - const results = this.GetFormResult() // getting results element - const n = results[i] - console.log(n) - console.log('############################################################') - } - // gets the question from the result page // i is the index of the question GetQuestionFromResult (i) { @@ -682,11 +769,6 @@ if (RPM.GetDropboxes(i).length > 0) { return RPM.GetCurrentAnswer(i) } }) - // image and text only question - fun.push(function TryGet5 (i) { - return RPM.GetOnlyImageQuestionResult(i) - }) - // if the correct answers are not shown, and the selected answer // is correct fun.push(function TryGet2 (i) { @@ -810,11 +892,10 @@ ShowMessage({ m: 'Fatál error. Check console (f12). Kattints az üzenetre az összes kérdés/válaszért manuális kereséshez!', isSimple: true - }, undefined, function () { - openInTab(serverAdress + 'lred', { - active: true - }) + }, undefined, () => { + OpenErrorPage(e) }) + Exception(e, 'script error at main:') } if (url.includes('eduplayer')) { AddVideoHotkeys(url) } // adding video hotkeys @@ -899,13 +980,12 @@ function Version15 () { var version15 = getVal('version15') // if the current run is the frst if (version15 === undefined || version15 === true) { - setVal('useNetDB', '1') setVal('version15', false) document.write( '

Moodle teszt userscript:

1.5.0 verzió: a script mostantól XMLHTTP kéréseket küld szerver fele! Erre a userscript futtató kiegészitőd is figyelmeztetni fog! Ha ez történik, a script rendes működése érdekében engedélyezd (Always allow domain)! Ha nem akarod, hogy ez történjen, akkor ne engedélyezd, vagy a menüben válaszd ki a "helyi fájl használata" opciót!

Elküldött adatok: minden teszt után a kérdés-válasz páros. Fogadott adatok: Az összes eddig ismert kérdés. Érdemes help-et elolvasni!!!

Ez az ablak frissités után eltűnik. Ha nem, akkor a visza gombbal próbálkozz.
' ) document.close() - throw 'something, so this stuff stops' // eslint-disable-line + throw new Error('something, so this stuff stops') } } @@ -923,31 +1003,7 @@ // : }}} - function GetFileData () { - return getResourceText('data') - } - - function ReadFile (cwith) { - var resource = '' - try { - resource = GetFileData() // getting data from txt - if (resource === undefined) { - ShowMessage({ - m: 'Nem lehetett beolvasni a fájlt :c Ellenőrizd az elérési utat, vagy a fájl jogosultságokat', - isSimple: true - }) - return - } - if (SUtils.EmptyOrWhiteSpace(resource)) { - throw 'data file empty' // eslint-disable-line - } - } catch (e) { - Exception(e, 'script error at reading file:') - } - NLoad(resource, cwith) - } - - function ReadNetDB (cwith, useNetDB) { + function ReadNetDB (cwith) { function NewXMLHttpRequest () { const url = serverAdress + 'data.json' xmlhttpRequest({ @@ -970,105 +1026,7 @@ } } - /* - * Returns a question database from the given data. - * Parameter should be raw read file in string with "\n"-s - * */ - function ParseRawData (data) { - const d = data.split('\n') - const r = new QuestionDB() - var logs = [] - var currSubj = '' // the current subjects name - var ExpectedIdentifier = ['+', '?'] - let currQuestion = new Question() - - var i = -1 - while (i < d.length) { - let currIdentifier - let skipped = 0 - do { - if (skipped >= 1) { logs.push(i + ': ' + d[i]) } - i++ - if (i >= d.length) { - if (currQuestion.IsComplete()) { r.AddQuestion(currSubj, currQuestion) } - return { - result: r, - logs: logs - } - } - currIdentifier = d[i][0] - skipped++ - } while (!ExpectedIdentifier.includes(currIdentifier) && i < d.length) - - let currData = d[i].substring(1).trim() - - if (currIdentifier === '+') { - if (currQuestion.IsComplete()) { r.AddQuestion(currSubj, currQuestion) } - currQuestion = new Question() - currSubj = currData - ExpectedIdentifier = ['?'] - continue - } - - if (currIdentifier === '?') { - if (currQuestion.IsComplete()) { - r.AddQuestion(currSubj, currQuestion) - currQuestion = new Question() - } - // overwriting is allowed here, bcus: - // ?????!> - currQuestion.Q = currData - ExpectedIdentifier = ['!', '?'] - continue - } - - if (currIdentifier === '!') { - // if dont have question continue - if (!currQuestion.HasQuestion()) { - throw 'No question! (A)' // eslint-disable-line - } - // dont allow overwriting - // ?!!!! - if (!currQuestion.HasAnswer()) { - currData = currData.replace('A helyes válaszok: ', '') - currData = currData.replace('A helyes válasz: ', '') - - currQuestion.A = currData - } - ExpectedIdentifier = ['?', '>', '+'] - continue - } - - if (currIdentifier === '>') { - // if dont have question or answer continue - if (!currQuestion.HasQuestion()) { - throw 'No question! (I)' // eslint-disable-line - } - if (!currQuestion.HasAnswer()) { - throw 'No asnwer! (I)' // eslint-disable-line - } - // dont allow overwriting - // ?!>>> - if (!currQuestion.HasImage()) { - try { - currQuestion.I = JSON.parse(currData) - } catch (e) { - currQuestion.I = currData.split(',') - } - } - ExpectedIdentifier = ['?', '+'] - continue - } - } - - return { - result: r, - logs: logs - } - } - function Load (cwith) { - var useNetDB = getVal('useNetDB') let skipLoad = getVal('skipLoad') if (skipLoad) { @@ -1076,7 +1034,7 @@ return -1 } - if (useNetDB !== undefined && useNetDB === 1) { return ReadNetDB(cwith, useNetDB) } else { return ReadFile(cwith) } + ReadNetDB(cwith) } function LoadMOTD (resource) { @@ -1109,16 +1067,12 @@ d = JSON.parse(resource) } catch (e) { Log('Old data, trying with old methods....') - try { - d = ParseRawData(resource).result - } catch (e2) { - Log('Couldt parse data!') - ShowMessage({ - m: 'Nem sikerült betölteni az adatokat! Ellenőriz a megadott fájlt, vagy az internetelérésed!', - isSimple: true - }) - return - } + Log('Couldt parse data!') + Log(e) + ShowMessage({ + m: 'Nem sikerült betölteni az adatokat! Kattints a manualért', + isSimple: true + }, undefined, ShowHelp) } var r = new QuestionDB() var rt = [] @@ -1268,7 +1222,7 @@ if (r !== undefined) { answers.push(r) } HighLightAnswer(result, j) // highlights the answer for the current result } - ShowAnswers(answers) + ShowAnswers(answers, q.q) } function PrepareAnswers (result, j) { @@ -1294,7 +1248,7 @@ } } - function ShowAnswers (answers) { + function ShowAnswers (answers, question) { assert(answers) if (answers.length > 0) { // if there are more than 0 answer @@ -1304,8 +1258,9 @@ m: 'Nincs találat :( Kattints az üzenetre az összes kérdés/válaszért manuális kereséshez! Előfordulhat, hogy a tárgyat nem válsztottad ki a menüben.', isSimple: true }, undefined, function () { - openInTab(serverAdress + 'lred', { - active: true + OpenErrorPage({ + message: 'No result found', + stack: JSON.stringify(question) }) }) } @@ -1326,10 +1281,7 @@ if (addedQ > 0) { msg = 'Klikk ide a nyers adatokhoz. ' + addedQ + ' új kérdés!' - var useNetDB = getVal('useNetDB') - if (useNetDB !== undefined && useNetDB === 1) { - 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.' } - } else { msg += 'Ne felejtsd el bemásolni a fő txt-be!' } + 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.' } } else { msg = 'A kérdőívben nincsen új kérdés. Ha mégis le akarod menteni klikk ide.' if (!data) { msg += ' Lehet azért, mert nincs kérdés betöltve.' } @@ -1342,13 +1294,10 @@ var towrite = '

' + sentData.subj + '
TXT-ben nem szereplő kérdések: ' + addedQ + '/' + allQ + '


' + output.replace(/\n/g, '
') + '

Összes kérdés/válasz:

' + allOutput.replace( /\n/g, '
') - var useNetDB = getVal('useNetDB') - if (useNetDB !== undefined && useNetDB === 1) { - try { - towrite += '

Elküldött adatok:

' + JSON.stringify(sentData) - } catch (e) { - towrite += '

Elküldött adatok:

' + sentData - } + try { + towrite += '

Elküldött adatok:

' + JSON.stringify(sentData) + } catch (e) { + towrite += '

Elküldött adatok:

' + sentData } document.write(towrite) document.close() @@ -1393,10 +1342,7 @@ function SaveQuiz (quiz, questionData) { try { if (quiz.length === 0) { - throw { // eslint-disable-line - message: 'quiz length is zero!', - stack: 'no stack.' - } + throw new Error('quiz length is zero!') } var output = '' // thefinal output var allOutput = '' // thefinal output with all questions @@ -1428,14 +1374,11 @@ sentData.subj = 'NOSUBJ' Log('unable to get subject name :c') } - var useNetDB = getVal('useNetDB') - if (useNetDB !== undefined && useNetDB === 1) { - sentData.allData = quiz - sentData.data = newQuestions - sentData.version = info().script.version - SendXHRMessage('datatoadd=' + JSON.stringify(sentData)) - sendSuccess = true - } + sentData.allData = quiz + sentData.data = newQuestions + sentData.version = info().script.version + SendXHRMessage('datatoadd=' + JSON.stringify(sentData)) + sendSuccess = true } catch (e) { Exception(e, 'error at sending data to server.') } @@ -1471,9 +1414,6 @@ var img = GetImageFormResult(i) question.i = img - if (q !== undefined) { q = SUtils.ReplaceCharsWithSpace(q, '\n') } - if (a !== undefined) { a = SUtils.ReplaceCharsWithSpace(a, '\n') } - if (question.a !== undefined) { quiz.push(new Question(question.q, question.a, question.i)) // adding current question to quiz } else { @@ -2107,46 +2047,6 @@ CreateNodeWithText(questionTickboxCell, 'Kérdések mutatása válaszhoz', 'span') - // database mode listbox ----------------------------------------------------------------------------------------------------------------------------- - var databasemodeListboxRow = tbl.insertRow() - var databasemodeListboxCell = databasemodeListboxRow.insertCell() - - var databasemodeListbox = document.createElement('select') - databasemodeListbox.type = 'checkbox' - // databasemodeListbox.checked = getVal("showSplash") || false; - databasemodeListbox.style.position = '' - // databasemodeListbox.style.background = "white"; - databasemodeListbox.style.left = 10 + 'px' - databasemodeListbox.style.margin = '5px 5px 5px 5px' // fancy margin - databasemodeListbox.style.top = menuDiv.offsetHeight + 'px' - - var databasemodeListboxText = CreateNodeWithText(questionTickboxCell, - 'Kérdések beszerzése:', 'span') - databasemodeListboxCell.appendChild(databasemodeListboxText) - - databasemodeListboxCell.appendChild(databasemodeListbox) // adding to main div - - databasemodeListbox.addEventListener('change', function (e) { - // sorry for using selectedindex :c - setVal('useNetDB', databasemodeListbox.selectedIndex) - }) - - var uselocal = document.createElement('option') - uselocal.text = 'Helyi fájlból (old school)' - uselocal.value = 2 - databasemodeListbox.add(uselocal, 0) - - var usenetsafe = document.createElement('option') - usenetsafe.text = 'Netről' - usenetsafe.value = 0 - databasemodeListbox.add(usenetsafe, 1) - - var selected = getVal('useNetDB') - if (selected !== undefined) { databasemodeListbox.selectedIndex = selected } - - var databasemodeListboxElement = document.createElement('span') // new paragraph - databasemodeListboxCell.appendChild(databasemodeListboxElement) - // setting up buttons var buttonRow = tbl.insertRow() var buttonCell = buttonRow.insertCell() @@ -2241,6 +2141,28 @@ if (!val) { throw new Error('Assertion failed') } } + function OpenErrorPage (e) { + let path = 'lred' + try { + if (e.message || e.stack) { + path += '?' + } + if (e.message) { + path += 'msg:' + SUtils.SimplifyQuery(e.message) + } + if (e.stack) { + path += '___stack:' + SUtils.SimplifyStack(e.stack) + } + path = SUtils.RemoveSpecialChars(path) + } catch (e) { + Exception(e, 'error at setting error stack/msg link') + } + path = path.replace(/ /g, '_') + openInTab(serverAdress + path, { + active: true + }) + } + // : }}} // : Help {{{