-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.js
108 lines (94 loc) · 3.52 KB
/
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
const cron = require('node-cron')
const axios = require('axios')
const cheerio = require('cheerio')
const express = require('express')
const hbs = require('express-handlebars')
const sequelize = require('./db/conn')
const acaoRoutes = require('./routes/AcaoRoutes')
const Acao = require('./models/Acao')
const port = process.env.PORT || 3000
// alterado por marcos no dia 08/04/2022
// configurações do 'express'
const app = express()
app.use(
express.urlencoded({
extended: true
})
)
app.use(express.json())
// configurações do 'handlebars'
app.engine('handlebars', hbs.engine()) // define a template engine do projeto
app.set('view engine', 'handlebars')
app.use(express.static('public')) // express config
// configurações das rotas Mestres
app.use('/acoes', acaoRoutes)
app.get('/sobre', // cria a rota de exibição das tasks '/tasks/'
(req,res)=>{
res.render('sobre')
}
)
app.get('/', // cria a rota de exibição das tasks '/tasks/'
(req,res)=>{
res.redirect('/acoes/')
}
)
/* Conecta o banco de dados antes de iniciar a aplicação */
sequelize
.sync()
.then(() => {
app.listen(port, () => { console.log(`Executando na porta ${port}`) })
// updateCotacoes() // atualiza as cotações no banco de dados
/* Agendador de tarefa. Executa a atualização das ações no banco a cada 15 min*/
// cron.schedule('*/15 * * * *', () => {
// console.log("Atualizando...");
// updateCotacoes() // atualiza as cotações no banco de dados
// });
})
.catch(err => { console.log(err) })
/* FUNÇÕES DO BACK-END ************************************/
async function updateCotacoes(){
// busca as cotações das ações (scrapping)
const acoes = await loadCotacoes()
// conta a quantidade de registros existentes na tabela 'Acoes'
const qt = await Acao.count()
if(qt){ // se houver registros na tabela, precisamos apenas atualizar
// atualiza cada uma das ações no banco de dados
acoes.map( (acao, index)=>{
Acao.update(acao,{where:{code:acao.code}})
})
}else{ // caso não haja registros, precisamos criá-los
// salvar cada uma das ações no banco de dados
acoes.map( (acao, index)=>{
Acao.create(acao)
})
}
}
// Busca 'nome','código' e 'preço' das ações da BOVESPA
async function loadCotacoes() {
try {
// carrega o html do site com as cotações
const buffer = await axios.get('https://valorinveste.globo.com/cotacoes/')
const html = buffer.data // extrai o código html
const $ = cheerio.load(html) // converte para json mais legível
// faz a filtragem com base nos seletores desejados
let acoes = []
$('tbody > tr').each((index, elem) => {
// captura os dados do 'nome','código' e 'preço' de cada uma das ações
const lines = $(elem).find('.table-date-value')
const name = lines[0].children[0].data.trim()
// verifica se o ativo não é um fundo imobiliário (FII)
if (!name.toLowerCase().startsWith('fii')) {
const code = lines[1].children[0].data.trim()
const price = lines[2].children[0].data.trim()
const acao = {
name, code, price
}
acoes.push(acao)
}
})
return acoes // retorna as ações carregadas
} catch (err) {
console.log(err)
return null
}
}