mirror of
https://gitlab.com/MrFry/moodle-test-userscript
synced 2025-04-01 20:22:48 +02:00
merged kgk
This commit is contained in:
commit
ef647006f4
1 changed files with 296 additions and 55 deletions
291
stable.user.js
291
stable.user.js
|
@ -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 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function AfterLoad() {
|
const pageMatchers = [
|
||||||
const url = currUrl
|
{
|
||||||
|
matchString: 'portal.kgk',
|
||||||
try {
|
testPage: {
|
||||||
if (
|
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')) ||
|
(url.includes('/quiz/') && url.includes('attempt.php')) ||
|
||||||
forceTestPage
|
forceTestPage
|
||||||
) {
|
)
|
||||||
// if the current page is a test
|
},
|
||||||
handleQuiz()
|
action: () => {
|
||||||
} else if (
|
handleMoodleQuiz()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
resultPage: {
|
||||||
|
match: (url) => {
|
||||||
|
return (
|
||||||
(url.includes('/quiz/') && url.includes('review.php')) ||
|
(url.includes('/quiz/') && url.includes('review.php')) ||
|
||||||
forceResultPage
|
forceResultPage
|
||||||
) {
|
)
|
||||||
// if the current window is a test-s result
|
},
|
||||||
HandleResults(url)
|
action: (url) => {
|
||||||
} else if (
|
HandleMoodleResults(url)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: {
|
||||||
|
match: (url) => {
|
||||||
|
return (
|
||||||
(!url.includes('/quiz/') &&
|
(!url.includes('/quiz/') &&
|
||||||
!url.includes('review.php') &&
|
!url.includes('review.php') &&
|
||||||
!url.includes('.pdf')) ||
|
!url.includes('.pdf')) ||
|
||||||
forceDefaultPage
|
forceDefaultPage
|
||||||
) {
|
)
|
||||||
// if the current window is any other window than a quiz or pdf.
|
},
|
||||||
|
action: (url) => {
|
||||||
HandleUI(url)
|
HandleUI(url)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
function AfterLoad() {
|
||||||
|
const url = currUrl
|
||||||
|
|
||||||
|
try {
|
||||||
|
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) {
|
} 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,8 +1725,49 @@
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
try {
|
||||||
const answers = results.reduce((acc, res) => {
|
const answers = results.reduce((acc, res) => {
|
||||||
const prepared = PrepareAnswers(res)
|
const prepared = PrepareAnswers(res)
|
||||||
addImageIdsToImageNodes(res.question)
|
addImageIdsToImageNodes(res.question)
|
||||||
|
@ -1557,15 +1794,19 @@
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('Error showing answers')
|
||||||
|
console.warn(e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// : }}}
|
// : }}}
|
||||||
|
|
||||||
// : 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.')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue