samuel-moreira's picture
Upload 71 files
b9a69cb verified
from flask import render_template, abort, request, redirect, url_for, jsonify, Response
from flask_login import login_required, current_user, login_user, logout_user
from flask_caching import Cache
import json
from portalrhjobs.ext.models import User, Vagas, Candidatos
from portalrhjobs.ext.database import db
from portalrhjobs.blueprints.rest_api.ai_function import AI_RH
from sqlalchemy import asc
from datetime import timedelta
import re
def init_app(app):
cache = Cache(app, config={'CACHE_TYPE': 'simple', 'CACHE_DEFAULT_TIMEOUT': 3600})
'''
################################
ROTA DE LOGIN
################################
'''
@app.route('/')
def index():
if current_user.is_authenticated:
return redirect(url_for('home'))
else:
return redirect(url_for('login'))
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
if current_user.is_authenticated:
return redirect(url_for('home'))
else:
return render_template('login.html')
error_message = None
if request.method == 'POST':
email = request.form.get('email')
password = request.form.get('password')
user = User.query.filter_by(email=email).first()
remember_me = bool(int(request.form.get('remember_me')))
if user and user.password == password:
login_user(user, remember=remember_me, duration=timedelta(30))
return redirect(url_for('home'))
else:
error_message = 'Usuário ou senha incorretos'
return render_template('login.html', error_message=error_message)
@app.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('login'))
@app.route('/home')
@login_required
def home():
if current_user.is_authenticated:
return render_template('index.html')
'''
################################
ROTA DE USUARIOS
################################
'''
@app.route('/new_user', methods=['GET', 'POST'])
@login_required
def new_user():
if request.method == 'POST':
nome = request.form['nome']
sobrenome = request.form['sobrenome']
email = request.form['email']
username = request.form['username']
senha = request.form['senha']
status = request.form['status']
role = request.form['role']
if User.query.filter_by(nome=nome).first():
raise RuntimeError(f'{nome} ja esta cadastrado')
user = User(nome=nome, sobrenome=sobrenome, email=email, username=username, password=senha, status=status, user_type=role)
db.session.add(user)
db.session.commit()
db.session.close()
return render_template('new_user.html')
'''
################################
ROTAS DA PÁGINA DE VAGAS
################################
'''
@app.route('/vagas')
@login_required
# @cache.cached()
def vagas():
vagas = Vagas.query.filter_by(status='ativo').order_by(Vagas.data_abertura.desc()).all()
return render_template('vagas.html', vagas=vagas)
@app.route('/vagas/<int:vaga_id>', methods=['GET', 'POST'])
@login_required
#@cache.cached()
def vaga(vaga_id):
vaga = Vagas.query.filter_by(id=vaga_id).first()
candidatos = Candidatos.query.filter_by(vaga_id=vaga_id).all()
return render_template('vaga.html', vaga=vaga, candidatos=candidatos)
def count_status(candidatos, status):
count = 0
for candidato in candidatos:
if candidato.status == status:
count += 1
return count
app.add_template_global(count_status, 'count_status')
@app.route('/nova_vaga', methods=['GET', 'POST'])
@login_required
def nova_vaga():
if request.method == 'POST':
cargo = request.form['cargo']
dept = request.form['departamento']
local = request.form['localizacao']
nivel = request.form['nivel']
escopo = request.form['escopo']
requisitos = request.form['requisitos']
qualificacoes = request.form['qualificacoes']
info_adicionais = request.form['info-adicionais']
if not info_adicionais.strip():
info_adicionais = None
vaga = Vagas(cargo=cargo, departamento=dept, local=local, nivel=nivel, escopo_vaga=escopo, requisitos=requisitos, qualificacoes=qualificacoes, info_adicionais=info_adicionais)
db.session.add(vaga)
db.session.commit()
db.session.refresh(vaga)
vaga_id = vaga.id
cache.clear()
return redirect(url_for('vaga', vaga_id=vaga_id))
return render_template('nova_vaga.html')
@app.route('/editar_vaga/<int:vaga_id>', methods=['GET', 'POST'])
@login_required
def editar_vaga(vaga_id):
# Recupere a vaga do banco de dados
vaga = Vagas.query.get(vaga_id)
if request.method == 'POST':
vaga.cargo = request.form['cargo']
vaga.dept = request.form['departamento']
vaga.local = request.form['localizacao']
vaga.nivel = request.form['nivel']
vaga.escopo = request.form['escopo']
vaga.requisitos = request.form['requisitos']
vaga.qualificacoes = request.form['qualificacoes']
vaga.info_adicionais = request.form['info-adicionais']
if not vaga.info_adicionais.strip():
vaga.info_adicionais = None
db.session.commit()
cache.clear()
return redirect(url_for('vaga', vaga_id=vaga_id))
return render_template('editar_vaga.html', vaga=vaga)
@app.route('/encerrar_vaga/<int:vaga_id>')
@login_required
def encerrar_vaga(vaga_id):
vaga = Vagas.query.filter_by(id=vaga_id).first()
vaga.status = 'inativo'
db.session.commit()
cache.clear()
return redirect(url_for('vaga', vaga_id=vaga_id))
@app.route('/reabrir_vaga/<int:vaga_id>')
@login_required
def reabrir_vaga(vaga_id):
vaga = Vagas.query.filter_by(id=vaga_id).first()
vaga.status = 'ativo'
db.session.commit()
cache.clear()
return redirect(url_for('vaga', vaga_id=vaga_id))
@app.route('/candidatos/vaga=<int:vaga_id>', methods=['GET', 'POST'])
@login_required
#@cache.cached()
def candidatos_vaga_id(vaga_id):
vaga = Vagas.query.filter_by(id=vaga_id).first()
candidatos = Candidatos.query.filter_by(vaga_id=vaga_id).all()
message = None
pdf_ = None
if request.method == 'POST':
message, pdf_ = processar_pdf(vaga_id)
if pdf_:
message = f'Arquivo PDF enviado com sucesso!\nIniciando o processo de extração de texto...'
salvar_candidato(pdf_, pdf_.id)
cache.clear()
else:
message = 'Nenhum arquivo enviado'
return 'Tudo certo', 204, {'X-Message': 'Currículo cadastrado com sucesso!'}
return render_template('candidatos_vaga_id.html', vaga=vaga, message=message, candidatos=candidatos)
def processar_pdf(vaga_id):
if 'file' not in request.files:
return 'Nenhum arquivo enviado'
pdf_file = request.files['file']
if pdf_file.filename == '':
return 'Nome do arquivo vazio'
pdf_data = pdf_file.read()
novo_pdf = salvar_pdf(vaga_id, pdf_data)
return 'Arquivo PDF enviado com sucesso', novo_pdf
def salvar_pdf(vaga_id, pdf_data):
novo_pdf = Candidatos(vaga_id=vaga_id, curriculo_pdf=pdf_data)
db.session.add(novo_pdf)
db.session.commit()
db.session.refresh(novo_pdf)
return novo_pdf
@app.route('/candidatos/vaga=<int:vaga_id>/mining-text', methods=['POST'])
@login_required
def extrair_texto(pdf):
pdf_content = pdf.curriculo_pdf
texto_extraido = AI_RH().create_contents(pdf_content)
return texto_extraido
def salvar_candidato(pdf, pdf_id):
content = extrair_texto(pdf)
json_string = '\n'.join(content.split('\n'))
data = json.loads(content)
candidato = Candidatos.query.get(pdf_id)
candidato.nome = data["Nome"]
candidato.idade = data["Idade"]
candidato.localizacao = data["Localização"]
candidato.email = data["Email"]
candidato.telefone = data["Telefone"]
candidato.experiencia = data["Experiências"]
candidato.educacao = data["Educação"]
candidato.habilidades = data["Habilidades"]
db.session.commit()
@app.route('/notification')
@login_required
def notification():
return render_template('notification.html')
################################################
### ROTA DE CANDIDATOS ###
################################################
@app.route('/candidatos')
@login_required
# @cache.cached()
def candidatos():
vagas = Vagas.query.filter_by(status='ativo').order_by(Vagas.cargo.asc()).all()
candidatos = Candidatos.query.order_by(asc(Candidatos.nome)).all()
return render_template('candidatos.html', candidatos=candidatos, vagas=vagas, vaga=vaga)
@app.route('/candidatos/')
@login_required
def candidatos_():
return redirect(url_for('candidatos'))
@app.route('/candidatos/<int:candidato_id>', methods=['GET', 'POST'])
@login_required
def candidato(candidato_id):
candidato = Candidatos.query.filter_by(id=candidato_id).first()
candidato_dict = vars(candidato)
candidato_dict.pop('curriculo_pdf', None)
candidato_dict.pop('data_cadastro', None)
print (candidato_dict)
if request.method == 'POST':
if 'acao_fase' in request.form:
acao = request.form['acao_fase'].lower()
if acao == 'avancar':
novo_status = avancar_fase(candidato)
elif acao == 'retroceder':
novo_status = retroceder_fase(candidato)
if novo_status:
cache.clear()
novo_status = candidato.status
return jsonify({'novoStatus': novo_status}), 200
return render_template('candidatos_candidato_id.html', candidato=candidato)
def get_next_status():
return {
'Currículo enviado': 'Background check',
'Background check': 'Entrevista técnica',
'Entrevista técnica': 'Aprovado',
'Aprovado': None
}
def get_previous_status():
return {
'Background check': 'Currículo enviado',
'Entrevista técnica': 'Background check',
'Aprovado': 'Entrevista técnica'
}
def retroceder_fase(candidato):
status_atual = candidato.status
status_anterior = get_previous_status().get(status_atual)
if status_anterior:
candidato.status = status_anterior
db.session.commit()
db.session.refresh(candidato)
return candidato
return candidato
def avancar_fase(candidato):
status_atual = candidato.status
proximo_status = get_next_status().get(status_atual)
if proximo_status:
candidato.status = proximo_status
db.session.commit()
db.session.refresh(candidato)
return candidato
return candidato
@app.route('/candidatos/<int:candidato_id>/atualizar', methods=['POST'])
@login_required
def atualizar_candidato(candidato_id):
candidato = Candidatos.query.get(candidato_id)
data = request.get_json()
nome = data.get('nome', '')
telefone = data.get('telefone', '')
email = data.get('email', '')
localizacao = data.get('localizacao', '')
experiencia = data.get('experiencia', [])
educacao = data.get('educacao', [])
habilidades = data.get('habilidades', [])
candidato.nome = nome
candidato.telefone = telefone
candidato.email = email
candidato.localizacao = localizacao
candidato.experiencia = experiencia
candidato.educacao = educacao
candidato.habilidades = habilidades
db.session.commit()
db.session.refresh(candidato)
cache.clear()
return jsonify({'message': 'Dados atualizados com sucesso!'})
@app.route('/candidatos/<int:candidato_id>/resumo', methods=['POST'])
@login_required
def resumo_candidato(candidato_id):
def to_dict(objeto, atributos):
candidato_dict = {attr: getattr(objeto, attr) for attr in atributos if not attr.startswith('_')}
remover_colunas(candidato_dict)
return candidato_dict
def remover_colunas(dicionario):
colunas_para_remover = ['curriculo_pdf', 'data_cadastro'] # Lista de colunas para remover
for coluna in colunas_para_remover:
dicionario.pop(coluna, None)
def obter_atributos_vaga(candidato):
vaga_id = candidato.vaga_id # Obtém a vaga associada ao candidato
if vaga_id:
vaga_associada = Vagas.query.get(vaga_id)
if vaga_associada:
return {
'escopo_vaga': vaga_associada.escopo_vaga,
'requisitos': vaga_associada.requisitos,
'qualificacoes': vaga_associada.qualificacoes,
'info_adicionais': vaga_associada.info_adicionais
}
else:
return None # Retorna None se não houver vaga associada ao candidato
candidato = Candidatos.query.get(candidato_id)
atributos_para_incluir = [key for key in vars(candidato) if not key.startswith('_')] # Obtendo todos os atributos, exceto os que começam com "_"
candidato_dict = to_dict(candidato, atributos_para_incluir)
vaga_dict = obter_atributos_vaga(candidato)
if request.method == 'POST':
print ('starting')
resumo_ia = AI_RH().resumo_ai_function(vaga_dict, candidato_dict)
partes = resumo_ia.split('Avaliação:')
resumo_candidato = partes[0].strip()
avaliacao = partes[1].strip().replace('.', '') if len(partes) > 1 else None
print (resumo_candidato)
print (avaliacao)
candidato.resumo_ia = resumo_candidato
candidato.avaliacao_ia = avaliacao
db.session.commit()
return jsonify({'resumo_candidato': resumo_candidato, 'avaliacao': avaliacao})