diff --git a/.gitignore b/.gitignore index 5302287..daf8285 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,13 @@ npm-debug.log dist/ packages/ -extension + +src/components.d.ts +extension/manifest.json + +*.crx +*.local +*.log +*.pem +*.xpi +*.zip diff --git a/src/assets/error.svg b/extension/assets/error.svg similarity index 100% rename from src/assets/error.svg rename to extension/assets/error.svg diff --git a/src/assets/icon-128.png b/extension/assets/icon-128.png similarity index 100% rename from src/assets/icon-128.png rename to extension/assets/icon-128.png diff --git a/src/assets/icon-16.png b/extension/assets/icon-16.png similarity index 100% rename from src/assets/icon-16.png rename to extension/assets/icon-16.png diff --git a/src/assets/icon-19.png b/extension/assets/icon-19.png similarity index 100% rename from src/assets/icon-19.png rename to extension/assets/icon-19.png diff --git a/src/assets/icon-38.png b/extension/assets/icon-38.png similarity index 100% rename from src/assets/icon-38.png rename to extension/assets/icon-38.png diff --git a/src/assets/loading.svg b/extension/assets/loading.svg similarity index 100% rename from src/assets/loading.svg rename to extension/assets/loading.svg diff --git a/src/assets/logo-white.svg b/extension/assets/logo-white.svg similarity index 100% rename from src/assets/logo-white.svg rename to extension/assets/logo-white.svg diff --git a/src/assets/logo.svg b/extension/assets/logo.svg similarity index 100% rename from src/assets/logo.svg rename to extension/assets/logo.svg diff --git a/src/assets/refresh.png b/extension/assets/refresh.png similarity index 100% rename from src/assets/refresh.png rename to extension/assets/refresh.png diff --git a/src/assets/refresh_small.png b/extension/assets/refresh_small.png similarity index 100% rename from src/assets/refresh_small.png rename to extension/assets/refresh_small.png diff --git a/src/assets/ring.gif b/extension/assets/ring.gif similarity index 100% rename from src/assets/ring.gif rename to extension/assets/ring.gif diff --git a/extension/pages/iframe.html b/extension/pages/iframe.html new file mode 100644 index 0000000..5fd1061 --- /dev/null +++ b/extension/pages/iframe.html @@ -0,0 +1,9 @@ + + +
+ + + + Next Storage + + diff --git a/src/pages/matricula/corte.html b/extension/pages/matricula/corte.html similarity index 100% rename from src/pages/matricula/corte.html rename to extension/pages/matricula/corte.html diff --git a/src/pages/matricula/fragments/matriculasNumber.html b/extension/pages/matricula/fragments/matriculasNumber.html similarity index 100% rename from src/pages/matricula/fragments/matriculasNumber.html rename to extension/pages/matricula/fragments/matriculasNumber.html diff --git a/src/pages/matricula/fragments/professorPopover.html b/extension/pages/matricula/fragments/professorPopover.html similarity index 100% rename from src/pages/matricula/fragments/professorPopover.html rename to extension/pages/matricula/fragments/professorPopover.html diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..80340b5 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/*": ["src/*"] + } + }, + "include": ["src/**/*.js"], + "exclude": ["node_modules", "**/node_modules", "dist"] +} diff --git a/package.json b/package.json index 1d85dec..3d3f2eb 100644 --- a/package.json +++ b/package.json @@ -5,21 +5,19 @@ "type": "module", "description": "Adiciona funcionalidades novas ao sistema de matricula da UFABC", "scripts": { - "dev": "rimraf extension/dev && run-p dev:*", - "dev:prepare": "node --no-warnings=ExperimentalWarning tasks/prepare.dev.js dev", + "dev": "yarn clear && NODE_ENV=dev run-p dev:*", + "dev:prepare": "node tasks/prepare.js", + "dev:background": "yarn build:background --mode dev", "dev:web": "vite", - "dev:js": "yarn run build:dev --watch src", - "build": "NODE_ENV=prod run-s clear build:web build:prepare build:prod", - "build:prepare": "node tasks/prepare.prod.js build", + "dev:js": "yarn run build:js --mode dev", + "dev:general": "yarn run build:general --mode dev", + "build": "NODE_ENV=prod run-s clear build:web build:prepare build:background build:js", + "build:prepare": "node tasks/prepare.js", + "build:background": "vite build --config vite.config.background.js", "build:web": "vite build", - "build:dev": "tsup --onSuccess 'node --no-warnings=ExperimentalWarning tasks/mvsw.dev.js'", - "build:prod": "tsup --onSuccess 'node --no-warnings=ExperimentalWarning tasks/mvsw.prod.js'", - "clear": "rimraf extension/prod" - }, - "standard": { - "globals": [ - "chrome" - ] + "build:js": "vite build --config vite.config.content.js", + "build:general": "vite build --config vite.config.files.js", + "clear": "rimraf --glob extension/dist extension/manifest.json extension.*" }, "devDependencies": { "@vitejs/plugin-vue2": "^2.3.1", @@ -27,8 +25,9 @@ "fs-extra": "^11.2.0", "kolorist": "^1.8.0", "npm-run-all": "^4.1.5", + "prettier": "^3.2.5", "rimraf": "^5.0.5", - "tsup": "^8.0.1", + "unplugin-vue-components": "^0.26.0", "vite": "^5.1.1" }, "dependencies": { diff --git a/prettier.config.js b/prettier.config.js new file mode 100644 index 0000000..7b4e4e3 --- /dev/null +++ b/prettier.config.js @@ -0,0 +1,8 @@ +export default { + printWidth: 80, + tabWidth: 2, + singleQuote: false, + trailingComma: "all", + arrowParens: "always", + semi: true, +}; diff --git a/src/lib/init.cjs b/src/lib/init.cjs index 1d6267c..cafad90 100644 --- a/src/lib/init.cjs +++ b/src/lib/init.cjs @@ -1,6 +1,6 @@ -import { extensionUtils } from "../utils/extensionUtils"; +import { extensionUtils } from "@/utils/extensionUtils"; -xdLocalStorage.init({ +window.xdLocalStorage.init({ /* required */ iframeUrl: extensionUtils.extensionURL("pages/iframe.html"), //an option function to be called right after the iframe was loaded and ready for action diff --git a/src/manifest.js b/src/manifest.js index 491adb0..cbf1a4a 100644 --- a/src/manifest.js +++ b/src/manifest.js @@ -1,6 +1,5 @@ import pkg from "../package.json" with { type: "json" }; - -const isDev = process.env.NODE_ENV !== "prod"; +import { isDev, PORT } from "../tasks/utils.js"; export async function getManifest() { // update this file to update this manifest.json @@ -11,11 +10,11 @@ export async function getManifest() { version: pkg.version, description: pkg.description, icons: { - 16: "./assets/icon-16.png", - 128: "./assets/icon-128.png", + 16: "assets/icon-16.png", + 128: "assets/icon-128.png", }, background: { - service_worker: "background.js", + service_worker: "dist/background/background.mjs", }, permissions: ["storage"], host_permissions: [ @@ -28,7 +27,7 @@ export async function getManifest() { content_scripts: [ { all_frames: true, - js: ["contentscript.js"], + js: ["dist/contentScripts/contentscript.global.js"], matches: [ "http://*.ufabc.edu.br/*", "https://*.ufabc.edu.br/*", @@ -55,24 +54,20 @@ export async function getManifest() { 38: "assets/icon-38.png", }, default_title: "Next Extension", - default_popup: "./views/Popup/index.html", + default_popup: "dist/views/Popup/index.html", }, content_security_policy: { - extension_pages: "script-src 'self'; object-src 'self'", + extension_pages: isDev + ? `script-src 'self' http://localhost:${PORT}; object-src 'self'` + : "script-src 'self'; object-src 'self'", }, web_accessible_resources: [ { resources: [ - "components/*", "assets/*", - "lib/*", "pages/*", - "scripts/*", - "services/*", - "styles/*", - "utils/*", - "views/*", - "html/*", + "dist/contentScripts/style.css", + "dist/lib/*", ], matches: [ "http://*.ufabc.edu.br/*", @@ -85,11 +80,5 @@ export async function getManifest() { ], }; - if (isDev) { - manifest.content_security_policy = { - extension_pages: `script-src 'self' http://localhost:${5001}; object-src 'self'`, - }; - } - return manifest; } diff --git a/src/pages/iframe.html b/src/pages/iframe.html deleted file mode 100644 index fede243..0000000 --- a/src/pages/iframe.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - Next Storage - - diff --git a/src/scripts/contentScriptPortal.js b/src/scripts/contentScriptPortal.js index dd90b4e..1011180 100644 --- a/src/scripts/contentScriptPortal.js +++ b/src/scripts/contentScriptPortal.js @@ -1,21 +1,21 @@ -import toastr from "toastr"; +import "@/styles/portal.css"; + import $ from "jquery"; import _ from "lodash"; -import { extensionUtils } from "../utils/extensionUtils"; -import { NextAPI } from "../services/NextAPI"; -import { NextStorage } from "../services/NextStorage"; import Axios from "axios"; +import toastr from "toastr"; import Toastify from "toastify-js"; -const getURL = chrome.runtime.getURL ?? ((path) => path); - -const nextApi = new NextAPI().init(); +import { extensionUtils } from "@/utils/extensionUtils"; +import { NextAPI } from "@/services/NextAPI"; +import { NextStorage } from "@/services/NextStorage"; +const getURL = chrome.runtime.getURL ?? ((path) => path); const toast = new Toastify({ text: `Atualizando suas informações...
\n\n NÃO SAIA DESSA PÁGINA, @@ -33,6 +33,8 @@ const toast = new Toastify({ }, }); +const nextApi = new NextAPI().init(); + const basePortalAlunoURL = new URL(document.location.href); const isPortalAluno = basePortalAlunoURL.pathname === "/dados_pessoais"; const isFichasIndividuais = @@ -44,37 +46,42 @@ if (isPortalAluno) { anchor.setAttribute("id", "app"); document.body.append(anchor); - extensionUtils.injectStyle("styles/portal.css"); + extensionUtils.injectStyle("dist/contentScripts/style.css"); toastr.info( - "Clique em Ficha Individual para atualizar suas informações!" + "Clique em Ficha Individual para atualizar suas informações!", ); } else if (isFichasIndividuais) { - extensionUtils.injectStyle("styles/portal.css"); - + extensionUtils.injectStyle("dist/contentScripts/style.css"); toast.showToast(); iterateTabelaCursosAndSaveToLocalStorage(); } else if (isStudentFicha) { - extensionUtils.injectStyle("styles/portal.css"); + extensionUtils.injectStyle("dist/contentScripts/style.css"); } function iterateTabelaCursosAndSaveToLocalStorage() { - var tabelaCursos = $("tbody").children().slice(1); + const tabelaCursos = $("tbody").children().slice(1); let count = 0; tabelaCursos.each(async function () { - var linhaCurso = $(this).children(); + const linhaCurso = $(this).children(); + + const coursename = $(linhaCurso[0]).children("a").text(); + const fichaAlunoURL = $(linhaCurso[1]).children("a").attr("href"); + const gradeYear = $(linhaCurso[2]).text(); - var nomeDoCurso = $(linhaCurso[0]).children("a").text(); - var fichaAlunoUrl = $(linhaCurso[1]).children("a").attr("href"); - var anoDaGrade = $(linhaCurso[2]).text(); + const curso = await getFichaAluno(fichaAlunoURL, coursename, fichaAlunoURL); + console.log(curso); + if (count === 0) { + toast.hideToast(); + } - const curso = await getFichaAluno(fichaAlunoUrl, nomeDoCurso, anoDaGrade); - if (count == 0) toast.hideToast(); count++; - if (!curso) return; + if (!curso) { + return; + } curso.curso = linhaCurso[0].innerText.replace("Novo", ""); curso.turno = linhaCurso[3].innerText; @@ -86,92 +93,96 @@ function iterateTabelaCursosAndSaveToLocalStorage() { } async function getFichaAluno(fichaAlunoUrl, nomeDoCurso, anoDaGrade) { + const STUDENT_FICHA_TIMEOUT = 60 * 1000; try { - var curso = {}; - var ficha_url = fichaAlunoUrl.replace(".json", ""); + const curso = {}; + const ficha_url = fichaAlunoUrl.replace(".json", ""); - const ficha = await Axios.get("https://aluno.ufabc.edu.br" + ficha_url, { - timeout: 60 * 1 * 1000, // 1 minute - }); - const ficha_obj = $($.parseHTML(ficha.data)); - const info = ficha_obj.find(".coeficientes tbody tr td"); + const { data: ficha } = await Axios.get( + `https://aluno.ufabc.edu.br${ficha_url}`, + { + timeout: STUDENT_FICHA_TIMEOUT, + }, + ); + + const parsedStudentFicha = $($.parseHTML(ficha)); + + const info = parsedStudentFicha.find(".coeficientes tbody tr td"); + const rawStudentCourseAndRa = parsedStudentFicha + .find("#page") + .children("p")[2].innerText; - const ra = - /.*?(\d+).*/g.exec( - ficha_obj.find("#page").children("p")[2].innerText - )[1] || "some ra"; + const [, ra] = /.*?(\d+).*/g.exec(rawStudentCourseAndRa); - const storageRA = "ufabc-extension-ra-" + getEmailAluno(); + const storageRA = `ufabc-extension-ra-${emailAluno()}`; await NextStorage.setItem(storageRA, ra); - const jsonFicha = await Axios.get( - "https://aluno.ufabc.edu.br" + fichaAlunoUrl, + const { data: jsonFicha } = await Axios.get( + `https://aluno.ufabc.edu.br${fichaAlunoUrl}`, { - timeout: 60 * 1 * 1000, // 1 minute - } + timeout: STUDENT_FICHA_TIMEOUT, + }, ); - const disciplinasCategory = ficha_obj.find( - ".quantidades:last-child tbody tr td" + const disciplinasCategory = parsedStudentFicha.find( + ".quantidades:last-child tbody tr td", ); // free const totalCreditsCoursedFree = toNumber(disciplinasCategory[2]); const totalPercentageCoursedFree = toNumber(disciplinasCategory[3]); const totalCreditsFree = Math.round( - (totalCreditsCoursedFree * 100) / totalPercentageCoursedFree + (totalCreditsCoursedFree * 100) / totalPercentageCoursedFree, ); // mandatory const totalCreditsCoursedMandatory = toNumber(disciplinasCategory[7]); const totalPercentageCoursedMandatory = toNumber(disciplinasCategory[8]); const totalCreditsMandatory = Math.round( - (totalCreditsCoursedMandatory * 100) / totalPercentageCoursedMandatory + (totalCreditsCoursedMandatory * 100) / totalPercentageCoursedMandatory, ); // limited const totalCreditsCoursedLimited = toNumber(disciplinasCategory[12]); const totalPercentageCoursedLimited = toNumber(disciplinasCategory[13]); const totalCreditsLimited = Math.round( - (totalCreditsCoursedLimited * 100) / totalPercentageCoursedLimited + (totalCreditsCoursedLimited * 100) / totalPercentageCoursedLimited, ); - await nextApi.post( - "/histories", - { - ra: ra, - disciplinas: jsonFicha.data, - curso: nomeDoCurso, - grade: anoDaGrade, - - // credits total - mandatory_credits_number: totalCreditsMandatory, - limited_credits_number: totalCreditsLimited, - free_credits_number: totalCreditsFree, - credits_total: - totalCreditsMandatory + totalCreditsLimited + totalCreditsFree, - }, - { - timeout: 60 * 1 * 1000, // 1 minute - } - ); + const userHistory = { + ra, + disciplinas: jsonFicha, + curso: nomeDoCurso, + grade: anoDaGrade, + + // credits total + mandatory_credits_number: totalCreditsMandatory, + limited_credits_number: totalCreditsLimited, + free_credits_number: totalCreditsFree, + credits_total: + totalCreditsMandatory + totalCreditsLimited + totalCreditsFree, + }; + + await nextApi.post("/histories", userHistory, { + timeout: STUDENT_FICHA_TIMEOUT, + }); curso.ra = ra; curso.cp = toNumber(info[0]); curso.cr = toNumber(info[1]); curso.ca = toNumber(info[2]); - curso.quads = ficha_obj.find(".ano_periodo").length; + curso.quads = parsedStudentFicha.find(".ano_periodo").length; - curso.cursadas = jsonFicha.data; + curso.cursadas = jsonFicha; return curso; } catch (err) { - console.log(err); + console.error("some bad happened", err); Toastify({ text: `