NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Cursed Knowledge (9¾) // @namespace off2class // @version 14.41 // @description «I work to support my hobby. So If you asked me which I’d choose, my job or my hobby, my hobby takes priority.» // @author 3rdUnknown // @homepageURL https://openuserjs.org/scripts/3rdUnknown/Cursed_Knowledge_(9%C2%BE) // @copyright 2021 // @license MIT // @match https://*.off2class.com/student/* // @match https://*.off2class.com/student // @require https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.3.1/chart.min.js // @require https://ics-ikeda.github.io/shuffle-text/build/shuffle-text.js // @grant GM_getResourceText // @grant GM_addStyle // @run-at document-idle // @updateURL https://openuserjs.org/meta/3rdUnknown/Cursed_Knowledge_(9¾).meta.js // ==/UserScript== (function() { 'use strict'; //“Did you know? If a colony of ants gets rid of the laziest one, another one will just start being lazy instead?” if ((window.location.pathname.indexOf('student/lesson') !== -1) || (window.location.pathname.indexOf('student/placement') !== -1)) { enableCopy(); } else if (window.location.pathname.indexOf('student/homework') !== -1) { let lessonInfo = document.querySelector(".mt-2"); let lessonInfoContainer = createLessonInfo(lessonInfo); enableCopy(); const created = o2c.page.homework.created_at; const updated = o2c.page.homework.updated_at; const lesson = o2c.page.homework.lesson_id; const dueDate = o2c.page.studentHomework.due_date; const createdAt = o2c.page.studentHomework.created_at; const submitted = o2c.page.studentHomework.latest_student_answer.answer.submitted; const submittedAt = o2c.page.studentHomework.latest_student_answer.answer.submitted_at; addElement('gif','https://7355608.fun/images/cat.gif', lessonInfoContainer); addElement('title', `Lesson ID: ${lesson}`, lessonInfoContainer); addElement('data', `Test was created: ${created}`, lessonInfoContainer); addElement('data', `Test was updated: ${updated}`, lessonInfoContainer); addElement('data', `Homework was assigned: ${createdAt}`, lessonInfoContainer); addElement('data', `Due date: ${dueDate}`, lessonInfoContainer); addElement('title', diffDate(dueDate, (new Date()), 'Test will be closed after: '), lessonInfoContainer); if (submitted) { addElement('title', diffDate(submittedAt, (new Date(createdAt)), 'Test was done after: '), lessonInfoContainer); } } else { // FixMe: chart size dirty hack GM_addStyle ( ` canvas { width:900px !important; height:600px !important; } .pt-4 { padding-top: 3.5rem!important; } #student-dashboard .homework-table { background-image: url(https://7355608.fun/images/board2.png)!important; } ` ); let pwndLogo = 'https://7355608.fun/images/glitch_logo.gif'; document.querySelector('#site_logo').src=pwndLogo; let pwndTeacher = `https://7355608.fun/images/teacher${Math.floor(Math.random() * 5) + 1}.png`; document.querySelector('.teacher').src=pwndTeacher; // Shuffle Text window.addEventListener('load', init); function init() { var effectList = []; var elementList1 = [document.querySelector("#navbarSupportedContent span")]; var elementList2 = []; var elementList = elementList1.concat(elementList2); for (var i = 0; i < elementList.length; i++) { var element = elementList[i]; element.dataset.index = i; effectList[i] = new ShuffleText(element); element.addEventListener('mouseenter', function () { effectList[+this.dataset.index].start(); }); element.addEventListener('mouseleave', function () { effectList[+this.dataset.index].start(); }); effectList[i].start(); } } let colors = [{ main: 'rgb(255, 99, 132)', light: 'rgb(255, 99, 132, 0.2)' },{ main: 'rgb(75, 192, 192)', light: 'rgb(75, 192, 192, 0.2)' },{ main: 'rgb(255, 205, 86)', light: 'rgb(255, 205, 86, 0.2)' }]; const x = []; Object.entries(o2c.page.completedTests.data).forEach(([key, value]) => { console.log(`${key}: ${value.id}`) console.log(`${key}: ${value.assigned_on}`) console.log(`${key}: ${value.isCompleted}`) const xxx = fetch(`https://${window.location.hostname}/student/placement/${value.id}/result`) .then(function(response) { // When the page is loaded convert it to text return response.text() }) .then(function(html) { // Initialize the DOM parser let parser = new DOMParser(); // Parse the text let doc = parser.parseFromString(html, "text/html"); // You can now even select part of that html as you would in the regular DOM let parsed = doc.querySelectorAll('script')[4]; parsed = parsed.innerText; let parsedStats = parsed.split('o2c.page')[4]; parsedStats = parsedStats.split('.stats = ')[1]; parsedStats = parsedStats.slice(0, -10); parsedStats = JSON.parse(parsedStats); console.log(parsedStats["grading-1"]); let datasetTemplate = { label: '', data: [], fill: true, backgroundColor: colors[key].light, borderColor: colors[key].main, pointBackgroundColor: colors[key].main, pointBorderColor: '#fff', pointHoverBackgroundColor: '#fff', pointHoverBorderColor: colors[key].main, }; let score = ''; Object.entries(parsedStats["grading-1"]).forEach(([key, value]) => { console.log(`${key}: ${value.correct}`); score = `${score} ${grading('grade', key)}:${grading('score', value.correct)}`; datasetTemplate.data.push(parseInt(value.correct)); }); let parsedLevel = parsed.split('o2c.page')[6]; parsedLevel = parsedLevel.split('.proficiency = ')[1]; parsedLevel = parsedLevel.slice(0, -10); parsedLevel = JSON.parse(parsedLevel); let label = `${parsedLevel.name} ${parsedLevel.shortName} (${value.assigned_on})`; console.log(`${label}`); // Updating "PLACEMENT TEST RESULTS" dashboard let placementTestData = `${value.assigned_on.split(" ")[1]} ${value.assigned_on.split(" ")[0]}th`; let cells = document.querySelectorAll("#completedTests table td"); cells.forEach(function(item, index, arr) { if (item.innerText == placementTestData) { arr[index-1].innerHTML = `📚 ${parsedLevel.shortName}: ${score}`; } }); // datasetTemplate.label = label; return datasetTemplate }) .catch(function(err) { console.log('Failed to fetch page: ', err); }); x.push(xxx) }); Promise.all(x).then(datasets => { datasets.reverse(); console.log(datasets); // FixMe: add optional chart by click // block = document.querySelector("div.teacher-image-box"); // container = createChart(block); var popCanvas = document.getElementById("popChart"); var barChart = new Chart(popCanvas, { type: 'bar', data: { labels: ["A1", "A2", "B1", "B2", "C1"], datasets: datasets, }, options: { elements: { line: { borderWidth: 3, } } } }); }); let block = document.querySelector("#navbarSupportedContent"); let container = createDiv(block); startTime(); //fixed size of blocks let div = document.getElementsByClassName('col-md-2 col-lg-2')[0]; div.classList.remove("col-md-2", "col-lg-2"); div.classList.add("col-md-3", "col-lg-3"); div = document.getElementsByClassName('col-12 col-sm-12 col-md-10 col-lg-10')[0]; div.classList.remove("col-12", "col-sm-12", "col-md-10", "col-lg-10"); div.classList.add("col-9", "col-sm-9", "col-md-9", "col-lg-9"); } })(); function createDiv(container) { let newDiv = document.createElement("div"); newDiv.id = "clock"; insertAfter(newDiv, container); return newDiv; } function createChart(container) { let newCanvas = document.createElement("canvas"); newCanvas.id = "popChart"; insertAfter(newCanvas, container); return newCanvas; } function createLessonInfo(container) { var newDiv = document.createElement("div"); newDiv.id = "knowledge"; newDiv.setAttribute("style", "position: absolute; top: 25px; left: 200px; width: max-content;"); insertAfter(newDiv, container); return newDiv; } function addElement(key, value, container) { let newEl; if (key === 'title') { newEl = document.createElement("p"); newEl.className = "homework-header"; newEl.setAttribute("style", "margin-bottom: 0.5em;"); newEl.innerHTML = `<br><b> ${value} </b>`; } else if (key === 'gif') { newEl = document.createElement("img"); newEl.src = value; } else { newEl = document.createElement("p"); newEl.setAttribute("style", "margin-bottom: 0.5em;"); newEl.innerHTML = `${value}`; } container.appendChild(newEl); } function insertAfter(newNode, existingNode) { existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling); } function enableCopy() { let allowText = function(e){ e.stopImmediatePropagation(); return true; }; document.addEventListener('copy', allowText, true); document.addEventListener('cut', allowText, true); } function startTime() { var h1,h2,m1,m2; var today = new Date(); var h = today.getHours(); var m = today.getMinutes(); h1 = Math.trunc(h/10); h2 = h%10; m1 = Math.trunc(m/10); m2 = m%10; document.getElementById('clock').innerHTML = '<img src="https://7355608.fun/images/'+h1+'.gif" alt="'+h1+'" width="20%" border="0">'+ '<img src="https://7355608.fun/images/'+h2+'.gif" alt="'+h2+'" width="20%" border="0">'+ ' : '+ '<img src="https://7355608.fun/images/'+m1+'.gif" alt="'+m1+'" width="20%" border="0">'+ '<img src="https://7355608.fun/images/'+m2+'.gif" alt="'+m2+'" width="20%" border="0">'; var t = setTimeout(startTime, 10000); } function diffDate(dueDate, nowDate, text) { const dateNow = nowDate; const dateFuture = new Date(dueDate); if (dateNow > dateFuture) { return `${text} closed` } let diffInMilliSeconds = Math.abs(dateFuture - dateNow) / 1000; // calculate days const days = Math.floor(diffInMilliSeconds / 86400); diffInMilliSeconds -= days * 86400; console.log('Days', days); // calculate hours const hours = Math.floor(diffInMilliSeconds / 3600) % 24; diffInMilliSeconds -= hours * 3600; console.log('Hours', hours); // calculate minutes const minutes = Math.floor(diffInMilliSeconds / 60) % 60; diffInMilliSeconds -= minutes * 60; console.log('Minutes', minutes); return `${text} ${days} days ${hours} hours ${minutes} minutes`; } function grading(type, text) { console.log(`grading: type=${type} | text=${text}`); if (type == 'grade') { switch (text) { case '10': return '<b>A1</b>'; break; case '20': return '<b>A2</b>'; break; case '30': return '<b>B1</b>'; break; case '50': return '<b>B2</b>'; break; case '60': return '<b>C1</b>'; break; default: return text } } else if (type == 'score') { if (text <= 10) { return `<b><font color="red">${text}</font></b>` } else if (text <= 15) { return `<b><font color="orange">${text}</font></b>` } else if (text > 15) { return `<b><font color="green">${text}</font></b>` } else { return text } } }