diff --git a/modules/main/main.js b/modules/main/main.js new file mode 100644 index 0000000..1ef78dc --- /dev/null +++ b/modules/main/main.js @@ -0,0 +1,73 @@ +/* ---------------------------------------------------------------------------- + + Question Server + GitLab: + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + ------------------------------------------------------------------------- */ + +let url = '' // http(s)//asd.basd + +const express = require('express') +const bodyParser = require('body-parser') +const busboy = require('connect-busboy') +const app = express() + +const logger = require('../../utils/logger.js') +// const utils = require('../utils/utils.js') +// const actions = require('../utils/actions.js') + +app.set('view engine', 'ejs') +app.set('views', [ + './modules/main/views', + './sharedViews' +]) +app.use(express.static('public')) +app.use(busboy({ + limits: { + fileSize: 10000 * 1024 * 1024 + } +})) +app.use(bodyParser.json()) +app.use(bodyParser.urlencoded({ + limit: '5mb', + extended: true +})) +app.use(bodyParser.json({ + limit: '5mb' +})) + +// -------------------------------------------------------------- + +app.get('/', function (req, res) { + res.render('main', { + siteurl: url + }) +}) + +app.get('*', function (req, res) { + res.status(404).render('shared/404') +}) + +app.post('*', function (req, res) { + res.status(404).render('shared/404') +}) + +exports.app = app +exports.setup = (x) => { + url = x.url +} + +logger.Log('Main module started', logger.GetColor('yellow')) diff --git a/modules/main/views/main.ejs b/modules/main/views/main.ejs new file mode 100755 index 0000000..11d8f43 --- /dev/null +++ b/modules/main/views/main.ejs @@ -0,0 +1,41 @@ + + + + + + FryLabs.net + + + + + + +

+ +

+ +
+   ____           __     __      
+  / __/_____ __  / /__ _/ /  ___ 
+ / _// __/ // / / / _ `/ _ \(_-< 
+/_/ /_/  \_, / /_/\_,_/_.__/___/ 
+        /___/ 
+        
+
+

+ + diff --git a/modules/old/old.js b/modules/old/old.js new file mode 100755 index 0000000..759748f --- /dev/null +++ b/modules/old/old.js @@ -0,0 +1,46 @@ +/* ---------------------------------------------------------------------------- + + Question Server + GitLab: + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + ------------------------------------------------------------------------- */ + +let url = '' +const express = require('express') +const app = express() + +const logger = require('../../utils/logger.js') + +// -------------------------------------------------------------- + +app.get('/', function (req, res) { + res.redirect(url + req.url) +}) + +app.get('*', function (req, res) { + res.redirect(url + req.url) +}) + +app.post('*', function (req, res) { + res.redirect(url + req.url) +}) + +exports.app = app +exports.setup = (x) => { + url = x.url +} + +logger.Log('Old module started', logger.GetColor('yellow')) diff --git a/modules/qmining/qmining.js b/modules/qmining/qmining.js new file mode 100644 index 0000000..e9112cb --- /dev/null +++ b/modules/qmining/qmining.js @@ -0,0 +1,242 @@ +/* ---------------------------------------------------------------------------- + + Question Server + GitLab: + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + ------------------------------------------------------------------------- */ + +let url = '' + +const express = require('express') +const bodyParser = require('body-parser') +const busboy = require('connect-busboy') +const fs = require('fs') +const app = express() +// const http = require('http') +// const https = require('https') + +const logger = require('../../utils/logger.js') +const utils = require('../../utils/utils.js') +const actions = require('../../utils/actions.js') + +const recivedFiles = 'public/recivedfiles' +const uloadFiles = 'public/f' +const dataFile = 'public/data.json' +const msgFile = 'stats/msgs' +const motdFile = 'public/motd' +let donateURL = '' +try { + donateURL = utils.ReadFile('./data/donateURL') +} catch (e) { + logger.Log('Couldnt read donate URL file!', logger.GetColor('red')) +} + +app.set('view engine', 'ejs') +app.set('views', [ + './modules/qmining/views', + './sharedViews' +]) +app.use(express.static('public')) +app.use(busboy({ + limits: { + fileSize: 10000 * 1024 * 1024 + } +})) +app.use(bodyParser.json()) +app.use(bodyParser.urlencoded({ + limit: '5mb', + extended: true +})) +app.use(bodyParser.json({ + limit: '5mb' +})) + +// -------------------------------------------------------------- + +app.get('/', function (req, res) { + // req.hostname + + let motd = '' + try { + motd = utils.ReadFile(motdFile) + } catch (e) { + + } + res.render('main', { + siteurl: url, + qa: actions.ProcessQA(), + motd: motd + }) + res.end() +}) + +app.get('/manual', function (req, res) { + res.render('man') + res.end() + logger.LogReq(req) +}) + +app.get('/legacy', function (req, res) { + var f = utils.ReadFile(dataFile) + var d = actions.LoadJSON(f) + let qcount = 0 + for (let i = 0; i < d.length; i++) { qcount += d.Subjects[i].length } + let scount = d.length + + res.render('alldata', { + data: d, + scount: scount, + qcount: qcount, + siteurl: url + }) + + logger.LogReq(req) +}) + +app.post('/postfeedback', function (req, res) { + res.redirect('back') + logger.Log('New feedback message', logger.GetColor('bluebg'), true) + utils.AppendToFile('\n\n' + logger.GetDateString() + ': ' + req.body.message_field, msgFile) +}) + +app.get('/postfeedback', function (req, res) { + res.redirect('/') +}) + +app.post('/isAdding', function (req, res) { + res.end('OK') + logger.LogReq(req) + actions.ProcessIncomingRequest(req.body.datatoadd) + utils.WriteBackup() +}) + +app.get('/lred', function (req, res) { + res.redirect('/legacy') + res.end() + logger.LogReq(req) +}) + +app.get('/menuClick', function (req, res) { + res.redirect('/') + res.end() + logger.LogReq(req) +}) + +// all questions readable +app.get('/allqr', function (req, res) { + var f = utils.ReadFile(dataFile) + var d = actions.LoadJSON(f) + + res.render('allqr', { + d: d.toString().split('\n') + }) + logger.LogReq(req) +}) + +app.get('/greasy', function (req, res) { + res.redirect('https://greasyfork.org/en/scripts/38999-moodle-elearning-kmooc-test-help') + res.end() + logger.LogReq(req) +}) + +app.get('/install', function (req, res) { + res.redirect(url + '/moodle-test-userscript/stable.user.js?install') + res.end() + logger.LogReq(req) +}) + +app.get('/donate', function (req, res) { + res.redirect(donateURL) + res.end() + logger.LogReq(req) +}) + +app.get('/thanks', function (req, res) { + res.render('thanks', { + siteurl: url + }) + res.end() + logger.LogReq(req) +}) + +app.get('/classesgit', function (req, res) { + res.redirect('https://gitlab.com/MrFry/question-classes') + res.end() + logger.LogReq(req) +}) + +app.get('/scriptgit', function (req, res) { + res.redirect('https://gitlab.com/MrFry/moodle-test-userscript') + res.end() + logger.LogReq(req) +}) + +app.get('/servergit', function (req, res) { + res.redirect('https://gitlab.com/MrFry/mrfrys-node-server') + res.end() + logger.LogReq(req) +}) + +function UploadFile (req, res, path, next) { + var fstream + req.pipe(req.busboy) + req.busboy.on('file', function (fieldname, file, filename) { + logger.Log('Uploading: ' + filename, logger.GetColor('blue')) + + utils.CreatePath(path, true) + let d = new Date() + let fn = d.getHours() + '' + d.getMinutes() + '' + d.getSeconds() + '_' + filename + + fstream = fs.createWriteStream(path + '/' + fn) + file.pipe(fstream) + fstream.on('close', function () { + logger.Log('Upload Finished of ' + path + '/' + fn, logger.GetColor('blue')) + next(fn) + }) + fstream.on('error', function (err) { + console.log(err) + res.end('something bad happened :s') + }) + }) +} + +app.route('/fosuploader').post(function (req, res, next) { + UploadFile(req, res, uloadFiles, (fn) => { + res.redirect('/f/' + fn) + }) +}) + +app.route('/badtestsender').post(function (req, res, next) { + UploadFile(req, res, recivedFiles, (fn) => { + res.render('uploaded') + }) + logger.LogReq(req) +}) + +app.get('*', function (req, res) { + res.status(404).render('404') +}) + +app.post('*', function (req, res) { + res.status(404).render('404') +}) + +exports.app = app +exports.setup = (x) => { + url = x.url +} + +logger.Log('Qmining module started', logger.GetColor('yellow')) diff --git a/modules/qmining/views/alldata.ejs b/modules/qmining/views/alldata.ejs new file mode 100755 index 0000000..4a9f454 --- /dev/null +++ b/modules/qmining/views/alldata.ejs @@ -0,0 +1,146 @@ + + + + + + All questions + + + + +
+

+ Ennek az oldalnak a tartalma dinamikusan frissül minden beküldött kérdés után +
+ <%=scount%> tárgy és <%=qcount%> kérdés +

+

+ Letöltés + +
+ + <% include aludni.ejs %> + + <% for (var i = 0; i < data.Subjects.length; i++) { %> + +
+ <% var a = data.Subjects[i].toString().split('\n')%> + <% for (var j = 1; j < a.length; j++) { %> + <% if (a[j][0] == '?') { %> +
+ <% } %> + <%=a[j] %> +
+ <% } %> +
+ <% } %> + + <% include b.ejs %> + + diff --git a/modules/qmining/views/allqr.ejs b/modules/qmining/views/allqr.ejs new file mode 100755 index 0000000..6e6b48d --- /dev/null +++ b/modules/qmining/views/allqr.ejs @@ -0,0 +1,23 @@ + + + + + + All questions + + + + + + <% for (var i = 0; i < d.length; i++) { %> + <%= d[i] %> +
+ <% } %> + + + diff --git a/modules/qmining/views/aludni.ejs b/modules/qmining/views/aludni.ejs new file mode 100755 index 0000000..b90d50c --- /dev/null +++ b/modules/qmining/views/aludni.ejs @@ -0,0 +1,6 @@ +<% var d = new Date().getHours(); +if (d < 6 || d > 22) { %> +
+ img +
+<% } %> diff --git a/modules/qmining/views/b.ejs b/modules/qmining/views/b.ejs new file mode 100755 index 0000000..c0804d8 --- /dev/null +++ b/modules/qmining/views/b.ejs @@ -0,0 +1,35 @@ +<% function GetRandom(min, max) { + return Math.floor(Math.random() * (max - min + 1) + min); +} %> + + +<% if (GetRandom(0, 100) == 1) { %> +
+ img +
+ + +<% } %> + + diff --git a/modules/qmining/views/main.ejs b/modules/qmining/views/main.ejs new file mode 100755 index 0000000..4a96f6d --- /dev/null +++ b/modules/qmining/views/main.ejs @@ -0,0 +1,112 @@ + + + + + + Question mining + + + + + + + +

+

+ Script install | + Manual | + Összes kérdés (Olvasható formátum) | + Összes kérdés (JSON) | + Szerver repó | + Userscript repó | + Classes repó | + Donate +

+ +
+

+ MOTD: + <%- motd %> +

+
+ +
+
Észrevételek: (közeledő teszt miatti kérdés-karbantartás, bug, feature vagy egyéb dolog, ami nyomja a lelked)
+ +
Rengeteg spam-et kapok, nyugodtan küldd el ezerszer, akkor hátha észreveszem a spam + között :)
+ +
+ +
+ + Hibát kiváltó teszt feltöltése +
+ +
+ + +
+ +

+ Ha egy kérdésre mindig helytelenül talál választ a userscript (vagy egyéb hibát észlelsz), akkor azon az oldalon nyomj egy ctrl-s -t. Ez lementi a weboldalt úgy ahogy van egy mappába, és egy html fájlba. Ezt a kettőt ha berakod egy .zip-be, és ide feltöltöd, akkor ránézek mi lehet a hiba, és kijavítom. Max 10 MB! + Ha több, elég a .html. Bónusz ha mellékelsz egy readme-t, hogy mit csináljak. + + <% include aludni.ejs %> + + + +
+ + + <% include qa.ejs %> + +
+
...
+ + <% include b.ejs %> + + diff --git a/modules/qmining/views/man.ejs b/modules/qmining/views/man.ejs new file mode 100755 index 0000000..8df7192 --- /dev/null +++ b/modules/qmining/views/man.ejs @@ -0,0 +1,232 @@ + + + + + + + Moodle/Elearning/KMOOC manual + + + + +
+

Moodle/Elearnig/KMOOC manual

+
+
+ Ez a userscript Moodle/Elearnig/KMOOC tesztek megoldása során segítséget jelenít meg. +
+

+ A válasz ablakban jobb felül lévő százalék jelzi, hogy mekkora eséllyel jó a megoldás. Ez + sokszor jó viszonyítás, de semmi sem biztos! Bármikor előfordulhat, hogy nem jó a + megjelenített válasz! Ezért csak saját felelősségedre használd! Sok kikerülhetetlen + hibalehetőség van, amit egyszerű nem lehet scriptben lekezelni (Pl rosszul megadott kérdés + tanár részéről). Kézzel is lehet keresni a elmentett kérdések között. Ezért mindig + legyen egy letöltött verziód a kérdésekről, mert nem 100% hogy mindég elérhető a szerver! + Továbbá ha a moodle oldalán a layout megváltozik, a script nem fog működni! Ez nem annyira + gyakori, de bármikor megtörténhet! Érdemes nem kikapcsolni a tampermonkey-ban a userscript + frissítést. Ez nem windows update, itt tényleg hibajavítások jönnek ki. Hiba, észrevétel + esetén : Script Feedback (ezt + gyakran még aznap megnézem.) +

+

+ Továbbá ez a userscript HTTP requestekket küldhet egy szerver felé, ahova az összes megoldott + tesztjeid kérdéseit és (helyes)válaszait feltölti! Ezzel garantálja, hogy neked, és mindenki + másnak a legfrissebb adatok állnak rendelkezésre. +
+ + <% include aludni.ejs %> + +

Tartalomjegyzék

+
+
+
    +
  • + Használat - Ez szuper fontos, elsőnek olvasd el +
  • +
  • + Eddigi teszt kérdések - Itt elérhető az eddigi összes ismert teszt + kérdés-válaszai +
  • +
  • + Gyakran előforduló kérdések - Ha itt nincs kérdésed, akkor itt tedd fel! +
  • +
  • + Adat egyszerűsítés - Ha túl sok egyforma kérdésed van ;) +
  • +
  • + Other stuff +
  • +
+
+

Használat

+
+
+ + + +
+

Először is tölts le egy userscript futtató kiegészítőt a böngésződhöz. Én Tampermonkeyt használok, és ezzel van tesztelve a + userscript is, ezért ez ajánlott. Más is működhet (violentmonkey, etc), de az nem garantált. + Majd a weboldalról egy kattintással elvileg + le tudod tölteni a scriptet, és elvileg kész is. +

Ha tesztet akarsz megoldani, akkor először nézd meg a menüben, hogy aktív-e a + tárgyad. Teszt közben a script a megadott tárgy már lementett kérdéseiből próbál segíteni. +

+

Teszt közben még több dolog történhet: +

+
    +
  • Nem jó kérdésre ad választ a script: Ilyenkor az van, hogy nincs meg a + kérdés, vagy több hasonló kérdés/válasz van. Ilyenkor a jobbra/balra gombbal + váltogathatsz azok a kérdés/válasz combók közül, amit talált a script
  • + +
  • Több teszt kérdés van egy oldalon: Fel le gombbal váltogathatsz a kérdések között. + Ilyenkor is működik az előbb említett funkció. Az indexek, amit kiír a bal felső sarokban: + aktuális kérdés száma / aktuális találat száma.
  • + +
  • Nem jelenik meg semmi, vagy nem működik a script: Megesik az ilyesmi. Ha + a webszerver még elérhető akkor ott meg bírod nézni a kérdéseket, és ott lehet + keresgélni Ctrl + F -el Ha az sincs, akkor lehet hogy jól jön ha van egy + lementett kérdés gyűjteményed.
  • +
+ +

Fontos hogy kijelöld a tárgyat amit szeretnél "tanulni" mielőtt nekikezdesz. Ha egy + olyan tárgynak kezdesz neki, ami még nincs benne az adatbázisban, akkor az új tárgyként + fog bekerülni (obviously). De azt neked kell utána aktívnak jelölnöd! Ha nem + használsz egy tárgyat, akkor kapcsold ki, mert picit belassulhat! + +

Egyéb funkciók: +
    +
  • + Ha esetleg videókat nézel, akkor spaceval lehet play/pausolni, és jobbra/balra + gombbal ugrani a videóban. +
  • +
  • + Menüben el lehet rejteni a kérdéseket a felugró ablakról, így az + kisebb helyet foglal, de így nem bírod ellenőrizni, hogy tényleg jó kérdés/választ talált-e. +
  • +
  • + Ugyanitt az üdvözlő üzenetet is el lehet rejteni. Ez frissítésnél vagy hibánál így is + úgyis megjelenik, mert azok nagyjából fontosak. +
  • +
  • + Ha bármikor nem kell a script, akkor a menü gomb alatt bekapcsolhatod a passzív + módot, ami nem olvassa be a kérdéseket. Vagy kikapcsolhatod magát a scriptet + tampermonkey-ban. Ha bármiért is el akarod tüntetni a következő oldalig az éppen + megjelenő script ablakot, akkor középső egér gombbal kattintva rajta ezt + megteheted. +
  • +
+ +

TL; DR:

+ + Olvasd csak el. Az összes bonyodalom abból adódik, hogy a tampermonkey API-je + korlátozott, és néhány dolgot neked kell megcsinálni, megérteni. Nagy eséllyel semmi + teendőd, de azért jó ha tudod hogy működik, ha esetleg valami elromlik teszt közben, + tudd hogy lehet megcsinálni gyorsan. Legyen mindég nálad egy másolat az online + kérdésekről, mert bármikor eltűnhet! + +
+ img +
+
+

Eddigi teszt kérdések:

+
+
+ Eddigi összes kérdés + Továbbá ez még arra jó, hogy ha valamiért bugos a script, akkor itt tudsz ctrl-f el nézegetni, + vagy ha lemented az összes kérdést, akkor még akkor is biztonságban vagy, ha netán leáll a + szerver, vagy elmegy a neted. Bár úgy nehezen moodlezel, de mind1 + +
+

Gyakran előforduló kérdések

+
+
+
    +
  • + 1. Olyan helyeken fut le a script, ahol nem kellene, vagy zavar +
    Tampermonkey bővitmény ikon -> click -> scriptet kapcsold ki. Csak ne felejtsd + visszakapcsolni ;) Meg passzív módot is bekapcsolhatod a menü gomb alatt. +
  • +

    +
  • + 2. Túl nagy a kérdést és a választ megjelenítő ablak, nem tudok a válaszra kattintani +
    Zommolj ki egy kicsit, vagy kapcsold ki addig a scriptet. Továbbá középső + egérgombra kattintva rá el bírod tüntetni az ablakot, amíg újra nem töltöd az oldalt, + vagy másikra ugrasz. +
  • +

    +
  • + 3. Online adatokat használok, de a script hibát jelez +
    Ennek több oka is lehet: +
      +
    • Nem engedélyezted az http requestek küldését a usercript menedzselő + programodnál. Ez nélkül nem működik.
    • +
    • Nem elérhető a szerver. Ezt ellenőrizheted: link
    • +
    • Nincs kiválasztva a megoldani kívánt tárgy a menüben.
    • +
    +
  • +
  • + 4. Mi ez a ... ? +
    + img +
  • +
  • + 5. +
    + img +
  • +

    +
  • + Egyéb:
    + észrevétel +
  • +
+
Jogosultságok: +
GM_openInTab: help megnyitása új lapon, GM_xmlhttpRequest: online adatbázishoz. GM_info: a + scriptről információ, a verzióváltozás érzékeléséhez. GM_getValue/ GM_setValue: oldal + bezárásakor megmaradó változók kezelése. Előző verzió tárolására, ugyanúgy verzióváltozás + érzékeléséhez, néhány beállítás, illetve hogy melyik tárgyakból keressen kérdéseket. Ezek + függvények, és a sciptben néhol meg vannak hívva, keresd meg. +

Elküldött adatok online módban: Minden teszt végén az összes kérdés, és rá a moodle szerint + helyesnek vélt válaszok. Fogadott adatok: az összes eddig ismert moodle kérdés +
+
+

+ Weboldal +

+
+ + + <% include b.ejs %> + + diff --git a/modules/qmining/views/qa.ejs b/modules/qmining/views/qa.ejs new file mode 100755 index 0000000..f3315b3 --- /dev/null +++ b/modules/qmining/views/qa.ejs @@ -0,0 +1,35 @@ +

Q & A:

+<% for (var i = qa.length - 1; i >= 0 ; i--) { %> +
+ + + + +
+

+ <%= i %> +

+
+ + + <%= qa[i].q %> + + +

+ <% if (qa[i].a) { %> + <% for (var j = 0; j < qa[i].a.length; j++) { %> + + <% if (j != 0) { %> +

+ <% } %> + + <%= qa[i].a[j] %> + + <% } %> + + <% } else { %> + Válasz folyamatban... + <% } %> +

+ +<% } %> diff --git a/modules/qmining/views/thanks.ejs b/modules/qmining/views/thanks.ejs new file mode 100644 index 0000000..a83885f --- /dev/null +++ b/modules/qmining/views/thanks.ejs @@ -0,0 +1,114 @@ + + + + + + + Thank you! + + + +
+
+
+
+
+
Thanks for the gold, kind question miner!Return
+
+
+
+
+
+ + + diff --git a/modules/qmining/views/uploaded.ejs b/modules/qmining/views/uploaded.ejs new file mode 100755 index 0000000..38c7812 --- /dev/null +++ b/modules/qmining/views/uploaded.ejs @@ -0,0 +1,23 @@ + + + + + + + + + + fájl feltöltve! + Vissza + + + diff --git a/modules/sio/sio.js b/modules/sio/sio.js new file mode 100644 index 0000000..5ae80c9 --- /dev/null +++ b/modules/sio/sio.js @@ -0,0 +1,99 @@ +/* ---------------------------------------------------------------------------- + + Question Server + GitLab: + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + ------------------------------------------------------------------------- */ + +const express = require('express') +const bodyParser = require('body-parser') +const busboy = require('connect-busboy') +const fs = require('fs') +const app = express() +// const http = require('http') +// const https = require('https') + +const logger = require('../../utils/logger.js') +const utils = require('../../utils/utils.js') + +const uloadFiles = './public/f' + +app.set('view engine', 'ejs') +app.set('views', [ + './modules/sio/views', + './sharedViews' +]) +app.use(express.static('public')) +app.use(busboy({ + limits: { + fileSize: 10000 * 1024 * 1024 + } +})) +app.use(bodyParser.json()) +app.use(bodyParser.urlencoded({ + limit: '5mb', + extended: true +})) +app.use(bodyParser.json({ + limit: '5mb' +})) + +// -------------------------------------------------------------- + +app.get('/', function (req, res) { + res.render('uload') + res.end() +}) + +function UploadFile (req, res, path, next) { + var fstream + req.pipe(req.busboy) + req.busboy.on('file', function (fieldname, file, filename) { + logger.Log('Uploading: ' + filename, logger.GetColor('blue')) + + utils.CreatePath(path, true) + let d = new Date() + let fn = d.getHours() + '' + d.getMinutes() + '' + d.getSeconds() + '_' + filename + + fstream = fs.createWriteStream(path + '/' + fn) + file.pipe(fstream) + fstream.on('close', function () { + logger.Log('Upload Finished of ' + path + '/' + fn, logger.GetColor('blue')) + next(fn) + }) + fstream.on('error', function (err) { + console.log(err) + res.end('something bad happened :s') + }) + }) +} + +app.route('/fosuploader').post(function (req, res, next) { + UploadFile(req, res, uloadFiles, (fn) => { + res.redirect('/f/' + fn) + }) +}) +app.get('*', function (req, res) { + res.status(404).render('shared/404') +}) + +app.post('*', function (req, res) { + res.status(404).render('shared/404') +}) + +exports.app = app + +logger.Log('Sio module started', logger.GetColor('yellow')) diff --git a/modules/sio/views/uload.ejs b/modules/sio/views/uload.ejs new file mode 100755 index 0000000..89a6f9a --- /dev/null +++ b/modules/sio/views/uload.ejs @@ -0,0 +1,39 @@ + + + + + + Shit uploader + + + + +
+ + +
+ + + + diff --git a/modules/stuff/stuff.js b/modules/stuff/stuff.js new file mode 100644 index 0000000..07976d7 --- /dev/null +++ b/modules/stuff/stuff.js @@ -0,0 +1,212 @@ +/* ---------------------------------------------------------------------------- + + Question Server + GitLab: + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + ------------------------------------------------------------------------- */ + +const express = require('express') +const bodyParser = require('body-parser') +const busboy = require('connect-busboy') +const fs = require('fs') +const app = express() +let url = '' + +const logger = require('../../utils/logger.js') +// const utils = require('../utils/utils.js') +// const actions = require('../utils/actions.js') + +const listedFiles = './public/files' + +app.set('view engine', 'ejs') +app.set('views', [ + './modules/stuff/views', + './sharedViews' +]) +app.use(express.static('public')) +app.use(busboy({ + limits: { + fileSize: 10000 * 1024 * 1024 + } +})) +app.use(bodyParser.json()) +app.use(bodyParser.urlencoded({ + limit: '5mb', + extended: true +})) +app.use(bodyParser.json({ + limit: '5mb' +})) + +// -------------------------------------------------------------- + +// app, '/*.mp4', 'video/mp4', 'stuff/video' +function appGetFileType (app, wildcard, contentType, pageToRender) { + app.get(wildcard, function (req, res) { + let p = decodeURI(req.url) + let fp = p + if (p.includes('?')) { + fp = p.split('?') + fp.pop() + fp = fp.join('/') + } + const fpath = './public/files' + fp + if (!fs.existsSync(fpath)) { + res.render('nofile', { + missingFile: fpath, + url + }) + return + } + if (req.query.stream || !pageToRender) { + const stat = fs.statSync(fpath) + const fileSize = stat.size + const range = req.headers.range + if (range) { + const parts = range.replace(/bytes=/, '').split('-') + const start = parseInt(parts[0], 10) + const end = parts[1] + ? parseInt(parts[1], 10) + : fileSize - 1 + const chunksize = (end - start) + 1 + const file = fs.createReadStream(fpath, { start, end }) + const head = { + 'Content-Range': `bytes ${start}-${end}/${fileSize}`, + 'Accept-Ranges': 'bytes', + 'Content-Length': chunksize, + 'Content-Type': contentType + } + res.writeHead(206, head) + file.pipe(res) + } else { + const head = { + 'Content-Length': fileSize, + 'Content-Type': contentType + } + res.writeHead(200, head) + fs.createReadStream(fpath).pipe(res) + } + } else { + logger.LogReq(req) + let fname = fpath.split('/') + fname = fname.pop() + res.render(pageToRender, { + path: fp, + fname, + url, + contentType, + albumArt: GetAlbumArt(p) + }) + } + }) +} + +const fileTypes = [ + ['/*.mp4', 'video/mp4', 'video'], + ['/*.mkv', 'audio/x-matroska', 'video'], + ['/*.mp3', 'audio/mpeg', 'audio'], + ['/*.pdf', 'application/pdf'], + ['/*.zip', 'application/zip'] +] + +function GetAlbumArt (path) { + let tmp = path.split('.') + tmp.pop() + tmp = tmp.join('.').split('/') + let last = tmp.pop() + + return tmp.join('/') + '/.' + last + '.png' +} + +fileTypes.forEach((t) => { + appGetFileType(app, t[0], t[1], t[2]) +}) + +app.get('/*', function (req, res) { + let parsedUrl = decodeURI(req.url) + let curr = listedFiles + '/' + parsedUrl.substring('/'.length, parsedUrl.length).split('?')[0] + let relPath = curr.substring('./public/files'.length, curr.length) + + if (relPath[relPath.length - 1] !== '/') { relPath += '/' } + + let t = relPath.split('/') + let prevDir = '' + for (let i = 0; i < t.length - 2; i++) { prevDir += t[i] + '/' } + + // curr = curr.replace(/\//g, "/"); + // relPath = relPath.replace(/\//g, "/"); + + logger.LogReq(req) + + try { + if (fs.lstatSync(curr).isDirectory()) { + if (curr[curr.length - 1] !== '/') { curr += '/' } + + let f = [] + + fs.readdirSync(curr).forEach((item) => { + if (item[0] !== '.') { + let res = { name: item } + let stat = fs.statSync(curr + '/' + item) + + let fileSizeInBytes = stat['size'] + res.size = Math.round(fileSizeInBytes / 1000000) + + res.path = relPath + if (res.path[res.path.length - 1] !== '/') { res.path += '/' } + res.path += item + + res.mtime = stat['mtime'].toLocaleString() + res.isDir = stat.isDirectory() + + f.push(res) + } + }) + + res.render('folders', { + folders: f, + dirname: relPath, + prevDir, + url + }) + } else { + let fileStream = fs.createReadStream(curr) + fileStream.pipe(res) + } + } catch (e) { + res.render('nofile', { + missingFile: curr, + url + }) + } +}) + +// ----------------------------------------------------------------------------------------------- + +app.get('*', function (req, res) { + res.status(404).render('shared/404') +}) + +app.post('*', function (req, res) { + res.status(404).render('shared/404') +}) + +exports.app = app +exports.setup = (x) => { + url = x.url +} + +logger.Log('Stuff module started', logger.GetColor('yellow')) diff --git a/modules/stuff/views/audio.ejs b/modules/stuff/views/audio.ejs new file mode 100755 index 0000000..6d5e3ae --- /dev/null +++ b/modules/stuff/views/audio.ejs @@ -0,0 +1,39 @@ + + + + + + + <%= fname %> + + + + +
+

+ <%= fname %> +

+  + +
+ + + diff --git a/modules/stuff/views/folders.ejs b/modules/stuff/views/folders.ejs new file mode 100755 index 0000000..e6dd742 --- /dev/null +++ b/modules/stuff/views/folders.ejs @@ -0,0 +1,130 @@ + + + + + + <%=dirname%> + + + + +
+

+ <%=dirname%> +

+
+

+ Up one level +

+

+ + + <% for (var i = 0; i < folders.length; i++) { %> + + + + <% } %> +
+ + + +
+ + + diff --git a/modules/stuff/views/nofile.ejs b/modules/stuff/views/nofile.ejs new file mode 100755 index 0000000..c2e81ae --- /dev/null +++ b/modules/stuff/views/nofile.ejs @@ -0,0 +1,94 @@ + + + + + + No such file/folder + + + +
+

+ No such file / folder: +
+ <%= missingFile %> +
+ Back to root +
+ + Go back + +

+
+ + + diff --git a/modules/stuff/views/video.ejs b/modules/stuff/views/video.ejs new file mode 100755 index 0000000..62db36a --- /dev/null +++ b/modules/stuff/views/video.ejs @@ -0,0 +1,34 @@ + + + + + + <%= fname %> + + + + +
+

+ <%= fname %> +

+
+ + + +