diff --git a/stable.user.js b/stable.user.js index 1168b00..3352d58 100755 --- a/stable.user.js +++ b/stable.user.js @@ -21,7 +21,7 @@ // ==UserScript== // @name Moodle/Elearning/KMOOC test help -// @version 2.0.0.10 +// @version 2.0.1.8 // @description Online Moodle/Elearning/KMOOC test help // @author MrFry // @match https://elearning.uni-obuda.hu/main/* @@ -30,6 +30,7 @@ // @match https://qmining.frylabs.net/* // @noframes // @match http://qmining.frylabs.net/* +// @noframes // @grant GM_getResourceText // @grant GM_info // @grant GM_getValue @@ -60,10 +61,8 @@ /* eslint-enable */ var addEventListener // add event listener function - const serverAdress = 'https://qmining.frylabs.net/' - // const serverAdress = 'http://localhost:8080/' - const apiAdress = 'https://api.frylabs.net/' - // const apiAdress = 'http://localhost:8080/' + let serverAdress = 'https://qmining.frylabs.net/' + let apiAdress = 'https://api.frylabs.net/' const ircAddress = 'https://kiwiirc.com/nextclient/irc.sub.fm/#qmining' // forcing pages for testing. unless you test, do not set these to true! @@ -75,13 +74,19 @@ const log = true const motdShowCount = 3 /* Ammount of times to show motd */ - const infoExpireTime = 60 // Every n seconds basic info should be loaded from server + let infoExpireTime = 60 // Every n seconds basic info should be loaded from server var motd = '' var lastestVersion = '' var subjInfo + if (getVal('ISDEVEL')) { + infoExpireTime = 1 + serverAdress = 'http://localhost:8080/' + apiAdress = 'http://localhost:80/' + } + const huTexts = { - lastChangeLog: '- "Húzza a megfelelő helyre ..." kérdés lekezelése\n- Kód refactor\n- Ha valami elszállt: feedback pls', + lastChangeLog: '', fatalError: 'Fatál error. Check console (f12). Kattints az üzenetre az összes kérdés/válaszért manuális kereséshez!', consoleErrorInfo: 'Itteni hibák 100% a moodle hiba. Kivéve, ha oda van írva hogy script error ;) Ha ilyesmi szerepel itt, akkor olvasd el a segítség szekciót!', freshStartWarning: '

Moodle teszt userscript:

1.5.0 verzió: a script mostantól XMLHTTP kéréseket küld szerver fele! Erre a userscript futtató kiegészítő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.
', @@ -93,17 +98,20 @@ close: 'Bezárás', help: 'Help', websiteBugreport: 'Weboldal / Bug report', + contribute: 'Contribute', donate: 'Donate', - passiveTooltip: 'Ha erre kattintasz akkor a script átálítja a neptunban a hallgatói státuszod passzívra', retry: 'Újrapróbálás', ircButton: 'IRC', + invalidPW: 'Hibás jelszó: ', search: 'Keresés ...', loading: 'Betöltés ...', + login: 'Belépés', + requestPWInsteadOfLogin: 'Jelszó igénylés', + contributeTitle: 'Hozzájárulás a script és weboldal fejleszétéshez', + newPWTitle: 'Új jelszó új felhasználónak', + pwRequest: 'Új jelszó', noServer: 'Nem elérhető a szerver!', - passiveModeActivated: 'Passzív mód bekapcsolva, nem lesz mostantól a szerver piszkálva', - passiveModeDeactivated: 'Passzív mód kikapcsolva, frissíts az érvénybe lépéshez!', - passiveMode: 'Passzív mód', - passiveModeMenuBoxText: 'Passzív mód aktív', + noUser: 'Nem vagy bejelentkezve!', noServerConsoleMessage: `Nem elérhető a szerver, vagy kis eséllyel kezeletlen hiba történt! Ha elérhető a weboldal, akkor ott meg bírod nézni a kérdéseket itt: ${serverAdress}legacy` } @@ -717,7 +725,19 @@ // : Loading {{{ function HandleQminingSite (url) { try { - Array.from(document.getElementById('sideBarLinks').childNodes).forEach((link) => { + const idInput = document.getElementById('cid') + if (idInput) { + idInput.value = getVal('clientId') + } + } catch (e) { + console.info('Error filling client ID input', e) + } + try { + const sideLinks = document.getElementById('sideBarLinks') + if (!sideLinks) { + return + } + Array.from(sideLinks.childNodes).forEach((link) => { link.addEventListener('mousedown', () => { FillFeedbackCID(url, link) }) @@ -783,18 +803,53 @@ } VersionActions() if (!url.includes('.pdf')) { ShowMenu() } - if (!getVal('skipLoad')) { - ConnectToServer(AfterLoad) - } + ConnectToServer(AfterLoad) + } + + function Auth (pw) { + SendXHRMessage('login', { pw: pw, script: true }) + .then((res) => { + if (res.result === 'success') { + ConnectToServer(AfterLoad) + ClearAllMessages() + resetMenu() + } else { + SafeGetElementById('infoMainDiv', (elem) => { + elem.innerText = texts.invalidPW + pw + }) + } + }) + } + + function resetMenu () { + SafeGetElementById('menuButtonDiv', (elem) => { + elem.style.backgroundColor = '#262626' + }) + SafeGetElementById('ircButton', (elem) => { + elem.style.display = 'none' + }) + SafeGetElementById('retryButton', (elem) => { + elem.style.display = 'none' + }) + SafeGetElementById('loginDiv', (elem) => { + elem.style.display = 'none' + }) + SafeGetElementById('infoMainDiv', (elem) => { + elem.innerText = texts.loading + }) } function ConnectToServer (cwith) { ClearAllMessages() GetXHRInfos().then((inf) => { + if (inf.result === 'nouser') { + NoUserAction() + return + } lastestVersion = inf.version motd = inf.motd subjInfo = inf.subjinfo - document.getElementById('infoMainDiv').innerText = `${subjInfo.subjects} tárgy, ${subjInfo.questions} kérdés` + document.getElementById('infoMainDiv').innerText = `${subjInfo.subjects} tárgy, ${subjInfo.questions} kérdés. Felh #${inf.uid}` // FIXME: if cwith() throws an unhandled error it sais server is not avaible cwith() }).catch(() => { @@ -802,6 +857,21 @@ }) } + function NoUserAction () { + SafeGetElementById('menuButtonDiv', (elem) => { + elem.style.backgroundColor = '#44cc00' + }) + SafeGetElementById('infoMainDiv', (elem) => { + elem.innerText = texts.noUser + if (getVal('clientId')) { + elem.innerText += ` (${getVal('clientId')})` + } + }) + SafeGetElementById('loginDiv', (elem) => { + elem.style.display = '' + }) + } + function NoServerAction () { SafeGetElementById('menuButtonDiv', (elem) => { elem.style.backgroundColor = 'red' @@ -1079,7 +1149,7 @@ sentData.id = GetId() sentData.quiz = quiz console.log('SENT DATA', sentData) - SendXHRMessage(JSON.stringify(sentData)).then((res) => { + SendXHRMessage('isAdding', sentData).then((res) => { next(res.success, sentData, res.newQuestions) }) } catch (e) { @@ -1485,9 +1555,9 @@ var menuButtonDiv = document.createElement('div') menuButtonDiv.setAttribute('id', 'menuButtonDiv') SetStyle(menuButtonDiv, { - // width: buttonWidth + 'px', + width: '600px', // height: buttonHeight + 'px', - top: (window.innerHeight - 90) + 'px', + top: (window.innerHeight - 120) + 'px', left: '10px', zIndex: 999999, position: 'fixed', @@ -1525,11 +1595,37 @@ // site link ---------------------------------------------------------------------------------------------------------------- + let contributeLink = CreateNodeWithText(buttonCell, texts.contribute, 'button') + contributeLink.title = texts.contributeTitle + SetStyle(contributeLink, buttonStyle) + + contributeLink.addEventListener('click', function () { + openInTab(serverAdress + 'contribute?scriptMenu', { + active: true + }) + }) + + // pw request ---------------------------------------------------------------------------------------------------------------- + + let pwRequest = CreateNodeWithText(buttonCell, texts.pwRequest, 'button') + pwRequest.title = texts.newPWTitle + SetStyle(pwRequest, buttonStyle) + + pwRequest.addEventListener('click', function () { + openInTab(serverAdress + 'pwRequest', { + active: true + }) + }) + + // site link ---------------------------------------------------------------------------------------------------------------- + let siteLink = CreateNodeWithText(buttonCell, texts.websiteBugreport, 'button') SetStyle(siteLink, buttonStyle) siteLink.addEventListener('click', function () { - location.href = serverAdress + 'menuClick' // eslint-disable-line + openInTab(serverAdress + 'menuClick', { + active: true + }) }) // donate link ---------------------------------------------------------------------------------------------------------------- @@ -1566,6 +1662,47 @@ margin: '5px' }) + // login div ---------------------------------------------------------------------------------------------------------------- + const loginDiv = document.createElement('div') + loginDiv.style.display = 'none' + loginDiv.setAttribute('id', 'loginDiv') + const loginButton = document.createElement('button') + loginButton.innerText = texts.login + const loginInput = document.createElement('input') + loginInput.type = 'text' + loginInput.style.width = '400px' + loginInput.style.textAlign = 'center' + const clientId = getVal('clientId') + if (clientId && clientId.toString()[0] !== '0') { + loginInput.value = clientId || '' + loginButton.innerText = texts.requestPWInsteadOfLogin + } + loginDiv.appendChild(loginInput) + loginDiv.appendChild(loginButton) + + SetStyle(loginButton, buttonStyle) + + loginInput.addEventListener('keyup', (e) => { + console.log(e.target.value) + if (e.target.value === clientId) { + loginButton.innerText = texts.requestPWInsteadOfLogin + } else if (e.target.value !== '') { + loginButton.innerText = texts.login + } + }) + + loginButton.addEventListener('click', function () { + if (loginInput.value === clientId.toString()) { + openInTab(serverAdress + 'getVeteranPw?cid=' + clientId, { + active: true + }) + } else { + Auth(loginInput.value) + } + }) + + ibuttonCell.appendChild(loginDiv) + // irc button ---------------------------------------------------------------------------------------------------------------- let ircButton = CreateNodeWithText(ibuttonCell, texts.ircButton, 'button') SetStyle(ircButton, buttonStyle) @@ -1597,39 +1734,7 @@ menuButtonDiv.style.top = (window.innerHeight - 70) + 'px' }) - // passive button ---------------------------------------------------------------------------------------------------------------- - let passiveButton = CreateNodeWithText(buttonCell, texts.passiveMode, 'button') - passiveButton.title = texts.passiveTooltip - SetStyle(passiveButton, buttonStyle) - - let setPassiveButtonState = (isPassive) => { - menuButtonDiv.style.background = '#262626' - retryButton.style.display = 'none' - ircButton.style.display = 'none' - if (!isPassive) { - infoDiv.innerText = texts.loading - } else { - infoDiv.innerText = texts.passiveModeMenuBoxText - } - } - setPassiveButtonState(getVal('skipLoad')) - - passiveButton.addEventListener('click', function () { - ClearAllMessages() - let sl = !getVal('skipLoad') - setVal('skipLoad', sl) - setPassiveButtonState(sl, true) - - if (sl) { - ShowMessage({ - m: texts.passiveModeActivated, - isSimple: true - }, 6) - } else { - ConnectToServer(AfterLoad) - } - }) - + // APPEND EVERYTHING appedtTo.appendChild(menuButtonDiv) } catch (e) { Exception(e, 'script error at showing menu:') @@ -1645,8 +1750,11 @@ return currId } else { currId = new Date() - currId = currId.getTime() + Math.floor(Math.random() * 10000000) - setVal('clientId', currId.toString()) + currId = currId.getTime() + Math.floor(Math.random() * 1000000000000) + currId = currId.toString().split('') + currId.shift() + currId = '0' + currId.join('') + setVal('clientId', currId) return currId } } @@ -1681,7 +1789,12 @@ setVal('lastInfoCheckTime', now) } - if (now > lastCheck + (infoExpireTime * 1000)) { + let lastInfo = { result: 'noLastInfo' } + try { + lastInfo = JSON.parse(getVal('lastInfo')) + } catch (e) { + } + if (lastInfo.result !== 'success' || now > lastCheck + (infoExpireTime * 1000)) { return new Promise((resolve, reject) => { const url = apiAdress + 'infos?version=true&motd=true&subjinfo=true&cversion=' + @@ -1691,6 +1804,11 @@ xmlhttpRequest({ method: 'GET', url: url, + crossDomain: true, + xhrFields: { withCredentials: true }, + headers: { + 'Content-Type': 'application/json' + }, onload: function (response) { try { setVal('lastInfoCheckTime', now) @@ -1712,7 +1830,7 @@ } else { return new Promise((resolve, reject) => { try { - resolve(JSON.parse(getVal('lastInfo'))) + resolve(lastInfo) } catch (e) { Log('Errro paring JSON in GetXHRInfos, when using old data!') Log(e) @@ -1770,13 +1888,18 @@ }) } - function SendXHRMessage (message) { - message = SUtils.RemoveSpecialChars(message) - var url = apiAdress + 'isAdding' + function SendXHRMessage (path, message) { + // message = SUtils.RemoveSpecialChars(message) // TODO: check this + if (typeof message === 'object') { + message = JSON.stringify(message) + } + const url = apiAdress + path return new Promise((resolve, reject) => { xmlhttpRequest({ method: 'POST', url: url, + crossDomain: true, + xhrFields: { withCredentials: true }, data: message, headers: { 'Content-Type': 'application/json' @@ -1790,7 +1913,7 @@ const res = JSON.parse(resp.responseText) resolve(res) } catch (e) { - Log('Errro paring JSON in SendXHRMessage') + Log('Error paring JSON in SendXHRMessage') Log(e) reject(e) }