mirror of
https://gitlab.com/MrFry/moodle-test-userscript
synced 2025-04-01 20:22:48 +02:00
updated readme, added make.sh, added peer selector
This commit is contained in:
parent
e90eb6d3b9
commit
72815d59fb
4 changed files with 175 additions and 56 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
node_modules
|
||||||
|
stable.user.js
|
29
README.md
29
README.md
|
@ -1,24 +1,17 @@
|
||||||
# Moodle/KMOOC teszt megoldó userscript
|
## Install
|
||||||
|
|
||||||
## Telepítés
|
1. Greasyfork-s guide on installing userscripts: https://greasyfork.org/en/help/installing-user-scripts
|
||||||
1. [Greasyfork leírása userscript futtató addon telepítésére](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
|
||||||
2. [Telepítés hivatalos weboldalról](http://qmining.frylabs.net/install)
|
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.
|
## License:
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
# 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:
|
|
||||||
GPLv3
|
GPLv3
|
||||||
|
|
30
make.sh
Executable file
30
make.sh
Executable file
|
@ -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}'"
|
|
@ -71,8 +71,8 @@
|
||||||
// @match https://moodle.uni-corvinus.hu/*
|
// @match https://moodle.uni-corvinus.hu/*
|
||||||
// @match https://v39.moodle.uniduna.hu/*
|
// @match https://v39.moodle.uniduna.hu/*
|
||||||
// @match https://mentok.net/*
|
// @match https://mentok.net/*
|
||||||
// @match https://qmining.frylabs.net/*
|
// @match https://qmining.[DOMAIN]/*
|
||||||
// @match https://frylabs.net/*
|
// @match https://[DOMAIN]/*
|
||||||
// @noframes
|
// @noframes
|
||||||
// @run-at document-start
|
// @run-at document-start
|
||||||
// @grant GM_getResourceText
|
// @grant GM_getResourceText
|
||||||
|
@ -84,16 +84,16 @@
|
||||||
// @grant GM_openInTab
|
// @grant GM_openInTab
|
||||||
// @grant unsafeWindow
|
// @grant unsafeWindow
|
||||||
// @license GNU General Public License v3.0 or later
|
// @license GNU General Public License v3.0 or later
|
||||||
// @supportURL frylabs.net
|
// @supportURL [DOMAIN]
|
||||||
// @contributionURL frylabs.net
|
// @contributionURL [DOMAIN]
|
||||||
// @namespace https://frylabs.net
|
// @namespace https://[DOMAIN]
|
||||||
// @updateURL https://frylabs.net/moodle-test-userscript/stable.user.js?up
|
// @updateURL https://[DOMAIN]/moodle-test-userscript/stable.user.js?up
|
||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
// : }}}
|
// : }}}
|
||||||
|
|
||||||
;(function () {
|
;(function () {
|
||||||
// CONFIG
|
// CONFIG
|
||||||
let originalServer = { host: 'frylabs.net', port: 443 }
|
let originalServer = { host: '[DOMAIN]', port: 443 }
|
||||||
const logElementGetting = false
|
const logElementGetting = false
|
||||||
const logEnabled = true
|
const logEnabled = true
|
||||||
const motdShowCount = 5 // Ammount of times to show motd
|
const motdShowCount = 5 // Ammount of times to show motd
|
||||||
|
@ -135,7 +135,7 @@
|
||||||
// Devel vars
|
// Devel vars
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
// 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 = true
|
||||||
const forcedMatchString = isDevel ? 'default' : null
|
const forcedMatchString = isDevel ? 'default' : null
|
||||||
// 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
|
||||||
|
@ -153,6 +153,7 @@
|
||||||
var updatableElements = [] // { elem: ..., target: ... }
|
var updatableElements = [] // { elem: ..., target: ... }
|
||||||
var elementUpdaterInterval = -1
|
var elementUpdaterInterval = -1
|
||||||
const overlayElemUpdateInterval = 2 // seconds
|
const overlayElemUpdateInterval = 2 // seconds
|
||||||
|
var skipAvailablePeerFind = false
|
||||||
|
|
||||||
if (isDevel) {
|
if (isDevel) {
|
||||||
warn('Moodle script running in developement mode!')
|
warn('Moodle script running in developement mode!')
|
||||||
|
@ -1746,6 +1747,9 @@
|
||||||
|
|
||||||
function ConnectToServer() {
|
function ConnectToServer() {
|
||||||
clearAllMessages()
|
clearAllMessages()
|
||||||
|
SafeGetElementById('peerSelector', (elem) => {
|
||||||
|
elem.style.display = 'none'
|
||||||
|
})
|
||||||
GetXHRInfos()
|
GetXHRInfos()
|
||||||
.then((inf) => {
|
.then((inf) => {
|
||||||
try {
|
try {
|
||||||
|
@ -1762,14 +1766,15 @@
|
||||||
setVal('userId', inf.uid)
|
setVal('userId', inf.uid)
|
||||||
overlay.querySelector(
|
overlay.querySelector(
|
||||||
'#infoMainDiv'
|
'#infoMainDiv'
|
||||||
).innerText = `${subjInfo.subjects.toLocaleString()} tárgy, ${subjInfo.questions.toLocaleString()} kérdés. UID: #${getUid()}\n${getShortServerURL(
|
).innerText = `${subjInfo.subjects.toLocaleString()} tárgy, ${subjInfo.questions.toLocaleString()} kérdés. UID: #${getUid()}`
|
||||||
serverAdress
|
|
||||||
)}`
|
|
||||||
if (inf.unreads.length > 0) {
|
if (inf.unreads.length > 0) {
|
||||||
overlay.querySelector('#mailButton').innerText = '📬'
|
overlay.querySelector('#mailButton').innerText = '📬'
|
||||||
}
|
}
|
||||||
|
|
||||||
getPeers().catch(() => warn('unable to get p2p info'))
|
getPeers().catch(() => warn('unable to get p2p info'))
|
||||||
|
SafeGetElementById('peerSelector', (elem) => {
|
||||||
|
elem.style.display = ''
|
||||||
|
})
|
||||||
AfterLoad()
|
AfterLoad()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
warn(texts.unhandledErrorConsoleMessage)
|
warn(texts.unhandledErrorConsoleMessage)
|
||||||
|
@ -1779,15 +1784,27 @@
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
warn(texts.noServerConsoleMessage)
|
warn(texts.noServerConsoleMessage)
|
||||||
warn(e)
|
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() {
|
async function tryAnotherPeer() {
|
||||||
SafeGetElementById('scriptMenuDiv', (elem) => {
|
|
||||||
elem.style.backgroundColor = 'red'
|
|
||||||
})
|
|
||||||
|
|
||||||
debugLog('Unable to connect to main server, trying peers')
|
debugLog('Unable to connect to main server, trying peers')
|
||||||
try {
|
try {
|
||||||
const lastp2pinfo = JSON.parse(getVal('lastp2pinfo'))
|
const lastp2pinfo = JSON.parse(getVal('lastp2pinfo'))
|
||||||
|
@ -1830,47 +1847,68 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (suitablePeer) {
|
if (suitablePeer) {
|
||||||
const url = getPeerUrl(suitablePeer)
|
debugLog(
|
||||||
debugLog('Found suitable peer with URL: ' + url + 'index: ' + i)
|
'Found suitable peer with URL: ' +
|
||||||
serverAdress = url
|
getPeerUrl(suitablePeer) +
|
||||||
apiAdress = url + 'api/'
|
'index: ' +
|
||||||
if (
|
i
|
||||||
suitablePeer.host === originalServer.host &&
|
)
|
||||||
suitablePeer.port === originalServer.port
|
connectToPeer(suitablePeer)
|
||||||
) {
|
|
||||||
setVal('peerToUse', undefined)
|
|
||||||
usingPeer = false
|
|
||||||
} else {
|
|
||||||
setVal('peerToUse', JSON.stringify(suitablePeer))
|
|
||||||
usingPeer = true
|
|
||||||
}
|
|
||||||
|
|
||||||
SafeGetElementById('scriptMenuDiv', (elem) => {
|
|
||||||
elem.style.backgroundColor = '#222426'
|
|
||||||
})
|
|
||||||
|
|
||||||
ConnectToServer()
|
|
||||||
} else {
|
} else {
|
||||||
SafeGetElementById('retryContainer', (elem) => {
|
SafeGetElementById('retryContainer', (elem) => {
|
||||||
elem.style.display = 'flex'
|
elem.style.display = 'flex'
|
||||||
})
|
})
|
||||||
|
SafeGetElementById('peerSelector', (elem) => {
|
||||||
|
elem.style.display = ''
|
||||||
|
})
|
||||||
SafeGetElementById('infoMainDiv', (elem) => {
|
SafeGetElementById('infoMainDiv', (elem) => {
|
||||||
elem.innerText = texts.noPeersOnline
|
elem.innerText = texts.noPeersOnline
|
||||||
})
|
})
|
||||||
|
SafeGetElementById('scriptMenuDiv', (elem) => {
|
||||||
|
elem.style.backgroundColor = 'red'
|
||||||
|
})
|
||||||
debugLog('None of the peers are online!')
|
debugLog('None of the peers are online!')
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
SafeGetElementById('retryContainer', (elem) => {
|
SafeGetElementById('retryContainer', (elem) => {
|
||||||
elem.style.display = 'flex'
|
elem.style.display = 'flex'
|
||||||
})
|
})
|
||||||
|
SafeGetElementById('peerSelector', (elem) => {
|
||||||
|
elem.style.display = ''
|
||||||
|
})
|
||||||
SafeGetElementById('infoMainDiv', (elem) => {
|
SafeGetElementById('infoMainDiv', (elem) => {
|
||||||
elem.innerText = texts.peerTryingError
|
elem.innerText = texts.peerTryingError
|
||||||
})
|
})
|
||||||
|
SafeGetElementById('scriptMenuDiv', (elem) => {
|
||||||
|
elem.style.backgroundColor = 'red'
|
||||||
|
})
|
||||||
warn('Error ocurred during trying to connect to peers!')
|
warn('Error ocurred during trying to connect to peers!')
|
||||||
warn(e)
|
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() {
|
function NoUserAction() {
|
||||||
SafeGetElementById('scriptMenuDiv', (elem) => {
|
SafeGetElementById('scriptMenuDiv', (elem) => {
|
||||||
elem.style.backgroundColor = '#44cc00'
|
elem.style.backgroundColor = '#44cc00'
|
||||||
|
@ -2627,7 +2665,7 @@
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
width: '300px',
|
width: '300px',
|
||||||
height: '90px',
|
height: '100px',
|
||||||
position: 'fixed',
|
position: 'fixed',
|
||||||
padding: '3px 0px',
|
padding: '3px 0px',
|
||||||
bottom: '30px',
|
bottom: '30px',
|
||||||
|
@ -2740,6 +2778,59 @@
|
||||||
textAlign: 'center',
|
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: {
|
loginContainer: {
|
||||||
id: 'loginDiv',
|
id: 'loginDiv',
|
||||||
style: {
|
style: {
|
||||||
|
@ -2901,7 +2992,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPeerUrl(peer) {
|
function getPeerUrl(peer, forDisplay) {
|
||||||
|
if (forDisplay) {
|
||||||
|
return peer.host + ':' + peer.port
|
||||||
|
}
|
||||||
let protocol = 'https://'
|
let protocol = 'https://'
|
||||||
if (isDevel) {
|
if (isDevel) {
|
||||||
protocol = 'http://'
|
protocol = 'http://'
|
Loading…
Add table
Add a link
Reference in a new issue