diff --git a/app/fonts/.gitkeep b/app/fonts/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/app/fonts/FontAwesome.otf b/app/fonts/FontAwesome.otf deleted file mode 100644 index d4de13e..0000000 Binary files a/app/fonts/FontAwesome.otf and /dev/null differ diff --git a/app/fonts/fontawesome-webfont.eot b/app/fonts/fontawesome-webfont.eot deleted file mode 100644 index c7b00d2..0000000 Binary files a/app/fonts/fontawesome-webfont.eot and /dev/null differ diff --git a/app/fonts/fontawesome-webfont.svg b/app/fonts/fontawesome-webfont.svg deleted file mode 100644 index 8b66187..0000000 --- a/app/fonts/fontawesome-webfont.svg +++ /dev/null @@ -1,685 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/fonts/fontawesome-webfont.ttf b/app/fonts/fontawesome-webfont.ttf deleted file mode 100644 index f221e50..0000000 Binary files a/app/fonts/fontawesome-webfont.ttf and /dev/null differ diff --git a/app/fonts/fontawesome-webfont.woff b/app/fonts/fontawesome-webfont.woff deleted file mode 100644 index 6e7483c..0000000 Binary files a/app/fonts/fontawesome-webfont.woff and /dev/null differ diff --git a/app/fonts/fontawesome-webfont.woff2 b/app/fonts/fontawesome-webfont.woff2 deleted file mode 100644 index 7eb74fd..0000000 Binary files a/app/fonts/fontawesome-webfont.woff2 and /dev/null differ diff --git a/app/pages/iframe.html b/app/pages/iframe.html deleted file mode 100644 index cfb0f69..0000000 --- a/app/pages/iframe.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - UFABC Next Storage - - \ No newline at end of file diff --git a/app/scripts/components/SubjectTeachersList/index.vue b/app/scripts/components/SubjectTeachersList/index.vue deleted file mode 100644 index c65580b..0000000 --- a/app/scripts/components/SubjectTeachersList/index.vue +++ /dev/null @@ -1,260 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js deleted file mode 100644 index 61a37a6..0000000 --- a/app/scripts/contentscript.js +++ /dev/null @@ -1,105 +0,0 @@ -// https://crx.dam.io/ext/gphjopenfpnlnffmhhhhdiecgdcopmhk.html -// add extension id to window -const isBrowser = typeof chrome != "undefined" && !!chrome.storage -// var script = document.createElement('script'); -// const extension_id = isBrowser ? chrome.i18n.getMessage("@@extension_id") : null; -// script.innerHTML = `extension_id = "${extension_id}"`; -// (document.head || document.documentElement).appendChild(script) - -import $ from 'jquery' -import Utils from './helpers/utils' -import MatriculaHelper from './helpers/matricula' - -import _ from 'lodash' - -// CSS imports -import "element-ui/lib/theme-chalk/index.css" -import setupStorage from './helpers/setupStorage' - -let matricula_url - -if (process.env.NODE_ENV == 'production') { - matricula_url = [ - 'matricula.ufabc.edu.br/matricula', - 'ufabc-matricula.cdd.naoseiprogramar.com.br/snapshot', - 'api.ufabcnext.com/snapshot', - ] -} else { - matricula_url = [ - 'matricula.ufabc.edu.br/matricula', - 'api.ufabcnext.com/snapshot', - 'api.ufabcnext.com/snapshot/backup.html', - 'ufabc-matricula.cdd.naoseiprogramar.com.br/snapshot', - 'ufabc-matricula.cdd.naoseiprogramar.com.br/snapshot/backup.html', - 'ufabc-matricula-test.cdd.naoseiprogramar.com.br/snapshot', - 'ufabc-matricula-test.cdd.naoseiprogramar.com.br/snapshot/backup.html', - 'locahost:8011/snapshot', - 'locahost:8011/snapshot/backup.html' - ] -} - -if(!isBrowser) { - console.log('Not running on browser!') - load() -} else { - window.addEventListener('load', load) -} - -async function load() { - const currentUrl = document.location.href; - - // add cross-domain local storage - Utils.injectScript('scripts/lib/xdLocalStorage.min.js') - Utils.injectIframe('pages/iframe.html') - Utils.injectScript('scripts/lib/init.js') - - setupStorage() - require('./portal/portal') - - if(matricula_url.some(url => currentUrl.indexOf(url) != -1)) { - // update teachers locally - setTimeout(async () => { - let lastUpdate = null - try { - lastUpdate = await Utils.storage.getItem('ufabc-extension-last') - } catch (err) { - lastUpdate = Date.now() - } finally { - MatriculaHelper.updateProfessors(lastUpdate) - } - - // this is the main vue app - // i.e, where all the filters live - const anchor = document.createElement('div') - anchor.setAttribute('id', 'app') - $('#meio').prepend(anchor) - - //inject styles - Utils.injectStyle('styles/main.css') - - // manda as informacoes para o servidor - MatriculaHelper.sendAlunoData() - - // load vue app modal - const modal = document.createElement('div') - modal.setAttribute('id', 'modal') - modal.setAttribute('data-app', true); - document.body.append(modal) - - // load vue app teacherReview - const teacherReview = document.createElement('div') - teacherReview.setAttribute('id', 'teacherReview') - teacherReview.setAttribute('data-app', true); - document.body.append(teacherReview) - - // load vue app review subjects - const reviewSubject = document.createElement('div') - reviewSubject.setAttribute('id', 'review-subject') - reviewSubject.setAttribute('data-app', true); - document.body.append(reviewSubject) - - // inject Vue app - Utils.injectScript('scripts/main.js') - }, 1500) - } -} \ No newline at end of file diff --git a/app/scripts/helpers/api.js b/app/scripts/helpers/api.js deleted file mode 100644 index 6830fd5..0000000 --- a/app/scripts/helpers/api.js +++ /dev/null @@ -1,32 +0,0 @@ -import Axios from 'axios' - -module.exports = new Api() - -function resolveEndpoint(env) { - return { - 'development' : 'http://localhost:8011/v1', - 'staging' : 'https://ufabc-matricula-test.cdd.naoseiprogramar.com.br/v1', - 'production' : 'https://api.ufabcnext.com/v1' - }[env] || 'http://localhost:8011/v1' -} -function Api() { - - this.baseURL = resolveEndpoint(process.env.NODE_ENV) - - this.axios = Axios.create({ - baseURL: this.baseURL, - timeout: 5000, - headers: { - 'Accept': 'application/json', - 'Content-Type': 'application/json' - }, - }) - - this.axios.interceptors.response.use(function (response) { - return response.data - }, function (error) { - return Promise.reject(_.get(error, 'response.data', error)) - }) - - return this.axios -} \ No newline at end of file diff --git a/app/scripts/helpers/disciplinas.js b/app/scripts/helpers/disciplinas.js deleted file mode 100644 index 72b3fd0..0000000 --- a/app/scripts/helpers/disciplinas.js +++ /dev/null @@ -1,114 +0,0 @@ -const _ = require('lodash') -const removeDiatrics = require('./removeDiacritics') - -// This convert an disciplina from the .json from matriculas.ufabc -module.exports = function convertDisciplina(d) { - const obj = _.defaults(_.clone(d)) - - // specific for .json - delete obj.campus - delete obj.turno - obj.obrigatorias = _.map(obj.obrigatoriedades, 'curso_id') - - let afterNoon = false - - // handler horarios based on pdf or json - if(obj.horarios && _.isObject(obj.horarios)) { - let startHours = _.get(obj.horarios, '[0].horas', []) - let afterNoon = ['14:00', '15:00', '16:00', '17:00'].some(hour => startHours.includes(hour)) - } else if(obj.horarios && _.isString(obj.horarios)) { - obj.horarios = removeLineBreaks(obj.horarios) - - const matched = obj.horarios.match(/\d{2}:\d{2}/g) - - // only match if is even - if(matched.length % 2 == 0) { - let hours = _.chunk(matched, 2) - hours.forEach(m => { - let [start, end] = m.map(h => parseInt(h.split(':')[0])) - - if(start >= 12 && start < 18) { - afterNoon = true - } - }) - } - } - - // trabalha nas disciplinas - // if(!obj.nome) return obj - - let turnoIndex = null - - let breakRule = '-' - - var splitted = removeLineBreaks(obj.nome).split(breakRule) - if(splitted.length == 1) { - breakRule = ' ' - splitted = splitted[0].split(/\s+/) - } - - splitted.map(function(item, i) { - obj.campus = obj.campus || extractCampus(item) - obj.turno = obj.turno || (afterNoon ? 'tarde' : extractTurno(item)) - - if((obj.turno || obj.campus) && turnoIndex == null) turnoIndex = i - }) - - if(!obj.campus) { - let secondPath = splitted.slice(turnoIndex + 1, splitted.length) - obj.campus = extractCampus(secondPath.join(breakRule)) - } - - // cut until the index we found - splitted = splitted.slice(0, turnoIndex) - - // separa a turma da disciplina - var disciplina = _.compact(splitted.join('-').split(/\s+/)) - obj.turma = disciplina[disciplina.length -1] - disciplina.pop() - - // fix disciplina - obj.disciplina = disciplina.join(' ').trim() - //obj.ideal_quad = app.helpers.season.findIdeais().includes(obj.codigo) - - obj.disciplina_id = obj.id - obj.codigo = obj.codigo - - return obj -} - -function cleanTeacher(str){ - return _.startCase(_.camelCase(str)) - .replace(/-+.*?-+/g, '') - .replace(/\(+.*?\)+/g, '') -} - -function removeLineBreaks(str = '') { - return str.replace(/\r?\n|\r/g, ' ') -} - -function extractTurno(d){ - const min = d.toLowerCase() - if(min.includes("diurno") || min.includes("matutino")) { - return "diurno" - } - - if(min.includes("noturno")) { - return "noturno" - } - - return null -} - -function extractCampus(d) { - const min = removeDiatrics(d.toLowerCase()) - if(/.*santo\s+andre.*/.test(min)) { - return "santo andre" - } - - if(/.*sao\s+bernardo.*/.test(min)) { - return "sao bernardo" - } - - return null -} \ No newline at end of file diff --git a/app/scripts/helpers/findSeason.js b/app/scripts/helpers/findSeason.js deleted file mode 100644 index 1cd3a4b..0000000 --- a/app/scripts/helpers/findSeason.js +++ /dev/null @@ -1,23 +0,0 @@ -function findQuadFromDate(month) { - if([0, 1, 2, 10, 11].includes(month)) return 1 - if([3, 4, 5].includes(month)) return 2 - if([6, 7, 8, 9].includes(month)) return 3 -} - -module.exports = function findSeason(date = new Date()) { - const month = date.getMonth() - return { - 1 : { - quad: 1, - year: date.getFullYear() + (month < 6 ? 0 : 1) - }, - 2 : { - quad: 2, - year: date.getFullYear() - }, - 3 : { - quad: 3, - year: date.getFullYear() - }, - }[findQuadFromDate(date.getMonth() || month)] -} \ No newline at end of file diff --git a/app/scripts/helpers/findSeasonKey.js b/app/scripts/helpers/findSeasonKey.js deleted file mode 100644 index 38f319c..0000000 --- a/app/scripts/helpers/findSeasonKey.js +++ /dev/null @@ -1,6 +0,0 @@ -const findSeason = require('./findSeason') - -module.exports = function findSeasonKey(date) { - const d = findSeason(date) - return d.year + ':' + d.quad -} \ No newline at end of file diff --git a/app/scripts/helpers/matricula.js b/app/scripts/helpers/matricula.js deleted file mode 100644 index a2f6dfc..0000000 --- a/app/scripts/helpers/matricula.js +++ /dev/null @@ -1,193 +0,0 @@ -import Axios from 'axios' -import Api from './api' -import var2json from './parse/var2json' -import _ from 'lodash' -import $ from 'jquery' -import Utils from './utils' - -module.exports = new Matricula() - -function Matricula() { - const MATRICULAS_URL = { - 'development' : 'http://localhost:8011/snapshot/assets/todasDisciplinas.js', - 'staging' : 'https://ufabc-matricula-test.cdd.naoseiprogramar.com.br/snapshot/assets/todasDisciplinas.js', - 'production' : 'https://matricula.ufabc.edu.br/cache/matriculas.js' - }[process.env.NODE_ENV] || 'http://localhost:8011/v1' - - // check if we need to update our localStorage of professors - // based when you did this last request - async function updateProfessors(data) { - let lastTime = data - let timeDiff = (Date.now() - lastTime) / (1000 * 60) - - await getProfessors() - if(!lastTime || timeDiff > 0.2) { - await getProfessors() - } - } - - // fetch professors url and save them into localStorage - async function getProfessors () { - try { - let professors = await Api.get('/disciplinas') - await Utils.storage.setItem('ufabc-extension-last', Date.now()) - await Utils.storage.setItem('ufabc-extension-disciplinas', professors) - return professors - } catch(e) { - console.log('❌ Erro ao atualizar disciplinas') - console.error(e) - } - } - - // disciplinas que mudaram de nome (HARDCODED) - var disciplinas_mudadas = { - "Energia: Origens, Conversão e Uso" : "Bases Conceituais da Energia", - "Transformações nos Seres Vivos e Ambiente" : "Biodiversidade: Interações entre organismos e ambiente", - "Transformações Bioquímicas" : "Bioquímica: estrutura, propriedade e funções de Biomoléculas", - "Transformações Bioquímicas" : "Bioquímica: Estrutura, Propriedade e Funções de Biomoléculas", - "Origem da Vida e Diversidade dos Seres Vivos" : "Evolução e Diversificação da Vida na Terra", - } - - function findQuadFromDate(month) { - if([0, 1, 2, 10, 11].includes(month)) return 3 - if([3, 4, 5].includes(month)) return 1 - if([6, 7, 8, 9].includes(month)) return 2 - } - - function findIdeais(date) { - return { - 1 : - [ - 'BCM0506-15', // COMUNICACAO E REDES - 'BCJ0203-15', // ELETROMAG - 'BIN0406-15', // IPE - 'BCN0405-15', // IEDO - 'BIR0004-15', // EPISTEMOLOGICAS - 'BHO0102-15', // DESENVOL. E SUSTE. - 'BHO0002-15', // PENSA. ECONOMICO - 'BHP0201-15', // TEMAS E PROBLEMAS - 'BHO0101-15', // ESTADO E RELA - 'BIR0603-15', // CTS - 'BHQ0003-15', // INTEPRE. BRASIL - 'BHQ0001-15', // IDENT.E CULTURA - ], - 2 : [ - 'BCM0504-15', // NI - 'BCN0404-15', // GA - 'BCN0402-15', // FUV - 'BCJ0204-15', // FEMEC - 'BCL0306-15', // BIODIVERSIDADE - 'BCK0103-15', // QUANTICA - 'BCL0308-15', // BIOQUIMICA - 'BIQ0602-15', // EDS - 'BHO1335-15', // FORMACAO SISTEMA INTERNACIONAL - 'BHO1101-15', // INTRODUCAO A ECONOMIA - 'BHO0001-15', // INTRODUCAO AS HUMANIDADES - 'BHP0202-15', // PENSAMENTO CRITICO - ], - 3 : [ - 'BCJ0205-15', // FETERM - 'BCM0505-15', // PI - 'BCN0407-15', // FVV - 'BCL0307-15', // TQ - 'BCK0104-15', // IAM - 'BIR0603-15', // CTS - 'BHP0001-15', // ETICA E JUSTICA - 'BHQ0301-15', // TERRITORIO E SOCIEDADE - // ESTUDO ÉTNICOS RACIAIS - ], - }[findQuadFromDate(date || new Date().getMonth())] - } - - // fetch matriculas again - async function getMatriculas() { - const disciplinas = await Axios.get(MATRICULAS_URL) - return var2json(disciplinas.data) || {} - } - - // get total number of matriculas that was made until now - async function getTotalMatriculas() { - return Object.keys(await getMatriculas()).length - } - - // get matriculas by aluno_id - async function getMatriculasAluno(aluno_id) { - const matriculas = await getMatriculas() - return _.get(matriculas, aluno_id) - } - - // get current logged student - function getAlunoId() { - let toReturn = null - - $('script').each(function () { - var inside = $(this).text(); - var test = "todasMatriculas"; - if (inside.indexOf(test) != -1) { - var regex = /matriculas\[(.*)\]/ - var match = regex.exec(inside) - toReturn = (parseInt(match[1])) - } - }) - - return toReturn - } - - // find courseId for this season - function findIdForCurso(name){ - if ( _.camelCase(name) == _.camelCase('Bacharelado em Ciências da Computação')) { - name = 'Bacharelado em Ciência da Computação' - } - // normalize to camelCase - name = _.camelCase(name) - - // check which row matches the name passed - const course = $("#curso").children().filter(function(i, item) { - return name == _.camelCase($(item).text()) - })[0] - - return $(course).val() - } - - function currentUser() { - return $('#usuario_top').text().replace(/\s*/, '').split('|')[0].trim().toLowerCase() - } - - // send aluno data - async function sendAlunoData () { - const storageUser = 'ufabc-extension-' + currentUser() - const storageRA = 'ufabc-extension-ra-' + currentUser() - const user = await Utils.storage.getItem(storageUser) - const ra = await Utils.storage.getItem(storageRA) - - if(!user) return - - // remove as disciplinas cursadas - for (var i = 0; i < user.length; i++) { - delete user[i].cursadas; - } - - await Api.post('/students', { - aluno_id: getAlunoId(), - cursos: user.map(function(info){ - info.curso_id = findIdForCurso(info.curso); - return info; - }), - ra: ra, - login: currentUser(), - }) - } - - return { - updateProfessors, - getProfessors, - getMatriculas, - getTotalMatriculas, - getMatriculasAluno, - getAlunoId, - findIdForCurso, - currentUser, - sendAlunoData, - findIdeais, - } -} \ No newline at end of file diff --git a/app/scripts/helpers/parse/identifier.js b/app/scripts/helpers/parse/identifier.js deleted file mode 100644 index e87bd74..0000000 --- a/app/scripts/helpers/parse/identifier.js +++ /dev/null @@ -1,23 +0,0 @@ -const _ = require('lodash') -const crypto = require('crypto') - -module.exports = function(disciplina, keys, silent = true) { - keys = keys || ['disciplina', 'turno', 'campus', 'turma'] - - let d = _(disciplina || {}) - .pick(keys) - .mapValues(String) - .mapValues(_.camelCase) - .toPairs() - .sortBy(0) - .fromPairs() - .values() - .value() - .join('') - - if(!silent) { - console.log(d) - } - - return crypto.createHash('md5').update(d).digest('hex') -} \ No newline at end of file diff --git a/app/scripts/helpers/parse/var2json.js b/app/scripts/helpers/parse/var2json.js deleted file mode 100644 index 2f2ad72..0000000 --- a/app/scripts/helpers/parse/var2json.js +++ /dev/null @@ -1,8 +0,0 @@ -import _ from 'lodash' - -module.exports = (payload, max) => { - let json = JSON.parse(_.get(new RegExp(/^\w*=(.*)\;/).exec(payload), '[1]', {})) - - if(max) return json.slice(0, max) - return json -} \ No newline at end of file diff --git a/app/scripts/helpers/pie.js b/app/scripts/helpers/pie.js deleted file mode 100644 index d5fa3af..0000000 --- a/app/scripts/helpers/pie.js +++ /dev/null @@ -1,59 +0,0 @@ -// import Chart from 'chart.js' - -module.exports = new (function (){ - function getHTML (info, id) { - var html = "
"; - html += "
CR Aluno" + info.cr_aluno + "
CR Professor" + info.cr_professor + "
Reprovacoes" + info.reprovacoes + "
Trancamentos" + info.trancamentos +"
"; - return html; - } - - function generate(item, id){ - var ctx = $("#pie" + id); - - var possible_colors = { - "A" : "rgb(124, 181, 236)", - "B" : "rgb(67, 67, 72)", - "C": "rgb(144, 237, 125)", - "D" : "rgb(247, 163, 92)" - }; - - var possible_hover = { - "A" : "rgb(149, 206, 255)", - "B" : "rgb(92, 92, 97)", - "C": "rgb(168, 255, 150)", - "D" : "rgb(255, 188, 117)" - }; - - var info = []; - var backColor = []; - var hoverColor = []; - var labels = []; - - for (var key in item) { - labels.push(key); - info.push(item[key]); - backColor.push(possible_colors[key]); - hoverColor.push(possible_hover[key]); - } - - var data = { - labels: labels, - datasets: [ - { - data: info, - backgroundColor: backColor, - hoverBackgroundColor: hoverColor - }] - }; - - // var myChart = new Chart(ctx, { - // type: 'pie', - // data: data - // }); - } - - return { - getHTML: getHTML, - generate: generate - } -})() \ No newline at end of file diff --git a/app/scripts/helpers/setupStorage.js b/app/scripts/helpers/setupStorage.js deleted file mode 100644 index 13677e7..0000000 --- a/app/scripts/helpers/setupStorage.js +++ /dev/null @@ -1,58 +0,0 @@ -module.exports = function setupStorage() { - document.addEventListener('requestStorage', (event) => { - const key = event.detail.key - const date = event.detail.date - const value = event.detail.value - const method = event.detail.method.split('-')[0] - const eventType = event.type - if(!key || !date || !method || eventType != 'requestStorage') return - - - const IS_BROWSER = typeof chrome != "undefined" && !!chrome.storage - const eventMethod = event.detail.method - if (IS_BROWSER) { - console.log(`[${method} | ${key}] Using chrome.storage 🔵`) - // maybe below is actually resolve(data && data[key]) - please check - - if(method == 'setStorage') { - chrome.storage.local.set({ [key]: value }) - return document.dispatchEvent(new CustomEvent(eventMethod, { - "detail": { - "key": key, - "value": value - } - })) - } else if(method == 'getStorage') { - return chrome.storage.local.get(key, (data) => { - document.dispatchEvent(new CustomEvent(eventMethod, { - "detail": { - "key": key, - "value": data && data[key] - } - })) - }) - } - } - - console.log(`[${method} | ${key}] Using xdLocalStorage 🔴`) - if(method == 'setStorage') { - window.xdLocalStorage.setItem(key, JSON.stringify(value), (data) => { - document.dispatchEvent(new CustomEvent(eventMethod, { - "detail": { - "key": key, - "value": date.value - } - })) - }) - } else if(method == 'getStorage') { - window.xdLocalStorage.getItem(key, (data) => { - document.dispatchEvent(new CustomEvent(eventMethod, { - "detail": { - "key": key, - "value": JSON.parse(data.value) - } - })) - }) - } - }) -} \ No newline at end of file diff --git a/app/scripts/helpers/utils.js b/app/scripts/helpers/utils.js deleted file mode 100644 index a55ee6c..0000000 --- a/app/scripts/helpers/utils.js +++ /dev/null @@ -1,162 +0,0 @@ -import $ from 'jquery' -import Axios from 'axios' -import is from 'is_js' -import xdLocalStorage from '../lib/xdLocalStorage.min.js' -import _ from 'lodash' - -module.exports = new (function (){ - // force initialization of xdLocalStorage - window.xdLocalStorage.init({ iframeUrl: getExtensionUrl('/pages/iframe.html')}) - - const IS_BROWSER = typeof chrome != "undefined" && !!chrome.storage - const EXTENSION_ID = IS_BROWSER ? chrome.i18n.getMessage("@@extension_id") : null - - var getChromeUrl = function (url) { - return getExtensionUrl(url); - }; - - var fetchChromeUrl = async function(url, cb) { - return Axios.get(getChromeUrl(url)) - } - - var injectDiv = async function(link, el) { - let resp = await fetchChromeUrl(link) - const data = resp.data - - var div = document.createElement('div'); - div.innerHTML = data; - - if(el) { - let parent = el.parentNode - parent.insertBefore(div, el.nextSibling) - } else { - document.body.appendChild(div) - } - } - - function getBrowser() { - // Opera 8.0+ - var isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; - - // Firefox 1.0+ - var isFirefox = typeof InstallTrigger !== 'undefined'; - - // Safari 3.0+ "[object HTMLElementConstructor]" - var isSafari = /constructor/i.test(window.HTMLElement) || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window['safari'] || safari.pushNotification); - - // Internet Explorer 6-11 - var isIE = /*@cc_on!@*/false || !!document.documentMode; - - // Edge 20+ - var isEdge = !isIE && !!window.StyleMedia; - - // Chrome 1+ - var isChrome = !!window.chrome && !!window.chrome.webstore; - - // Blink engine detection - var isBlink = (isChrome || isOpera) && !!window.CSS; - - var result = - isOpera ? 'opera' : - isFirefox ? 'firefox' : - isSafari ? 'safari' : - isChrome ? 'chrome' : - isIE ? 'ie' : - isEdge ? 'edge' : - isBlink ? 'blink' : - "Don't know"; - - return result - } - - var injectStyle = function(link) { - var s = document.createElement("link"); - s.href = getExtensionUrl(link); - s.type = "text/css"; - s.rel = "stylesheet"; - document.head.appendChild(s); - } - - var injectScript = function (link) { - var s = document.createElement('script'); - s.src = getExtensionUrl(link); - - (document.head || document.documentElement).appendChild(s); - } - - var injectIframe = function (link) { - var s = document.createElement('iframe'); - s.src = getExtensionUrl(link); - s.setAttribute('style', 'display: none;'); - (document.body || document.documentElement).appendChild(s); - } - - var storage = { - setItem(key, value) { - return new Promise((resolve, reject) => { - try { - const date = Date.now() - const event = new CustomEvent("requestStorage", { - "detail": { - "method": `setStorage-${key}-${date}`, - "date": date, - "key": key, - "value": value - } - }) - document.addEventListener(`setStorage-${key}-${date}`, (evt) => { - resolve(evt.detail.value) - }) - document.dispatchEvent(event) - } catch (err) { - console.error(err) - } - }) - }, - getItem(key) { - return new Promise((resolve, reject) => { - try { - const date = Date.now() - const event = new CustomEvent("requestStorage", { - "detail": { - "method": `getStorage-${key}-${date}`, - "key": key, - "date": date - } - }) - document.addEventListener(`getStorage-${key}-${date}`, (evt) => { - resolve(evt.detail.value) - }) - document.dispatchEvent(event) - } catch (err) { - console.error(err) - } - }) - } - } - - function getExtensionUrl(link){ - if(EXTENSION_ID) { - const prefix = is.chrome() ? 'chrome-extension://' : 'moz-extension://' - return prefix + EXTENSION_ID + '/' + link.replace(/^\//, '') - } else { - return 'https://next-extension.sv.ufabcnext.com/static/' + link.replace(/^\//, '') - } - } - - var getFile = async function (link) { - return (await Axios.get(getChromeUrl(link))).data - } - - return { - getChromeUrl: getChromeUrl, - injectScript: injectScript, - injectDiv: injectDiv, - injectIframe: injectIframe, - injectStyle: injectStyle, - fetchChromeUrl: fetchChromeUrl, - getExtensionUrl: getExtensionUrl, - getFile: getFile, - storage: storage, - } -})(); \ No newline at end of file diff --git a/app/scripts/lib/init.js b/app/scripts/lib/init.js deleted file mode 100644 index 9e54c55..0000000 --- a/app/scripts/lib/init.js +++ /dev/null @@ -1,13 +0,0 @@ -import Utils from '../helpers/utils' - -xdLocalStorage.init( - { - /* required */ - iframeUrl: Utils.getExtensionUrl('/pages/iframe.html'), - //an option function to be called right after the iframe was loaded and ready for action - initCallback: function () { - console.log(Utils.getExtensionUrl('')) - console.log('Got iframe ready'); - } - } -) \ No newline at end of file diff --git a/app/scripts/main.js b/app/scripts/main.js deleted file mode 100644 index e9011df..0000000 --- a/app/scripts/main.js +++ /dev/null @@ -1,99 +0,0 @@ -import Vue from 'vue'; -import Vuetify from 'vuetify' -import ElementUI from 'element-ui' -Vue.use(Vuetify) -Vue.use(ElementUI) - -import App from './matricula/App.vue' -import ReviewTeacher from './matricula/ReviewTeacher.vue' -import ReviewSubject from './matricula/ReviewSubject.vue' -import Modal from './matricula/Modal.vue' -import MatriculaHelper from './helpers/matricula' - -// global const change modal data -const modalData = { - corte_id: null, - dialog: false, - disciplina: null, -} - -const teacherReviewData = { - dialog: false, - professor: null, - // use this to notify - notifier: null -} - -const reviewSubjectData = { - dialog: false, - subject: null, - // use this to notify - notifier: null -} - - -var app = new Vue({ - el: '#app', - data:{ - name: 'ufabc-matricula-extension' - }, - render: h => h(App) -}) - -new Vue({ - template: '', - el: '#modal', - data() { - return modalData - }, - components: { Modal } -}) - -new Vue({ - template: '', - el: '#teacherReview', - data() { - return teacherReviewData - }, - components: { ReviewTeacher } -}) - -new Vue({ - template: '', - el: '#review-subject', - data() { - return reviewSubjectData - }, - components: { ReviewSubject } -}) - - -// handler cortes -$('body').on('click', '.corte', async function (e) { - var aluno_id = MatriculaHelper.getAlunoId() - var target = $(e.target); - var corte_id = target.parent().parent().attr('value'); - modalData.corte_id = corte_id - modalData.dialog = true -}) - -// handler teacherReview -$('body').on('click', '.ReviewTeacher', function (e) { - const teacherId = $(e.target).attr('data') - const teacherName = $(e.target).attr('teacherName') - teacherReviewData.professor = { - id: teacherId, - name: teacherName, - } - - teacherReviewData.dialog = true -}) - -// handler subject click -$('body').on('click', 'span.sa, span.sbc', function (e) { - const subjectId = $(e.target).attr('subjectId') - reviewSubjectData.subject = { - id: subjectId, - } - reviewSubjectData.dialog = true -}) \ No newline at end of file diff --git a/app/scripts/matricula/App.vue b/app/scripts/matricula/App.vue deleted file mode 100644 index 2e90fa5..0000000 --- a/app/scripts/matricula/App.vue +++ /dev/null @@ -1,300 +0,0 @@ - - - diff --git a/app/scripts/matricula/ReviewTeacher.vue b/app/scripts/matricula/ReviewTeacher.vue deleted file mode 100644 index 24efea5..0000000 --- a/app/scripts/matricula/ReviewTeacher.vue +++ /dev/null @@ -1,472 +0,0 @@ - - - \ No newline at end of file diff --git a/app/scripts/portal.js b/app/scripts/portal.js deleted file mode 100644 index ddc732f..0000000 --- a/app/scripts/portal.js +++ /dev/null @@ -1,14 +0,0 @@ -import Vue from 'vue'; -import Vuetify from 'vuetify' - -Vue.use(Vuetify) - -import App from './portal/App.vue'; - -var app = new Vue({ - el: '#app', - data:{ - name: 'portal-matricula-extension' - }, - render: h =>h(App) -}) \ No newline at end of file diff --git a/app/scripts/portal/App.vue b/app/scripts/portal/App.vue deleted file mode 100644 index f8ab6ec..0000000 --- a/app/scripts/portal/App.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - \ No newline at end of file diff --git a/app/scripts/portal/portal.js b/app/scripts/portal/portal.js deleted file mode 100644 index d0589e6..0000000 --- a/app/scripts/portal/portal.js +++ /dev/null @@ -1,231 +0,0 @@ -import toastr from 'toastr' -import $ from 'jquery' -import _ from 'lodash' -import Utils from '../helpers/utils' -import Api from '../helpers/api' -import Axios from 'axios' -import MatriculaHelper from '../helpers/matricula' -import findSeasonKey from '../helpers/findSeasonKey' -import Toastify from 'toastify-js' -import "toastify-js/src/toastify.css" -const loading = require('./loading.svg') -const errorSVG = require('./error.svg') -const logoWhite = require('./logo-white.svg') - -const toast = new Toastify({ - text: ` -
- -

Atualizando suas informações...

\n\n - NÃO SAIA DESSA PÁGINA, -

apenas aguarde, no máx. 5 min 🙏

-
`, - duration: -1, - close: false, - gravity: "bottom", - position: "right", - className: "toast-loading", - escapeMarkup: false, - avatar: loading, - style: { - background: "linear-gradient(to right, #2E7EED, rgba(46, 126, 237, 0.5));", - }, -}); - -if (isIndexPortalAluno()) { - const anchor = document.createElement('div') - anchor.setAttribute('id', 'app') - document.body.append(anchor) - Utils.injectScript('scripts/portal.js') - - Utils.injectStyle('styles/portal.css') - toastr.info("Clique em Ficha Individual para atualizar suas informações!"); -} else if (isFichasIndividuaisPath()) { - Utils.injectStyle('styles/portal.css'); - - toast.showToast(); - - iterateTabelaCursosAndSaveToLocalStorage(); -} else if (isFichaIndividualPath()) { - Utils.injectStyle('styles/portal.css'); -}; - -function isIndexPortalAluno () { - return document.location.href - .indexOf('aluno.ufabc.edu.br/dados_pessoais') !== -1; -} - -function isFichasIndividuaisPath () { - return document.location.href - .indexOf('aluno.ufabc.edu.br/fichas_individuais') !== -1; -} - -function isFichaIndividualPath () { - return document.location.href - .indexOf('aluno.ufabc.edu.br/ficha_individual') !== -1; -} - -function iterateTabelaCursosAndSaveToLocalStorage () { - var tabelaCursos = $('tbody').children().slice(1); - let count = 0 - - tabelaCursos.each(async function () { - var linhaCurso = $(this).children(); - - 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, nomeDoCurso, anoDaGrade) - if(count == 0) toast.hideToast() - count++ - - if(!curso) return - - curso.curso = linhaCurso[0].innerText.replace("Novo", ''); - curso.turno = linhaCurso[3].innerText; - - await saveToLocalStorage(curso); - - await saveStudentsToLocalStorage(curso); - }) -} - -async function getFichaAluno(fichaAlunoUrl, nomeDoCurso, anoDaGrade) { - try { - var curso = {}; - var 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 ra = /.*?(\d+).*/g.exec(ficha_obj.find("#page").children('p')[2].innerText)[1] || 'some ra'; - - const storageRA = 'ufabc-extension-ra-' + getEmailAluno() - await Utils.storage.setItem(storageRA, ra) - - const jsonFicha = await Axios.get('https://aluno.ufabc.edu.br' + fichaAlunoUrl, { - timeout: 60 * 1 * 1000 // 1 minute - }) - - const disciplinasCategory = ficha_obj.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) - - // mandatory - const totalCreditsCoursedMandatory = toNumber(disciplinasCategory[7]) - const totalPercentageCoursedMandatory = toNumber(disciplinasCategory[8]) - const totalCreditsMandatory = Math.round((totalCreditsCoursedMandatory * 100) / totalPercentageCoursedMandatory) - - // limited - const totalCreditsCoursedLimited = toNumber(disciplinasCategory[12]) - const totalPercentageCoursedLimited = toNumber(disciplinasCategory[13]) - const totalCreditsLimited = Math.round(((totalCreditsCoursedLimited * 100) / totalPercentageCoursedLimited)) - - await Api.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 - }) - - 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.cursadas = jsonFicha.data; - - return curso - } catch(err) { - console.log(err) - Toastify({ - text: - ` -
- - Não foi possível salvar seus dados, recarregue a página e aguarde. -
`, - duration: -1, - close: true, - gravity: "top", - position: "right", - className: "toast-error-container", - style: { - background: "#E74C3C;", - }, - }).showToast(); - } -} - - -function getEmailAluno() { - return $('#top li') - .last() - .text() - .replace(/\s*/,'') - .split('|')[0] - .replace(' ','') - .toLowerCase(); -} - -function toNumber(el) { - return parseFloat(el.innerText.replace(',', '.')); -} - -async function saveToLocalStorage(curso) { - const storageUser = 'ufabc-extension-' + getEmailAluno() - let user = await Utils.storage.getItem(storageUser) - if(!user || _.isEmpty(user)) user = [] - - user.push(curso) - user = _.uniqBy(user, 'curso') - - await Utils.storage.setItem(storageUser, user) - - toastr.success( - `Suas informações foram salvas! Disciplinas do curso do ${curso.curso} - para o usuário ${getEmailAluno()}., - `, - { timeout: 100000 } - ); - -} - - -async function saveStudentsToLocalStorage(curso) { - const storageUser = 'ufabc-extension-' + getEmailAluno() - const cursos = await Utils.storage.getItem(storageUser) - const ra = (curso && curso.ra) || null - - let allSavedStudents = [] - const students = await Utils.storage.getItem('ufabc-extension-students') - if(students && students.length) { - allSavedStudents.push(...students) - } - - allSavedStudents = allSavedStudents.filter(student => student.ra != ra) - const student = { - cursos: cursos, - ra: ra, - name: getEmailAluno(), - lastUpdate: Date.now() - } - allSavedStudents.unshift(student) - await Utils.storage.setItem('ufabc-extension-students', allSavedStudents) -} diff --git a/app/scripts/matricula/Modal.vue b/src/components/Modal.vue similarity index 92% rename from app/scripts/matricula/Modal.vue rename to src/components/Modal.vue index 72a85ea..1e3e29f 100644 --- a/app/scripts/matricula/Modal.vue +++ b/src/components/Modal.vue @@ -12,7 +12,7 @@
- Critérios + Critérios -
@@ -115,13 +115,14 @@ + diff --git a/src/components/SubjectTeachersList.vue b/src/components/SubjectTeachersList.vue new file mode 100644 index 0000000..dcd4399 --- /dev/null +++ b/src/components/SubjectTeachersList.vue @@ -0,0 +1,297 @@ + + + + diff --git a/app/scripts/portal/error.svg b/src/images/error.svg similarity index 100% rename from app/scripts/portal/error.svg rename to src/images/error.svg diff --git a/app/images/icon-128.png b/src/images/icon-128.png similarity index 100% rename from app/images/icon-128.png rename to src/images/icon-128.png diff --git a/app/images/icon-16.png b/src/images/icon-16.png similarity index 100% rename from app/images/icon-16.png rename to src/images/icon-16.png diff --git a/app/images/icon-19.png b/src/images/icon-19.png similarity index 100% rename from app/images/icon-19.png rename to src/images/icon-19.png diff --git a/app/images/icon-38.png b/src/images/icon-38.png similarity index 100% rename from app/images/icon-38.png rename to src/images/icon-38.png diff --git a/app/scripts/portal/loading.svg b/src/images/loading.svg similarity index 100% rename from app/scripts/portal/loading.svg rename to src/images/loading.svg diff --git a/app/scripts/portal/logo-white.svg b/src/images/logo-white.svg similarity index 100% rename from app/scripts/portal/logo-white.svg rename to src/images/logo-white.svg diff --git a/app/scripts/popup/logo.svg b/src/images/logo.svg similarity index 100% rename from app/scripts/popup/logo.svg rename to src/images/logo.svg diff --git a/app/images/refresh.png b/src/images/refresh.png similarity index 100% rename from app/images/refresh.png rename to src/images/refresh.png diff --git a/app/images/refresh_small.png b/src/images/refresh_small.png similarity index 100% rename from app/images/refresh_small.png rename to src/images/refresh_small.png diff --git a/app/images/ring.gif b/src/images/ring.gif similarity index 100% rename from app/images/ring.gif rename to src/images/ring.gif diff --git a/src/lib/init.js b/src/lib/init.js new file mode 100644 index 0000000..08eab28 --- /dev/null +++ b/src/lib/init.js @@ -0,0 +1,10 @@ +import Utils from "../utils/extensionUtils"; + +xdLocalStorage.init({ + /* required */ + iframeUrl: Utils.getExtensionUrl("pages/iframe.html"), + //an option function to be called right after the iframe was loaded and ready for action + initCallback: function () { + console.log("Got iframe ready"); + }, +}); diff --git a/app/scripts/lib/xdLocalStorage.min.js b/src/lib/xdLocalStorage.min.js similarity index 100% rename from app/scripts/lib/xdLocalStorage.min.js rename to src/lib/xdLocalStorage.min.js diff --git a/app/scripts/lib/xdLocalStoragePostMessageApi.min.js b/src/lib/xdLocalStoragePostMessageApi.min.js similarity index 100% rename from app/scripts/lib/xdLocalStoragePostMessageApi.min.js rename to src/lib/xdLocalStoragePostMessageApi.min.js diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..f2e8e39 --- /dev/null +++ b/src/main.js @@ -0,0 +1,98 @@ +import Vue from "vue"; +import Vuetify from "vuetify"; +import ElementUI from "element-ui"; +Vue.use(Vuetify); +Vue.use(ElementUI); + +import Matricula from "./views/Matricula.vue"; +import ReviewTeacher from "./components/ReviewTeacher.vue"; +import ReviewSubject from "./components/ReviewSubject.vue"; +import Modal from "./components/Modal.vue"; + +// global const change modal data +const modalData = { + corte_id: null, + dialog: false, + disciplina: null, +}; + +const teacherReviewData = { + dialog: false, + professor: null, + // use this to notify + notifier: null, +}; + +const reviewSubjectData = { + dialog: false, + subject: null, + // use this to notify + notifier: null, +}; + +var app = new Vue({ + el: "#app", + data: { + name: "ufabc-matricula-extension", + }, + render: (h) => h(Matricula), +}); + +new Vue({ + template: + '', + el: "#modal", + data() { + return modalData; + }, + components: { Modal }, +}); + +new Vue({ + template: + '', + el: "#teacherReview", + data() { + return teacherReviewData; + }, + components: { ReviewTeacher }, +}); + +new Vue({ + template: + '', + el: "#review-subject", + data() { + return reviewSubjectData; + }, + components: { ReviewSubject }, +}); + +// handler cortes +$("body").on("click", ".corte", async function (e) { + const target = $(e.target); + const corte_id = target.parent().parent().attr("value"); + modalData.corte_id = corte_id; + modalData.dialog = true; +}); + +// handler teacherReview +$("body").on("click", ".ReviewTeacher", function (e) { + const teacherId = $(e.target).attr("data"); + const teacherName = $(e.target).attr("teacherName"); + teacherReviewData.professor = { + id: teacherId, + name: teacherName, + }; + + teacherReviewData.dialog = true; +}); + +// handler subject click +$("body").on("click", "span.sa, span.sbc", function (e) { + const subjectId = $(e.target).attr("subjectId"); + reviewSubjectData.subject = { + id: subjectId, + }; + reviewSubjectData.dialog = true; +}); diff --git a/app/manifest.json b/src/manifest.json similarity index 86% rename from app/manifest.json rename to src/manifest.json index 4958408..5c827d8 100644 --- a/app/manifest.json +++ b/src/manifest.json @@ -13,7 +13,13 @@ "service_worker": "scripts/background.js" }, "permissions": ["storage"], - "host_permissions": ["*://*/*"], + "host_permissions": [ + "http://*.ufabc.edu.br/*", + "https://*.ufabc.edu.br/*", + "http://localhost:8000/*", + "http://*.ufabcnext.com/*", + "https://*.ufabcnext.com/*" + ], "content_scripts": [ { "all_frames": true, @@ -52,12 +58,16 @@ "web_accessible_resources": [ { "resources": [ - "fonts/*", - "scripts/*", + "components/*", "images/*", - "html/*", + "lib/*", + "pages/*", + "scripts/*", + "services/*", "styles/*", - "pages/*" + "utils/*", + "views/*", + "html/*" ], "matches": [ "http://*.ufabc.edu.br/*", diff --git a/src/pages/iframe.html b/src/pages/iframe.html new file mode 100644 index 0000000..230e258 --- /dev/null +++ b/src/pages/iframe.html @@ -0,0 +1,9 @@ + + + + + + + UFABC Next Storage + + diff --git a/app/pages/matricula/corte.html b/src/pages/matricula/corte.html similarity index 100% rename from app/pages/matricula/corte.html rename to src/pages/matricula/corte.html diff --git a/app/pages/matricula/fragments/matriculasNumber.html b/src/pages/matricula/fragments/matriculasNumber.html similarity index 100% rename from app/pages/matricula/fragments/matriculasNumber.html rename to src/pages/matricula/fragments/matriculasNumber.html diff --git a/app/pages/matricula/fragments/professorPopover.html b/src/pages/matricula/fragments/professorPopover.html similarity index 100% rename from app/pages/matricula/fragments/professorPopover.html rename to src/pages/matricula/fragments/professorPopover.html diff --git a/app/pages/popup.html b/src/pages/popup.html similarity index 100% rename from app/pages/popup.html rename to src/pages/popup.html diff --git a/app/scripts/background.js b/src/scripts/background.js similarity index 100% rename from app/scripts/background.js rename to src/scripts/background.js diff --git a/src/scripts/contentScriptPortal.js b/src/scripts/contentScriptPortal.js new file mode 100644 index 0000000..01500a3 --- /dev/null +++ b/src/scripts/contentScriptPortal.js @@ -0,0 +1,252 @@ +import toastr from "toastr"; +import $ from "jquery"; +import _ from "lodash"; +import Utils from "../utils/extensionUtils"; +import { NextAPI } from "../services/NextAPI"; +import Axios from "axios"; +import Toastify from "toastify-js"; +import "toastify-js/src/toastify.css"; +const loading = require("../images/loading.svg"); +const errorSVG = require("../images/error.svg"); +const logoWhite = require("../images/logo-white.svg"); + +const nextApi = NextAPI(); + +const toast = new Toastify({ + text: ` +
+ +

Atualizando suas informações...

\n\n + NÃO SAIA DESSA PÁGINA, +

apenas aguarde, no máx. 5 min 🙏

+
`, + duration: -1, + close: false, + gravity: "bottom", + position: "right", + className: "toast-loading", + escapeMarkup: false, + avatar: loading, + style: { + background: "linear-gradient(to right, #2E7EED, rgba(46, 126, 237, 0.5));", + }, +}); + +if (isIndexPortalAluno()) { + const anchor = document.createElement("div"); + anchor.setAttribute("id", "app"); + document.body.append(anchor); + Utils.injectScript("studentPortal.js"); + + Utils.injectStyle("styles/portal.css"); + toastr.info( + "Clique em Ficha Individual para atualizar suas informações!" + ); +} else if (isFichasIndividuaisPath()) { + Utils.injectStyle("styles/portal.css"); + + toast.showToast(); + + iterateTabelaCursosAndSaveToLocalStorage(); +} else if (isFichaIndividualPath()) { + Utils.injectStyle("styles/portal.css"); +} + +function isIndexPortalAluno() { + return ( + document.location.href.indexOf("aluno.ufabc.edu.br/dados_pessoais") !== -1 + ); +} + +function isFichasIndividuaisPath() { + return ( + document.location.href.indexOf("aluno.ufabc.edu.br/fichas_individuais") !== + -1 + ); +} + +function isFichaIndividualPath() { + return ( + document.location.href.indexOf("aluno.ufabc.edu.br/ficha_individual") !== -1 + ); +} + +function iterateTabelaCursosAndSaveToLocalStorage() { + var tabelaCursos = $("tbody").children().slice(1); + let count = 0; + + tabelaCursos.each(async function () { + var linhaCurso = $(this).children(); + + 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, nomeDoCurso, anoDaGrade); + if (count == 0) toast.hideToast(); + count++; + + if (!curso) return; + + curso.curso = linhaCurso[0].innerText.replace("Novo", ""); + curso.turno = linhaCurso[3].innerText; + + await saveToLocalStorage(curso); + + await saveStudentsToLocalStorage(curso); + }); +} + +async function getFichaAluno(fichaAlunoUrl, nomeDoCurso, anoDaGrade) { + try { + var curso = {}; + var 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 ra = + /.*?(\d+).*/g.exec( + ficha_obj.find("#page").children("p")[2].innerText + )[1] || "some ra"; + + const storageRA = "ufabc-extension-ra-" + getEmailAluno(); + await Utils.storage.setItem(storageRA, ra); + + const jsonFicha = await Axios.get( + "https://aluno.ufabc.edu.br" + fichaAlunoUrl, + { + timeout: 60 * 1 * 1000, // 1 minute + } + ); + + const disciplinasCategory = ficha_obj.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 + ); + + // mandatory + const totalCreditsCoursedMandatory = toNumber(disciplinasCategory[7]); + const totalPercentageCoursedMandatory = toNumber(disciplinasCategory[8]); + const totalCreditsMandatory = Math.round( + (totalCreditsCoursedMandatory * 100) / totalPercentageCoursedMandatory + ); + + // limited + const totalCreditsCoursedLimited = toNumber(disciplinasCategory[12]); + const totalPercentageCoursedLimited = toNumber(disciplinasCategory[13]); + const totalCreditsLimited = Math.round( + (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 + } + ); + + 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.cursadas = jsonFicha.data; + + return curso; + } catch (err) { + console.log(err); + Toastify({ + text: ` +
+ + Não foi possível salvar seus dados, recarregue a página e aguarde. +
`, + duration: -1, + close: true, + gravity: "top", + position: "right", + className: "toast-error-container", + style: { + background: "#E74C3C;", + }, + }).showToast(); + } +} + +function getEmailAluno() { + return $("#top li") + .last() + .text() + .replace(/\s*/, "") + .split("|")[0] + .replace(" ", "") + .toLowerCase(); +} + +function toNumber(el) { + return parseFloat(el.innerText.replace(",", ".")); +} + +async function saveToLocalStorage(curso) { + const storageUser = "ufabc-extension-" + getEmailAluno(); + let user = await Utils.storage.getItem(storageUser); + if (!user || _.isEmpty(user)) user = []; + + user.push(curso); + user = _.uniqBy(user, "curso"); + + await Utils.storage.setItem(storageUser, user); + + toastr.success( + `Suas informações foram salvas! Disciplinas do curso do ${curso.curso} + para o usuário ${getEmailAluno()}. + `, + { timeout: 100000 } + ); +} + +async function saveStudentsToLocalStorage(curso) { + const storageUser = "ufabc-extension-" + getEmailAluno(); + const cursos = await Utils.storage.getItem(storageUser); + const ra = (curso && curso.ra) || null; + + let allSavedStudents = []; + const students = await Utils.storage.getItem("ufabc-extension-students"); + if (students && students.length) { + allSavedStudents.push(...students); + } + + allSavedStudents = allSavedStudents.filter((student) => student.ra != ra); + const student = { + cursos: cursos, + ra: ra, + name: getEmailAluno(), + lastUpdate: Date.now(), + }; + allSavedStudents.unshift(student); + await Utils.storage.setItem("ufabc-extension-students", allSavedStudents); +} diff --git a/src/scripts/contentscript.js b/src/scripts/contentscript.js new file mode 100644 index 0000000..67b129a --- /dev/null +++ b/src/scripts/contentscript.js @@ -0,0 +1,105 @@ +// https://crx.dam.io/ext/gphjopenfpnlnffmhhhhdiecgdcopmhk.html +// add extension id to window +const isBrowser = typeof chrome != "undefined" && !!chrome.storage; +// var script = document.createElement('script'); +// const extension_id = isBrowser ? chrome.i18n.getMessage("@@extension_id") : null; +// script.innerHTML = `extension_id = "${extension_id}"`; +// (document.head || document.documentElement).appendChild(script) + +import $ from "jquery"; +import _ from "lodash"; + +import matriculaUtils from "../utils/Matricula"; +import { setupStorage } from "../utils/setupStorage"; + +import Utils from "../utils/extensionUtils"; + +// CSS imports +import "element-ui/lib/theme-chalk/index.css"; + +let matricula_url; + +if (process.env.NODE_ENV == "production") { + matricula_url = [ + "matricula.ufabc.edu.br/matricula", + "ufabc-matricula.cdd.naoseiprogramar.com.br/snapshot", + "api.ufabcnext.com/snapshot", + ]; +} else { + matricula_url = [ + "matricula.ufabc.edu.br/matricula", + "api.ufabcnext.com/snapshot", + "api.ufabcnext.com/snapshot/backup.html", + "ufabc-matricula.cdd.naoseiprogramar.com.br/snapshot", + "ufabc-matricula.cdd.naoseiprogramar.com.br/snapshot/backup.html", + "ufabc-matricula-test.cdd.naoseiprogramar.com.br/snapshot", + "ufabc-matricula-test.cdd.naoseiprogramar.com.br/snapshot/backup.html", + "locahost:8011/snapshot", + "locahost:8011/snapshot/backup.html", + ]; +} + +if (!isBrowser) { + console.log("Not running on browser!"); + load(); +} else { + window.addEventListener("load", load); +} + +async function load() { + const currentUrl = document.location.href; + // add cross-domain local storage + Utils.injectScript("lib/xdLocalStorage.min.js"); + Utils.injectIframe("pages/iframe.html"); + Utils.injectScript("lib/init.js"); + + setupStorage(); + require("./contentScriptPortal"); + + if (matricula_url.some((url) => currentUrl.indexOf(url) != -1)) { + // update teachers locally + setTimeout(async () => { + let lastUpdate = null; + try { + lastUpdate = await Utils.storage.getItem("ufabc-extension-last"); + } catch (err) { + lastUpdate = Date.now(); + } finally { + matriculaUtils.updateProfessors(lastUpdate); + } + + // this is the main vue app + // i.e, where all the filters live + const anchor = document.createElement("div"); + anchor.setAttribute("id", "app"); + $("#meio").prepend(anchor); + + //inject styles + Utils.injectStyle("styles/main.css"); + + // manda as informacoes para o servidor + matriculaUtils.sendAlunoData(); + + // load vue app modal + const modal = document.createElement("div"); + modal.setAttribute("id", "modal"); + modal.setAttribute("data-app", true); + document.body.append(modal); + + // load vue app teacherReview + const teacherReview = document.createElement("div"); + teacherReview.setAttribute("id", "teacherReview"); + teacherReview.setAttribute("data-app", true); + document.body.append(teacherReview); + + // load vue app review subjects + const reviewSubject = document.createElement("div"); + reviewSubject.setAttribute("id", "review-subject"); + reviewSubject.setAttribute("data-app", true); + document.body.append(reviewSubject); + + // inject Vue app + Utils.injectScript("scripts/main.js"); + }, 1500); + } +} diff --git a/app/scripts/popup.js b/src/scripts/popup.js similarity index 93% rename from app/scripts/popup.js rename to src/scripts/popup.js index 102f5ca..15c8ab3 100644 --- a/app/scripts/popup.js +++ b/src/scripts/popup.js @@ -18,7 +18,7 @@ import _ from 'lodash' // }) import Vue from 'vue'; -import App from './popup/App.vue'; +import App from '../views/popup.vue'; var app = new Vue({ el: '#app', diff --git a/src/services/NextAPI.js b/src/services/NextAPI.js new file mode 100644 index 0000000..8647b06 --- /dev/null +++ b/src/services/NextAPI.js @@ -0,0 +1,30 @@ +import Axios from "axios"; + +function resolveEndpoint(env) { + return ( + { + development: "http://localhost:8011/v1", + staging: "https://ufabc-matricula-test.cdd.naoseiprogramar.com.br/v1", + production: "https://api.ufabcnext.com/v1", + }[env] || "http://localhost:8011/v1" + ); +} + +function NextAPI() { + const baseURL = resolveEndpoint(process.env.NODE_ENV); + const REQUEST_TIMEOUT = 5000; + const nextAPI = Axios.create({ + baseURL, + timeout: REQUEST_TIMEOUT, + headers: { + Accept: "application/json", + "Content-Type": "application/json", + }, + }); + + return nextAPI; +} + +module.exports = { + NextAPI, +}; diff --git a/src/studentPortal.js b/src/studentPortal.js new file mode 100644 index 0000000..435907c --- /dev/null +++ b/src/studentPortal.js @@ -0,0 +1,14 @@ +import Vue from "vue"; +import Vuetify from "vuetify"; + +Vue.use(Vuetify); + +import Portal from "./views/Portal.vue"; + +new Vue({ + el: "#app", + data: { + name: "portal-matricula-extension", + }, + render: (h) => h(Portal), +}); diff --git a/app/styles/main.css b/src/styles/main.css similarity index 100% rename from app/styles/main.css rename to src/styles/main.css diff --git a/app/styles/portal.css b/src/styles/portal.css similarity index 100% rename from app/styles/portal.css rename to src/styles/portal.css diff --git a/src/utils/Matricula.js b/src/utils/Matricula.js new file mode 100644 index 0000000..4efd35e --- /dev/null +++ b/src/utils/Matricula.js @@ -0,0 +1,158 @@ +import Axios from "axios"; +import { NextAPI } from "../services/NextAPI"; +import toJSON from "./toJSON"; +import _ from "lodash"; +import $ from "jquery"; +import Utils from "./extensionUtils"; + +const nextApi = NextAPI(); + +module.exports = new Matricula(); + +function Matricula() { + const MATRICULAS_URL = + { + development: "http://localhost:8011/snapshot/assets/todasDisciplinas.js", + staging: + "https://ufabc-matricula-test.cdd.naoseiprogramar.com.br/snapshot/assets/todasDisciplinas.js", + production: "https://matricula.ufabc.edu.br/cache/matriculas.js", + }[process.env.NODE_ENV] || "http://localhost:8011/v1"; + + // check if we need to update our localStorage of professors + // based when you did this last request + async function updateProfessors(data) { + let lastTime = data; + let timeDiff = (Date.now() - lastTime) / (1000 * 60); + + await getProfessors(); + if (!lastTime || timeDiff > 0.2) { + await getProfessors(); + } + } + + // fetch professors url and save them into localStorage + async function getProfessors() { + try { + let { data: professors } = await nextApi.get("/disciplinas"); + await Utils.storage.setItem("ufabc-extension-last", Date.now()); + await Utils.storage.setItem("ufabc-extension-disciplinas", professors); + return professors; + } catch (e) { + console.log("❌ Erro ao atualizar disciplinas"); + console.error(e); + } + } + + // disciplinas que mudaram de nome (HARDCODED) + var disciplinas_mudadas = { + "Energia: Origens, Conversão e Uso": "Bases Conceituais da Energia", + "Transformações nos Seres Vivos e Ambiente": + "Biodiversidade: Interações entre organismos e ambiente", + "Transformações Bioquímicas": + "Bioquímica: estrutura, propriedade e funções de Biomoléculas", + "Transformações Bioquímicas": + "Bioquímica: Estrutura, Propriedade e Funções de Biomoléculas", + "Origem da Vida e Diversidade dos Seres Vivos": + "Evolução e Diversificação da Vida na Terra", + }; + + // fetch matriculas again + async function getMatriculas() { + const disciplinas = await Axios.get(MATRICULAS_URL); + return toJSON(disciplinas.data) || {}; + } + + // get total number of matriculas that was made until now + async function getTotalMatriculas() { + return Object.keys(await getMatriculas()).length; + } + + // get matriculas by aluno_id + async function getMatriculasAluno(aluno_id) { + const matriculas = await getMatriculas(); + return _.get(matriculas, aluno_id); + } + + // get current logged student + function getAlunoId() { + let toReturn = null; + + $("script").each(function () { + var inside = $(this).text(); + var test = "todasMatriculas"; + if (inside.indexOf(test) != -1) { + var regex = /matriculas\[(.*)\]/; + var match = regex.exec(inside); + toReturn = parseInt(match[1]); + } + }); + + return toReturn; + } + + // find courseId for this season + function findIdForCurso(name) { + if ( + _.camelCase(name) == _.camelCase("Bacharelado em Ciências da Computação") + ) { + name = "Bacharelado em Ciência da Computação"; + } + // normalize to camelCase + name = _.camelCase(name); + + // check which row matches the name passed + const course = $("#curso") + .children() + .filter(function (i, item) { + return name == _.camelCase($(item).text()); + })[0]; + + return $(course).val(); + } + + function currentUser() { + return $("#usuario_top") + .text() + .replace(/\s*/, "") + .split("|")[0] + .trim() + .toLowerCase(); + } + + // send aluno data + async function sendAlunoData() { + const storageUser = "ufabc-extension-" + currentUser(); + const storageRA = "ufabc-extension-ra-" + currentUser(); + const user = await Utils.storage.getItem(storageUser); + const ra = await Utils.storage.getItem(storageRA); + + if (!user) return; + + // remove as disciplinas cursadas + for (var i = 0; i < user.length; i++) { + delete user[i].cursadas; + } + + await nextApi.post("/students", { + aluno_id: getAlunoId(), + cursos: user.map(function (info) { + info.curso_id = findIdForCurso(info.curso); + return info; + }), + ra: ra, + login: currentUser(), + }); + } + + return { + updateProfessors, + getProfessors, + getMatriculas, + getTotalMatriculas, + getMatriculasAluno, + getAlunoId, + findIdForCurso, + currentUser, + sendAlunoData, + }; +} diff --git a/src/utils/convertUfabcDisciplina.js b/src/utils/convertUfabcDisciplina.js new file mode 100644 index 0000000..f308eb6 --- /dev/null +++ b/src/utils/convertUfabcDisciplina.js @@ -0,0 +1,120 @@ +const _ = require("lodash"); +const removeDiacritics = require("./removeDiacritics"); + +// This convert an disciplina from the .json from matriculas.ufabc +function convertDisciplina(d) { + const obj = _.defaults(_.clone(d)); + + // specific for .json + delete obj.campus; + delete obj.turno; + obj.obrigatorias = _.map(obj.obrigatoriedades, "curso_id"); + + let afterNoon = false; + + // handler horarios based on pdf or json + if (obj.horarios && _.isObject(obj.horarios)) { + let startHours = _.get(obj.horarios, "[0].horas", []); + let afterNoon = ["14:00", "15:00", "16:00", "17:00"].some((hour) => + startHours.includes(hour) + ); + } else if (obj.horarios && _.isString(obj.horarios)) { + obj.horarios = removeLineBreaks(obj.horarios); + + const matched = obj.horarios.match(/\d{2}:\d{2}/g); + + // only match if is even + if (matched.length % 2 == 0) { + let hours = _.chunk(matched, 2); + hours.forEach((m) => { + let [start, end] = m.map((h) => parseInt(h.split(":")[0])); + + if (start >= 12 && start < 18) { + afterNoon = true; + } + }); + } + } + + // trabalha nas disciplinas + // if(!obj.nome) return obj + + let turnoIndex = null; + + let breakRule = "-"; + + var splitted = removeLineBreaks(obj.nome).split(breakRule); + if (splitted.length == 1) { + breakRule = " "; + splitted = splitted[0].split(/\s+/); + } + + splitted.map(function (item, i) { + obj.campus = obj.campus || extractCampus(item); + obj.turno = obj.turno || (afterNoon ? "tarde" : extractTurno(item)); + + if ((obj.turno || obj.campus) && turnoIndex == null) turnoIndex = i; + }); + + if (!obj.campus) { + let secondPath = splitted.slice(turnoIndex + 1, splitted.length); + obj.campus = extractCampus(secondPath.join(breakRule)); + } + + // cut until the index we found + splitted = splitted.slice(0, turnoIndex); + + // separa a turma da disciplina + var disciplina = _.compact(splitted.join("-").split(/\s+/)); + obj.turma = disciplina[disciplina.length - 1]; + disciplina.pop(); + + // fix disciplina + obj.disciplina = disciplina.join(" ").trim(); + //obj.ideal_quad = app.helpers.season.findIdeais().includes(obj.codigo) + + obj.disciplina_id = obj.id; + obj.codigo = obj.codigo; + + return obj; +} + +function cleanTeacher(str) { + return _.startCase(_.camelCase(str)) + .replace(/-+.*?-+/g, "") + .replace(/\(+.*?\)+/g, ""); +} + +function removeLineBreaks(str = "") { + return str.replace(/\r?\n|\r/g, " "); +} + +function extractTurno(d) { + const min = d.toLowerCase(); + if (min.includes("diurno") || min.includes("matutino")) { + return "diurno"; + } + + if (min.includes("noturno")) { + return "noturno"; + } + + return null; +} + +function extractCampus(d) { + const min = removeDiacritics(d.toLowerCase()); + if (/.*santo\s+andre.*/.test(min)) { + return "santo andre"; + } + + if (/.*sao\s+bernardo.*/.test(min)) { + return "sao bernardo"; + } + + return null; +} + +module.exports = { + convertDisciplina, +}; diff --git a/src/utils/disciplinaIdentifier.js b/src/utils/disciplinaIdentifier.js new file mode 100644 index 0000000..b8b4f1b --- /dev/null +++ b/src/utils/disciplinaIdentifier.js @@ -0,0 +1,20 @@ +import { createHash } from "crypto"; +import _ from "lodash"; + +const DEFAULT_FIELDS_TO_ENCODE = ["disciplina", "turno", "campus", "turma"]; + +/** + * Generates a unique identifier for a given disciplina + * */ +function generateIdentifier(disciplina, keys = DEFAULT_FIELDS_TO_ENCODE) { + const unorderedDisciplinas = keys.map((key) => String(disciplina[key])); + const disciplinaToEncode = unorderedDisciplinas + .map((disciplina) => _.camelCase(disciplina)) + .join(""); + + return createHash("md5").update(disciplinaToEncode).digest("hex"); +} + +module.exports = { + generateIdentifier, +}; diff --git a/src/utils/extensionUtils.js b/src/utils/extensionUtils.js new file mode 100644 index 0000000..0a30cf5 --- /dev/null +++ b/src/utils/extensionUtils.js @@ -0,0 +1,133 @@ +import $ from "jquery"; +import Axios from "axios"; +import is from "is_js"; +import _ from "lodash"; + +module.exports = new ExtensionUtils(); + +function ExtensionUtils() { + // force initialization of xdLocalStorage + // window.xdLocalStorage.init({ + // iframeUrl: getExtensionUrl("pages/iframe.html"), + // }); + + const IS_BROWSER = typeof chrome != "undefined" && !!chrome.storage; + const EXTENSION_ID = IS_BROWSER + ? chrome.i18n.getMessage("@@extension_id") + : null; + + var getChromeUrl = function (url) { + return getExtensionUrl(url); + }; + + var fetchChromeUrl = async function (url, cb) { + return Axios.get(getChromeUrl(url)); + }; + + var injectDiv = async function (link, el) { + let resp = await fetchChromeUrl(link); + const data = resp.data; + + var div = document.createElement("div"); + div.innerHTML = data; + + if (el) { + let parent = el.parentNode; + parent.insertBefore(div, el.nextSibling); + } else { + document.body.appendChild(div); + } + }; + + var injectStyle = function (link) { + var s = document.createElement("link"); + s.href = getExtensionUrl(link); + s.type = "text/css"; + s.rel = "stylesheet"; + + document.head.appendChild(s); + }; + + var injectScript = function (link) { + var s = document.createElement("script"); + s.src = getExtensionUrl(link); + + (document.head || document.documentElement).appendChild(s); + }; + + var injectIframe = function (link) { + var s = document.createElement("iframe"); + s.src = getExtensionUrl(link); + s.setAttribute("style", "display: none;"); + (document.body || document.documentElement).appendChild(s); + }; + + var storage = { + setItem(key, value) { + return new Promise((resolve, reject) => { + try { + const date = Date.now(); + const event = new CustomEvent("requestStorage", { + detail: { + method: `setStorage-${key}-${date}`, + date: date, + key: key, + value: value, + }, + }); + document.addEventListener(`setStorage-${key}-${date}`, (evt) => { + resolve(evt.detail.value); + }); + document.dispatchEvent(event); + } catch (err) { + console.error(err); + } + }); + }, + getItem(key) { + return new Promise((resolve, reject) => { + try { + const date = Date.now(); + const event = new CustomEvent("requestStorage", { + detail: { + method: `getStorage-${key}-${date}`, + key: key, + date: date, + }, + }); + document.addEventListener(`getStorage-${key}-${date}`, (evt) => { + resolve(evt.detail.value); + }); + document.dispatchEvent(event); + } catch (err) { + console.error(err); + } + }); + }, + }; + + function getExtensionUrl(link) { + if (EXTENSION_ID) { + const prefix = is.chrome() ? "chrome-extension://" : "moz-extension://"; + return prefix + EXTENSION_ID + "/" + link.replace(/^\//, ""); + } else { + return `https://next-extension.captain.sv.ufabcnext.com/static/${link}`; + } + } + + var getFile = async function (link) { + return (await Axios.get(getChromeUrl(link))).data; + }; + + return { + getChromeUrl, + injectScript, + injectDiv, + injectIframe, + injectStyle, + fetchChromeUrl, + getExtensionUrl, + getFile, + storage, + }; +} diff --git a/app/scripts/helpers/removeDiacritics.js b/src/utils/removeDiacritics.js similarity index 100% rename from app/scripts/helpers/removeDiacritics.js rename to src/utils/removeDiacritics.js diff --git a/src/utils/season.js b/src/utils/season.js new file mode 100644 index 0000000..d07483b --- /dev/null +++ b/src/utils/season.js @@ -0,0 +1,84 @@ +function findQuadFromDate(month) { + if ([0, 1, 2, 10, 11].includes(month)) { + return 1; + } + if ([3, 4, 5].includes(month)) { + return 2; + } + if ([6, 7, 8, 9].includes(month)) { + return 3; + } +} + +function findSeason(date = new Date()) { + const month = date.getMonth(); + return { + 1: { + quad: 1, + year: date.getFullYear() + (month < 6 ? 0 : 1), + }, + 2: { + quad: 2, + year: date.getFullYear(), + }, + 3: { + quad: 3, + year: date.getFullYear(), + }, + }[findQuadFromDate(date.getMonth() || month)]; +} + +function findSeasonKey(date) { + const { year, quad } = findSeason(date); + return `${year}:${quad}`; +} + +function findIdeais(date) { + return { + 1: [ + "BCM0506-15", // COMUNICACAO E REDES + "BCJ0203-15", // ELETROMAG + "BIN0406-15", // IPE + "BCN0405-15", // IEDO + "BIR0004-15", // EPISTEMOLOGICAS + "BHO0102-15", // DESENVOL. E SUSTE. + "BHO0002-15", // PENSA. ECONOMICO + "BHP0201-15", // TEMAS E PROBLEMAS + "BHO0101-15", // ESTADO E RELA + "BIR0603-15", // CTS + "BHQ0003-15", // INTEPRE. BRASIL + "BHQ0001-15", // IDENT.E CULTURA + ], + 2: [ + "BCM0504-15", // NI + "BCN0404-15", // GA + "BCN0402-15", // FUV + "BCJ0204-15", // FEMEC + "BCL0306-15", // BIODIVERSIDADE + "BCK0103-15", // QUANTICA + "BCL0308-15", // BIOQUIMICA + "BIQ0602-15", // EDS + "BHO1335-15", // FORMACAO SISTEMA INTERNACIONAL + "BHO1101-15", // INTRODUCAO A ECONOMIA + "BHO0001-15", // INTRODUCAO AS HUMANIDADES + "BHP0202-15", // PENSAMENTO CRITICO + ], + 3: [ + "BCJ0205-15", // FETERM + "BCM0505-15", // PI + "BCN0407-15", // FVV + "BCL0307-15", // TQ + "BCK0104-15", // IAM + "BIR0603-15", // CTS + "BHP0001-15", // ETICA E JUSTICA + "BHQ0301-15", // TERRITORIO E SOCIEDADE + // ESTUDO ÉTNICOS RACIAIS + ], + }[findQuadFromDate(date || new Date().getMonth())]; +} + +module.exports = { + findSeason, + findSeasonKey, + findIdeais, +}; diff --git a/src/utils/setupStorage.js b/src/utils/setupStorage.js new file mode 100644 index 0000000..f90fd93 --- /dev/null +++ b/src/utils/setupStorage.js @@ -0,0 +1,69 @@ +function setupStorage() { + document.addEventListener("requestStorage", (event) => { + const key = event.detail.key; + const date = event.detail.date; + const value = event.detail.value; + const method = event.detail.method.split("-")[0]; + const eventType = event.type; + if (!key || !date || !method || eventType != "requestStorage") return; + + const IS_BROWSER = typeof chrome != "undefined" && !!chrome.storage; + const eventMethod = event.detail.method; + if (IS_BROWSER) { + console.log(`[${method} | ${key}] Using chrome.storage 🔵`); + // maybe below is actually resolve(data && data[key]) - please check + + if (method == "setStorage") { + chrome.storage.local.set({ [key]: value }); + return document.dispatchEvent( + new CustomEvent(eventMethod, { + detail: { + key: key, + value: value, + }, + }) + ); + } else if (method == "getStorage") { + return chrome.storage.local.get(key, (data) => { + document.dispatchEvent( + new CustomEvent(eventMethod, { + detail: { + key: key, + value: data && data[key], + }, + }) + ); + }); + } + } + + console.log(`[${method} | ${key}] Using xdLocalStorage 🔴`); + if (method == "setStorage") { + window.xdLocalStorage.setItem(key, JSON.stringify(value), (data) => { + document.dispatchEvent( + new CustomEvent(eventMethod, { + detail: { + key: key, + value: date.value, + }, + }) + ); + }); + } else if (method == "getStorage") { + window.xdLocalStorage.getItem(key, (data) => { + document.dispatchEvent( + new CustomEvent(eventMethod, { + detail: { + key: key, + value: JSON.parse(data.value), + }, + }) + ); + }); + } + }); +} + +module.exports = { + setupStorage, +}; diff --git a/src/utils/toJSON.js b/src/utils/toJSON.js new file mode 100644 index 0000000..56f5bd2 --- /dev/null +++ b/src/utils/toJSON.js @@ -0,0 +1,17 @@ +import _ from "lodash"; + +const toJSON = (payload, max) => { + const json = JSON.parse( + _.get(new RegExp(/^\w*=(.*)/).exec(payload), "[1]", {}) + ); + + if (max) { + return json.slice(0, max); + } + + return json; +}; + +module.exports = { + toJSON, +}; diff --git a/src/views/Matricula.vue b/src/views/Matricula.vue new file mode 100644 index 0000000..684541e --- /dev/null +++ b/src/views/Matricula.vue @@ -0,0 +1,323 @@ + + + diff --git a/src/views/Portal.vue b/src/views/Portal.vue new file mode 100644 index 0000000..bd204f9 --- /dev/null +++ b/src/views/Portal.vue @@ -0,0 +1,9 @@ + + + diff --git a/app/scripts/popup/App.vue b/src/views/popup.vue similarity index 96% rename from app/scripts/popup/App.vue rename to src/views/popup.vue index 6db9dc7..e4f0053 100644 --- a/app/scripts/popup/App.vue +++ b/src/views/popup.vue @@ -1,6 +1,6 @@