From 38184716f9c7bab915b78932ab90a796f3362ed6 Mon Sep 17 00:00:00 2001 From: mrfry Date: Fri, 24 Sep 2021 16:05:26 +0200 Subject: [PATCH] Added stuff to handle kvk questions / answers --- stable.user.js | 352 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 298 insertions(+), 54 deletions(-) diff --git a/stable.user.js b/stable.user.js index 67ca346..b3d90b0 100755 --- a/stable.user.js +++ b/stable.user.js @@ -110,11 +110,12 @@ // Devel vars // ------------------------------------------------------------------------------ // forcing pages for testing. unless you test, do not set these to true! - const isDevel = false + const isDevel = true setVal('ISDEVEL', isDevel) + const forcedMatchString = isDevel ? 'kvk' : '' // only one of these should be true for testing const forceTestPage = isDevel && false - const forceResultPage = isDevel && false + const forceResultPage = isDevel && true const forceDefaultPage = isDevel && false // ------------------------------------------------------------------------------ @@ -210,6 +211,8 @@ // : HTML parsers {{{ + // : Moodle {{{ + // : Basic processing helpers {{{ function getTextPromisesFromNode(node) { @@ -320,7 +323,7 @@ // : Test page processing functions {{{ - function handleQuiz() { + function handleMoodleQuiz() { const { removeMessage: removeLoadingMessage } = ShowMessage( texts.loadingAnswer ) @@ -361,6 +364,7 @@ log(sentData) + log('Sent data', sentData) post('ask', sentData).then((results) => { removeLoadingMessage() ShowAnswers( @@ -375,7 +379,7 @@ }) .catch((err) => { warn(err) - warn('Error in handleQuiz()') + warn('Error in handleMoodleQuiz()') }) } @@ -463,7 +467,7 @@ resolve(errorsRemoved) }) .catch((err) => { - warn('Error in handleQuiz()') + warn('Error in handleMoodleQuiz()') warn(err) }) }) @@ -831,10 +835,12 @@ hashedImages: images.map((x) => { return x.val }), + source: 'script', } } else { return { type: 'simple', + source: 'script', } } } @@ -1011,6 +1017,125 @@ // : }}} + // : }}} + + // : KVK {{{ + + function getKVKAnswerNodesFromQuiz() { + let i = 1 + let currElem = null + const elems = [] + do { + currElem = document.getElementsByClassName(`kvalasz${i}`)[0] + if (currElem) { + elems.push(currElem) + } + i++ + } while (currElem !== undefined) + return elems + } + + function getKVKQuestionNodeFromQuiz() { + return document.getElementsByClassName('kkerdes')[0] + } + + function getKVKSubjName() { + return document.getElementsByTagName('header')[0].innerText + } + + function HandleKVKResults(url) { + const tableChilds = document.getElementsByTagName('table')[0].childNodes[0] + .childNodes + const question = removeUnnecesarySpaces( + tableChilds[0].innerText.split(':')[1] + ) + const answer = removeUnnecesarySpaces( + tableChilds[1].innerText.split(':')[1] + ) + const correct = removeUnnecesarySpaces( + tableChilds[2].innerText.split(':')[1] + ) + if (correct.toLowerCase() === 'helyes') { + const sentData = { + subj: getKVKSubjName(), + version: info().script.version, + id: getCid(), + location: 'https://moodle.kvk.hu', // TODO: url + quiz: [ + { + Q: question, + A: answer, + data: { + type: 'simple', + date: new Date().getTime(), + source: 'script', + }, + }, + ], + } + + post('isAdding', sentData).then((res) => { + ShowSaveQuizDialog(res.success, sentData, res.totalNewQuestions) + }) + } else { + ShowMessage('Nem eldönthető a helyes válasz') + } + } + + function simplifyKVKQuestionString(val) { + // FIXME: this is ugly + let x = val.split('\n') + x.shift() + x = x.join('\n').split(' ') + x.pop() + return x.join(' ') + } + + function handleKVKQuiz(url) { + // TODO: egy oldalon több kérdés? + // kérdésben 3/20 meg (1879) mit jelent elején végén + // 3/20 A szervezet érintettjeinek hatalom/érdek mátrixában hova tartozik a + // tulajdonosok/részvényesek? (1876) + try { + const { removeMessage: removeLoadingMessage } = ShowMessage( + texts.loadingAnswer + ) + const answerNodes = getKVKAnswerNodesFromQuiz() + const questionNode = getKVKQuestionNodeFromQuiz() + + const sentData = { + questions: [ + { + Q: simplifyKVKQuestionString(questionNode.innerText), + subj: 'asd', + data: { type: 'simple' }, + possibleAnswers: answerNodes.map((node) => { + return node.innerText + }), + }, + ], + testUrl: url, + } + + log('Sent data', sentData) + post('ask', sentData).then((results) => { + removeLoadingMessage() + ShowAnswers( + results.map((res, i) => { + return { + answers: res.answers, + question: sentData.questions[i], + } + }) + ) + }) + } catch (e) { + console.warn(e) + } + } + + // : }}} + // : Misc {{{ function getVideo() { @@ -1192,31 +1317,101 @@ } } + const pageMatchers = [ + { + matchString: 'kvk', + testPage: { + match: (url) => { + return false // TODO :insert real url + }, + action: (url) => { + handleKVKQuiz(url) + }, + }, + resultPage: { + match: (url) => { + return true // TODO :insert real url + }, + action: (url) => { + HandleKVKResults(url) + }, + }, + default: { + match: (url) => { + return false // TODO :insert real url + }, + action: (url) => { + HandleUI(url) + }, + }, + }, + { + matchString: 'default', + testPage: { + match: (url) => { + return ( + (url.includes('/quiz/') && url.includes('attempt.php')) || + forceTestPage + ) + }, + action: () => { + handleMoodleQuiz() + }, + }, + resultPage: { + match: (url) => { + return ( + (url.includes('/quiz/') && url.includes('review.php')) || + forceResultPage + ) + }, + action: (url) => { + HandleMoodleResults(url) + }, + }, + default: { + match: (url) => { + return ( + (!url.includes('/quiz/') && + !url.includes('review.php') && + !url.includes('.pdf')) || + forceDefaultPage + ) + }, + action: (url) => { + HandleUI(url) + }, + }, + }, + ] + function AfterLoad() { const url = currUrl try { - if ( - (url.includes('/quiz/') && url.includes('attempt.php')) || - forceTestPage - ) { - // if the current page is a test - handleQuiz() - } else if ( - (url.includes('/quiz/') && url.includes('review.php')) || - forceResultPage - ) { - // if the current window is a test-s result - HandleResults(url) - } else if ( - (!url.includes('/quiz/') && - !url.includes('review.php') && - !url.includes('.pdf')) || - forceDefaultPage - ) { - // if the current window is any other window than a quiz or pdf. - HandleUI(url) - } + pageMatchers.some((matcher) => { + if ( + url.includes(matcher.matchString) || + matcher.matchString === 'default' || + matcher.matchString === forcedMatchString + ) { + if (matcher.testPage && matcher.testPage.match(url)) { + matcher.testPage.action(url) + return true + } else if (matcher.resultPage && matcher.resultPage.match(url)) { + matcher.resultPage.action(url) + return true + } else if (matcher.default && matcher.default.match(url)) { + matcher.default.action(url) + return true + } else { + console.warn( + 'Matcher did not have matched handler implemented, or there was no match!', + matcher + ) + } + } + }) } catch (e) { ShowMessage( texts.fatalError, @@ -1512,6 +1707,10 @@ } function addImageIdsToImageNodes(imgs) { + if (!imgs || !Array.isArray(imgs.images)) { + return + } + imgs.images.forEach((img, i) => { const text = document.createElement('div') text.innerText = `[${i}]` @@ -1526,33 +1725,78 @@ }) } + // results = Array<{ + // answers: Array<{ + // detailedMatch: { + // qMatch: Number, + // aMatch: Number, + // dMatch: Number, + // matchedSubjName: String, + // avg: Number + // }, + // match: Number, + // q: { + // Q: String, + // A: String, + // cache: { + // Q: Array, + // A: Array, + // }, + // data: { + // type: String, + // date: Number + // images?: Array + // } + // } + // }>, + // question: { + // question: String, + // success: Boolean, + // images: Array<{ + // val: String, + // node: HtmlNode + // }>, + // data: { + // type: String, + // date: Number + // hashedImages?: Array, + // images?: Array + // }, + // possibleAnswers: Array + // } + // }> function ShowAnswers(results) { log(results) - const answers = results.reduce((acc, res) => { - const prepared = PrepareAnswers(res) - addImageIdsToImageNodes(res.question) - if (prepared) { - acc.push(prepared) - } - return acc - }, []) - - if (answers.length > 0) { - ShowMessage(answers) - } else { - ShowMessage( - texts.noResult, - - undefined, - function () { - OpenErrorPage({ - message: 'No result found', - question: Array.isArray(answers[0]) - ? answers[0][0].replace(/"/g, '').replace(/:/g, '') - : answers[0], - }) + try { + const answers = results.reduce((acc, res) => { + const prepared = PrepareAnswers(res) + addImageIdsToImageNodes(res.question) + if (prepared) { + acc.push(prepared) } - ) + return acc + }, []) + + if (answers.length > 0) { + ShowMessage(answers) + } else { + ShowMessage( + texts.noResult, + + undefined, + function () { + OpenErrorPage({ + message: 'No result found', + question: Array.isArray(answers[0]) + ? answers[0][0].replace(/"/g, '').replace(/:/g, '') + : answers[0], + }) + } + ) + } + } catch (e) { + console.warn('Error showing answers') + console.warn(e) } } @@ -1560,9 +1804,9 @@ // : Quiz saving {{{ - function HandleResults() { + function HandleMoodleResults() { getQuiz().then((res) => { - SaveQuiz(res, ShowSaveQuizDialog) // saves the quiz questions and answers + SaveQuiz(res) // saves the quiz questions and answers }) } @@ -1598,7 +1842,7 @@ } // saves the current quiz. questionData contains the active subjects questions - function SaveQuiz(quiz, next) { + function SaveQuiz(quiz) { try { let sentData = {} if (quiz.length === 0) { @@ -1620,7 +1864,7 @@ } log('SENT DATA', sentData) post('isAdding', sentData).then((res) => { - next(res.success, sentData, res.totalNewQuestions) + ShowSaveQuizDialog(res.success, sentData, res.totalNewQuestions) }) } catch (e) { Exception(e, 'error at sending data to server.')