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/', 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/', 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/') @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/') @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=', 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=/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/', 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//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//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})