merged kgk

This commit is contained in:
mrfry 2021-12-12 13:24:42 +01:00
commit ef647006f4

View file

@ -46,7 +46,7 @@
// : Script header {{{ // : Script header {{{
// ==UserScript== // ==UserScript==
// @name Moodle/Elearning/KMOOC test help // @name Moodle/Elearning/KMOOC test help
// @version 2.1.2.2 // @version 2.1.3.0
// @description Online Moodle/Elearning/KMOOC test help // @description Online Moodle/Elearning/KMOOC test help
// @author MrFry // @author MrFry
// @match https://elearning.uni-obuda.hu/* // @match https://elearning.uni-obuda.hu/*
@ -58,6 +58,8 @@
// @match https://moodle.pte.hu/* // @match https://moodle.pte.hu/*
// @match https://szelearning.sze.hu/* // @match https://szelearning.sze.hu/*
// @match https://moodle.kre.hu/* // @match https://moodle.kre.hu/*
// @match https://moodle.pte.hu/*
// @match https://portal.kgk.uni-obuda.hu/
// @noframes // @noframes
// @match https://qmining.frylabs.net/* // @match https://qmining.frylabs.net/*
// @run-at document-start // @run-at document-start
@ -115,6 +117,7 @@
// forcing pages for testing. unless you test, do not set these to true! // forcing pages for testing. unless you test, do not set these to true!
const isDevel = false const isDevel = false
setVal('ISDEVEL', isDevel) setVal('ISDEVEL', isDevel)
const forcedMatchString = isDevel ? '' : ''
// only one of these should be true for testing // only one of these should be true for testing
const forceTestPage = isDevel && false const forceTestPage = isDevel && false
const forceResultPage = isDevel && false const forceResultPage = isDevel && false
@ -128,12 +131,11 @@
var addEventListener // add event listener function var addEventListener // add event listener function
let serverAdress = 'https://qmining.frylabs.net/' let serverAdress = 'https://qmining.frylabs.net/'
let apiAdress = 'https://api.frylabs.net/' let apiAdress = 'https://api.frylabs.net/'
// const ircAddress = 'https://kiwiirc.com/nextclient/irc.sub.fm/#qmining'
const motdShowCount = 3 /* Ammount of times to show motd */ const motdShowCount = 3 /* Ammount of times to show motd */
const messageOpacityDelta = 0.1 const messageOpacityDelta = 0.1
const minMessageOpacity = 0.2 const minMessageOpacity = 0.2
let infoExpireTime = 60 // Every n seconds basic info should be loaded from server let infoExpireTime = 60 * 5 // Every n seconds basic info should be loaded from server
var motd = '' var motd = ''
var userSpecificMotd = undefined var userSpecificMotd = undefined
var lastestVersion = '' var lastestVersion = ''
@ -213,6 +215,8 @@
// : HTML parsers {{{ // : HTML parsers {{{
// : Moodle {{{
// : Basic processing helpers {{{ // : Basic processing helpers {{{
function getTextPromisesFromNode(node) { function getTextPromisesFromNode(node) {
@ -323,7 +327,7 @@
// : Test page processing functions {{{ // : Test page processing functions {{{
function handleQuiz() { function handleMoodleQuiz() {
const { removeMessage: removeLoadingMessage } = ShowMessage( const { removeMessage: removeLoadingMessage } = ShowMessage(
texts.loadingAnswer texts.loadingAnswer
) )
@ -364,6 +368,7 @@
log(sentData) log(sentData)
log('Sent data', sentData)
post('ask', sentData).then((results) => { post('ask', sentData).then((results) => {
removeLoadingMessage() removeLoadingMessage()
ShowAnswers( ShowAnswers(
@ -378,7 +383,7 @@
}) })
.catch((err) => { .catch((err) => {
warn(err) warn(err)
warn('Error in handleQuiz()') warn('Error in handleMoodleQuiz()')
}) })
} }
@ -466,7 +471,7 @@
resolve(errorsRemoved) resolve(errorsRemoved)
}) })
.catch((err) => { .catch((err) => {
warn('Error in handleQuiz()') warn('Error in handleMoodleQuiz()')
warn(err) warn(err)
}) })
}) })
@ -834,10 +839,12 @@
hashedImages: images.map((x) => { hashedImages: images.map((x) => {
return x.val return x.val
}), }),
source: 'script',
} }
} else { } else {
return { return {
type: 'simple', type: 'simple',
source: 'script',
} }
} }
} }
@ -1014,6 +1021,121 @@
// : }}} // : }}}
// : }}}
// : KGK {{{
function getKGKAnswerNodesFromQuiz() {
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 getKGKQuestionNodeFromQuiz() {
return document.getElementsByClassName('kkerdes')[0]
}
function getKGKSubjName() {
return document.getElementsByTagName('header')[0].innerText
}
function HandleKGKResults(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: getKGKSubjName(),
version: info().script.version,
id: getCid(),
location: 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 simplifyKGKQuestionString(val) {
// FIXME: this is ugly
let x = val.split('\n')
x.shift()
x = x.join('\n').split(' ')
x.pop()
return x.join(' ')
}
function handleKGKQuiz(url) {
try {
const { removeMessage: removeLoadingMessage } = ShowMessage(
texts.loadingAnswer
)
const answerNodes = getKGKAnswerNodesFromQuiz()
const questionNode = getKGKQuestionNodeFromQuiz()
const sentData = {
questions: [
{
Q: simplifyKGKQuestionString(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 {{{ // : Misc {{{
function getVideo() { function getVideo() {
@ -1195,31 +1317,101 @@
} }
} }
const pageMatchers = [
{
matchString: 'portal.kgk',
testPage: {
match: (url) => {
return url.includes('vizsga')
},
action: (url) => {
handleKGKQuiz(url)
},
},
resultPage: {
match: (url) => {
return false // TODO :insert real url
},
action: (url) => {
HandleKGKResults(url)
},
},
default: {
match: (url) => {
return true // TODO :insert real url
},
action: (url) => {
HandleUI(url)
},
},
},
{
matchString: 'default', // moodle, elearning, mooc
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() { function AfterLoad() {
const url = currUrl const url = currUrl
try { try {
if ( pageMatchers.some((matcher) => {
(url.includes('/quiz/') && url.includes('attempt.php')) || if (
forceTestPage url.includes(matcher.matchString) ||
) { matcher.matchString === 'default' ||
// if the current page is a test matcher.matchString === forcedMatchString
handleQuiz() ) {
} else if ( if (matcher.testPage && matcher.testPage.match(url)) {
(url.includes('/quiz/') && url.includes('review.php')) || matcher.testPage.action(url)
forceResultPage return true
) { } else if (matcher.resultPage && matcher.resultPage.match(url)) {
// if the current window is a test-s result matcher.resultPage.action(url)
HandleResults(url) return true
} else if ( } else if (matcher.default && matcher.default.match(url)) {
(!url.includes('/quiz/') && matcher.default.action(url)
!url.includes('review.php') && return true
!url.includes('.pdf')) || } else {
forceDefaultPage console.warn(
) { 'Matcher did not have matched handler implemented, or there was no match!',
// if the current window is any other window than a quiz or pdf. matcher
HandleUI(url) )
} }
}
})
} catch (e) { } catch (e) {
ShowMessage( ShowMessage(
texts.fatalError, texts.fatalError,
@ -1515,6 +1707,10 @@
} }
function addImageIdsToImageNodes(imgs) { function addImageIdsToImageNodes(imgs) {
if (!imgs || !Array.isArray(imgs.images)) {
return
}
imgs.images.forEach((img, i) => { imgs.images.forEach((img, i) => {
const text = document.createElement('div') const text = document.createElement('div')
text.innerText = `[${i}]` text.innerText = `[${i}]`
@ -1529,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<String>,
// A: Array<String>,
// },
// data: {
// type: String,
// date: Number
// images?: Array<String>
// }
// }
// }>,
// question: {
// question: String,
// success: Boolean,
// images: Array<{
// val: String,
// node: HtmlNode
// }>,
// data: {
// type: String,
// date: Number
// hashedImages?: Array<String>,
// images?: Array<String>
// },
// possibleAnswers: Array<String>
// }
// }>
function ShowAnswers(results) { function ShowAnswers(results) {
log(results) log(results)
const answers = results.reduce((acc, res) => { try {
const prepared = PrepareAnswers(res) const answers = results.reduce((acc, res) => {
addImageIdsToImageNodes(res.question) const prepared = PrepareAnswers(res)
if (prepared) { addImageIdsToImageNodes(res.question)
acc.push(prepared) 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],
})
} }
) 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)
} }
} }
@ -1563,9 +1804,9 @@
// : Quiz saving {{{ // : Quiz saving {{{
function HandleResults() { function HandleMoodleResults() {
getQuiz().then((res) => { getQuiz().then((res) => {
SaveQuiz(res, ShowSaveQuizDialog) // saves the quiz questions and answers SaveQuiz(res) // saves the quiz questions and answers
}) })
} }
@ -1601,7 +1842,7 @@
} }
// saves the current quiz. questionData contains the active subjects questions // saves the current quiz. questionData contains the active subjects questions
function SaveQuiz(quiz, next) { function SaveQuiz(quiz) {
try { try {
let sentData = {} let sentData = {}
if (quiz.length === 0) { if (quiz.length === 0) {
@ -1623,7 +1864,7 @@
} }
log('SENT DATA', sentData) log('SENT DATA', sentData)
post('isAdding', sentData).then((res) => { post('isAdding', sentData).then((res) => {
next(res.success, sentData, res.totalNewQuestions) ShowSaveQuizDialog(res.success, sentData, res.totalNewQuestions)
}) })
} catch (e) { } catch (e) {
Exception(e, 'error at sending data to server.') Exception(e, 'error at sending data to server.')