diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..963f3d3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +stable.user.js diff --git a/README.md b/README.md index d1d1548..6f0ae30 100755 --- a/README.md +++ b/README.md @@ -1,24 +1,17 @@ -# Moodle/KMOOC teszt megoldó userscript +## Install -## Telepítés -1. [Greasyfork leírása userscript futtató addon telepítésére](https://greasyfork.org/en/help/installing-user-scripts) -2. [Telepítés hivatalos weboldalról](http://qmining.frylabs.net/install) +1. Greasyfork-s guide on installing userscripts: https://greasyfork.org/en/help/installing-user-scripts +2. Run `./make.sh` with a `DOMAIN` env variable set (`DOMAIN=some.domain`) to replace urls inside the + script +3. Open stable.user.js in a browser. The browser addon should recognize it, and ask if you want to + install it -Első használatkor és frissítéseknél engedélyezni kell a webszerver elérését, de erre külön figyelmeztet. Ezután már használható is. +## Server +The server for this userscript is available here: https://gitlab.com/MrFry/mrfrys-node-server -# Működés +If used as a git submodule in the server repo, then the `make.sh` script will use the domain +specified in a file there -A userscript a teszt oldal DOM-jében megkeresi a kérdést/kérdéseket, és a hozzá tartozó egyéb adatokat (pl.: kép), és azokat a webszervernek elküldi. A szerver válaszában szerepel az összes lehetséges helyes válasz, és hogy az mekkora százalékkal a tényleges helyes válasz. - -Teszt eredmény oldalon végigjárja a kérdéseket, és a helyes megoldást szintén elküldi a szervernek, ami eldönti hogy ilyen kérdés van-e már, és ha nincs akkor hozzáadja az adatbázishoz. - -![alt text](http://qmining.frylabs.net/img/screens/2.png) - -# Egyéb -[Szerver repository](https://gitlab.com/MrFry/question-node-server) - -Jelenleg sok optimalizálatlan rész található benne, cél ezek kijavítása, szépítése - -# Licensz: +## License: GPLv3 diff --git a/make.sh b/make.sh new file mode 100755 index 0000000..5e2c1df --- /dev/null +++ b/make.sh @@ -0,0 +1,30 @@ +#!/bin/bash +scriptPath=$(dirname -- "${0}") +domainPath="${scriptPath}/../../data/domain" +userscriptPath="./user.js" +resultUserscriptPath="./stable.user.js" + +domain="${DOMAIN}" + +if [ -f "${domainPath}" ]; then + domain=$(cat "${domainPath}") +fi + +if [ -z "${domain}" ]; then + echo -e "\033[0;41m${domainPath} does not exist, and DOMAIN is not set!\033[0m" + exit 1 +fi + +if [ ! -f "${userscriptPath}" ]; then + echo -e "\033[0;41m${userscriptPath} does not exist!\033[0m" + exit 1 +fi + +userscript=$(cat "${userscriptPath}") + +toReplace="[DOMAIN]" +result="${userscript//"$toReplace"/"$domain"}" + +echo "$result" > "${resultUserscriptPath}" + +echo "Exported with domain: '${domain}' to '${resultUserscriptPath}'" diff --git a/stable.user.js b/user.js similarity index 95% rename from stable.user.js rename to user.js index 763e585..01022b5 100755 --- a/stable.user.js +++ b/user.js @@ -71,8 +71,8 @@ // @match https://moodle.uni-corvinus.hu/* // @match https://v39.moodle.uniduna.hu/* // @match https://mentok.net/* -// @match https://qmining.frylabs.net/* -// @match https://frylabs.net/* +// @match https://qmining.[DOMAIN]/* +// @match https://[DOMAIN]/* // @noframes // @run-at document-start // @grant GM_getResourceText @@ -84,16 +84,16 @@ // @grant GM_openInTab // @grant unsafeWindow // @license GNU General Public License v3.0 or later -// @supportURL frylabs.net -// @contributionURL frylabs.net -// @namespace https://frylabs.net -// @updateURL https://frylabs.net/moodle-test-userscript/stable.user.js?up +// @supportURL [DOMAIN] +// @contributionURL [DOMAIN] +// @namespace https://[DOMAIN] +// @updateURL https://[DOMAIN]/moodle-test-userscript/stable.user.js?up // ==/UserScript== // : }}} ;(function () { // CONFIG - let originalServer = { host: 'frylabs.net', port: 443 } + let originalServer = { host: '[DOMAIN]', port: 443 } const logElementGetting = false const logEnabled = true const motdShowCount = 5 // Ammount of times to show motd @@ -135,7 +135,7 @@ // Devel vars // ------------------------------------------------------------------------------ // forcing pages for testing. unless you test, do not set these to true! - const isDevel = false + const isDevel = true const forcedMatchString = isDevel ? 'default' : null // only one of these should be true for testing const forceTestPage = isDevel && false @@ -153,6 +153,7 @@ var updatableElements = [] // { elem: ..., target: ... } var elementUpdaterInterval = -1 const overlayElemUpdateInterval = 2 // seconds + var skipAvailablePeerFind = false if (isDevel) { warn('Moodle script running in developement mode!') @@ -1746,6 +1747,9 @@ function ConnectToServer() { clearAllMessages() + SafeGetElementById('peerSelector', (elem) => { + elem.style.display = 'none' + }) GetXHRInfos() .then((inf) => { try { @@ -1762,14 +1766,15 @@ setVal('userId', inf.uid) overlay.querySelector( '#infoMainDiv' - ).innerText = `${subjInfo.subjects.toLocaleString()} tárgy, ${subjInfo.questions.toLocaleString()} kérdés. UID: #${getUid()}\n${getShortServerURL( - serverAdress - )}` + ).innerText = `${subjInfo.subjects.toLocaleString()} tárgy, ${subjInfo.questions.toLocaleString()} kérdés. UID: #${getUid()}` if (inf.unreads.length > 0) { overlay.querySelector('#mailButton').innerText = '📬' } getPeers().catch(() => warn('unable to get p2p info')) + SafeGetElementById('peerSelector', (elem) => { + elem.style.display = '' + }) AfterLoad() } catch (e) { warn(texts.unhandledErrorConsoleMessage) @@ -1779,15 +1784,27 @@ .catch((e) => { warn(texts.noServerConsoleMessage) warn(e) - tryAnotherPeer() + SafeGetElementById('infoMainDiv', (elem) => { + elem.innerText = texts.noServer + }) + + if (skipAvailablePeerFind || !getVal('lastp2pinfo')) { + SafeGetElementById('retryContainer', (elem) => { + elem.style.display = 'flex' + }) + SafeGetElementById('peerSelector', (elem) => { + elem.style.display = '' + }) + SafeGetElementById('scriptMenuDiv', (elem) => { + elem.style.backgroundColor = 'red' + }) + } else { + tryAnotherPeer() + } }) } async function tryAnotherPeer() { - SafeGetElementById('scriptMenuDiv', (elem) => { - elem.style.backgroundColor = 'red' - }) - debugLog('Unable to connect to main server, trying peers') try { const lastp2pinfo = JSON.parse(getVal('lastp2pinfo')) @@ -1830,47 +1847,68 @@ } if (suitablePeer) { - const url = getPeerUrl(suitablePeer) - debugLog('Found suitable peer with URL: ' + url + 'index: ' + i) - serverAdress = url - apiAdress = url + 'api/' - if ( - suitablePeer.host === originalServer.host && - suitablePeer.port === originalServer.port - ) { - setVal('peerToUse', undefined) - usingPeer = false - } else { - setVal('peerToUse', JSON.stringify(suitablePeer)) - usingPeer = true - } - - SafeGetElementById('scriptMenuDiv', (elem) => { - elem.style.backgroundColor = '#222426' - }) - - ConnectToServer() + debugLog( + 'Found suitable peer with URL: ' + + getPeerUrl(suitablePeer) + + 'index: ' + + i + ) + connectToPeer(suitablePeer) } else { SafeGetElementById('retryContainer', (elem) => { elem.style.display = 'flex' }) + SafeGetElementById('peerSelector', (elem) => { + elem.style.display = '' + }) SafeGetElementById('infoMainDiv', (elem) => { elem.innerText = texts.noPeersOnline }) + SafeGetElementById('scriptMenuDiv', (elem) => { + elem.style.backgroundColor = 'red' + }) debugLog('None of the peers are online!') } } catch (e) { SafeGetElementById('retryContainer', (elem) => { elem.style.display = 'flex' }) + SafeGetElementById('peerSelector', (elem) => { + elem.style.display = '' + }) SafeGetElementById('infoMainDiv', (elem) => { elem.innerText = texts.peerTryingError }) + SafeGetElementById('scriptMenuDiv', (elem) => { + elem.style.backgroundColor = 'red' + }) warn('Error ocurred during trying to connect to peers!') warn(e) } } + function connectToPeer(peer) { + const url = getPeerUrl(peer) + serverAdress = url + apiAdress = url + 'api/' + if ( + peer.host === originalServer.host && + peer.port === originalServer.port + ) { + setVal('peerToUse', undefined) + usingPeer = false + } else { + setVal('peerToUse', JSON.stringify(peer)) + usingPeer = true + } + + SafeGetElementById('scriptMenuDiv', (elem) => { + elem.style.backgroundColor = '#222426' + }) + + ConnectToServer() + } + function NoUserAction() { SafeGetElementById('scriptMenuDiv', (elem) => { elem.style.backgroundColor = '#44cc00' @@ -2627,7 +2665,7 @@ display: 'flex', flexDirection: 'column', width: '300px', - height: '90px', + height: '100px', position: 'fixed', padding: '3px 0px', bottom: '30px', @@ -2740,6 +2778,59 @@ textAlign: 'center', }, }, + peerSelector: { + customElem: () => { + try { + const peerSelector = document.createElement('select') + peerSelector.setAttribute('id', 'peerSelector') + SetStyle(peerSelector, { + width: '100%', + textAlign: 'center', + backgroundColor: '#262626', + color: 'white', + border: '1px solid #f2cb05', + cursor: 'pointer', + }) + + // FIXME: add new peers here after load + const peers = [ + originalServer, + ...JSON.parse(getVal('lastp2pinfo')), + ] + + if (peers.length === 1) { + return document.createElement('span') + } + + peers.forEach((peer, i) => { + const option = document.createElement('option') + option.innerText = getPeerUrl(peer, true) + option.value = i + + peerSelector.appendChild(option) + }) + + peerSelector.addEventListener('change', (e) => { + skipAvailablePeerFind = true + const selectedPeer = peers[e.target.value] + connectToPeer(selectedPeer) + resetMenu() + }) + + try { + const selectedPeer = JSON.parse(getVal('peerToUse')) + const selectedIndex = peers.findIndex((x) => { + return getPeerUrl(x) === getPeerUrl(selectedPeer) + }) + peerSelector.value = selectedIndex + } catch (e) {} + + return peerSelector + } catch (e) { + return document.createElement('span') + } + }, + }, loginContainer: { id: 'loginDiv', style: { @@ -2901,7 +2992,10 @@ } } - function getPeerUrl(peer) { + function getPeerUrl(peer, forDisplay) { + if (forDisplay) { + return peer.host + ':' + peer.port + } let protocol = 'https://' if (isDevel) { protocol = 'http://'