Updating stable userscript

This commit is contained in:
MrFry 2019-10-07 15:41:34 +02:00
parent 68d9673629
commit 304e2d6651

396
stable.js
View file

@ -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:///<file path space is %20, and use "/"-s plz not "\" ty (and add .txt)// UTF-8 PLZ>
// @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(
'<h1>Moodle teszt userscript:<h1><h3>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!</h3> <h3>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!!!</h3><h5>Ez az ablak frissités után eltűnik. Ha nem, akkor a visza gombbal próbálkozz.</h5>'
)
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 = '<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>')
var useNetDB = getVal('useNetDB')
if (useNetDB !== undefined && useNetDB === 1) {
try {
towrite += '</p>Elküldött adatok:</p> ' + JSON.stringify(sentData)
} catch (e) {
towrite += '</p>Elküldött adatok:</p> ' + sentData
}
try {
towrite += '</p>Elküldött adatok:</p> ' + JSON.stringify(sentData)
} catch (e) {
towrite += '</p>Elküldött adatok:</p> ' + 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 {{{