Spaces:
Runtime error
Runtime error
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 | |
################################ | |
''' | |
def index(): | |
if current_user.is_authenticated: | |
return redirect(url_for('home')) | |
else: | |
return redirect(url_for('login')) | |
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) | |
def logout(): | |
logout_user() | |
return redirect(url_for('login')) | |
def home(): | |
if current_user.is_authenticated: | |
return render_template('index.html') | |
''' | |
################################ | |
ROTA DE USUARIOS | |
################################ | |
''' | |
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 | |
################################ | |
''' | |
# @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) | |
#@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') | |
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') | |
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) | |
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)) | |
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)) | |
#@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 | |
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() | |
def notification(): | |
return render_template('notification.html') | |
################################################ | |
### ROTA DE CANDIDATOS ### | |
################################################ | |
# @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) | |
def candidatos_(): | |
return redirect(url_for('candidatos')) | |
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 | |
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!'}) | |
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}) | |