From 9fc968666d25577505194fc77c2cf2286b3a223f Mon Sep 17 00:00:00 2001 From: Bruno Alphonsus de Oliveira Nascimento Date: Wed, 27 Dec 2017 20:54:07 -0200 Subject: [PATCH] Split inicial do script principal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Split do script principal para facilitar a manutenção do código junto ao repositório. - Inclusão de arquivo de configuração ATENÇÃO: QUEBRADOOOOOOOO --- __init__.py | 0 classes.py | 80 ++++++++++++++++++++++++++++++++++++++++++++ doufinder.cfg | 10 ++++++ globais.py | 62 ++++++++++++++++++++++++++++++++++ main.py | 93 +++++++++++++++++++++++++++++++++------------------ termos.py | 22 ++++++++++++ 6 files changed, 234 insertions(+), 33 deletions(-) create mode 100644 __init__.py create mode 100644 classes.py create mode 100644 doufinder.cfg create mode 100644 globais.py create mode 100644 termos.py diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/classes.py b/classes.py new file mode 100644 index 0000000..7d03db3 --- /dev/null +++ b/classes.py @@ -0,0 +1,80 @@ +from globais import * + +class Servidor: + def __init__(self, nome = '', emails_notificacao = [], termos_pesquisa = []): + self.nome = nome + self.emails_notificacao = emails_notificacao + self.termos_pesquisa = termos_pesquisa + +class Termo: + def __init__(self, valor = '') : + self.valor = valor + self.ocorrencias = [] + +class Pesquisa: + def __init__(self, lista_servidores=None): + lista = lista_servidores + + #TODO: incluir o processamento da edição EXTRA + def processar(jornal, extra=False): + + #alterando o número máximo de páginas da pesquisa (hoje 26/12, só o jornal 1 teve mais de + #1000 páginas). + for pagina in range (1,1100): + header = { + 'Content-Type':'application/pdf', + 'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', + 'Accept-Encoding':'gzip, deflate', + 'Accept-Language':'en,pt-BR;q=0.8,pt;q=0.6', + 'Cache-Controle':'no-cache', + 'Connection':'keep-alive', + 'Host':'pesquisa.in.gov.br', + 'Upgrade-Insecure-Requests':'1'} + + http = urllib3.PoolManager() + full_url = url.format(jornal,pagina,str_hoje) + print(full_url) + response = http.request('GET', full_url, headers=header) + + print ("Seção {0}, Página {1}".format(jornal, pagina)) + if 'text/html' not in response.headers['Content-Type'] and response.headers['Content-Encoding'] == 'gzip': + buff = response.data + arquivo = io.BytesIO(buff) + #print(PyPDF2.PdfFileReader(arquivo).getPage(0).extractText()) + #texto = PyPDF2.PdfFileReader(arquivo).getPage(0).extractText().upper().replace('\n',' ') + texto = extrair_texto(arquivo).upper() + + #escrevendo a pagina em disco no diretório de download + if not os.path.exists(diretorio_texto): + os.makedirs(diretorio_texto) + filename = "%s-%s.%s" % (jornal, pagina, "txt") + with open("%s%s" % (diretorio_texto,filename), 'w') as out: + out.write(texto) + + for servidor in servidores_pesquisa: + #pesquisa os termos do servidor interessado + for termo in servidor.termos_pesquisa: + + if re.search(termo.valor.replace(' ','(\s|)*').replace(' DA ','(DA|)').replace(' DE ','(DE|)'),texto): + if jornal == 515: + ocor = 'Jornal: 1, Página: {0}, URL: {1}'.format(pagina, full_url) + if jornal == 529: + ocor = 'Jornal: 2, Página: {0}, URL: {1}'.format(pagina, full_url) + if jornal == 530: + ocor = 'Jornal: 3, Página: {0}, URL: {1}'.format(pagina, full_url) + termo.ocorrencias.append(ocor) + + else: break + + def enviar_ocorrencias(): + for servidor in servidores_pesquisa: + #caso haja ocorrência de algum termo, montar mensagem e enviar e-mail + msg = '' + for termo in servidor.termos_pesquisa: + if len(termo.ocorrencias) > 0: + msg += "\n\n" + termo.valor + ":\n" + for ocorrencia in termo.ocorrencias: + msg += '\t' + ocorrencia + '\n' + + if msg is not '' : + enviar_email(msg, servidor.emails_notificacao, False) diff --git a/doufinder.cfg b/doufinder.cfg new file mode 100644 index 0000000..72c96a4 --- /dev/null +++ b/doufinder.cfg @@ -0,0 +1,10 @@ +[OFFLINE] +# incluir o caminho completo (sem barra no final) +DOWNLOAD_DIR=/home/caputhinefrobles/Downloads/ +[EMAIL] +# obrigatório +SMTP_SERVIDOR=teste +# obrigatório +SMTP_PORTA=25 +SMTP_USUARIO= +SMTP_SENHA= diff --git a/globais.py b/globais.py new file mode 100644 index 0000000..63e7362 --- /dev/null +++ b/globais.py @@ -0,0 +1,62 @@ +import urllib3 +import os, io +import re +from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter +from pdfminer.converter import TextConverter +from pdfminer.layout import LAParams +from pdfminer.pdfpage import PDFPage +import gzip +import smtplib +from mailer import Mailer +from mailer import Message +from termos import servidores_pesquisa + +# https://stackoverflow.com/questions/26494211/extracting-text-from-a-pdf-file-using-pdfminer-in-python +def extrair_texto(stream): + rsrcmgr = PDFResourceManager() + retstr = io.StringIO() + codec = 'utf-8' + laparams = LAParams() + device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams) + #fp = open(stream, 'rb') + interpreter = PDFPageInterpreter(rsrcmgr, device) + password = "" + maxpages = 0 + caching = True + pagenos = set() + + for page in PDFPage.get_pages(stream, pagenos, maxpages=maxpages, + password=password, + caching=caching, + check_extractable=True): + interpreter.process_page(page) + + text = retstr.getvalue() + + stream.close() + device.close() + retstr.close() + return text + +def enviar_email(mensagem, emails_destino, extra): + + message = Message(From="email_remetente@dominio.xyz", To=emails_destino, charset="utf-8") + + if extra: + message.Subject = "DouFinder - EDIÇÃO EXTRA" + else: + message.Subject = "DouFinder" + + message.Body = mensagem + + try: + sender = Mailer('smtp_host', port=25) + sender.login('usuario_smtp', 'senha_smtp') + sender.send(message) + except smtplib.SMTPRecipientsRefused as e: + print("ERRO AO ENVIAR LOG: %s" % str(e.recipients)) + except smtplib.SMTPException as e: + print("ERRO AO ENVIAR LOG: %s" % e) + except smtplib.SMTPAuthenticatioError as e: + print("ERRO AO ENVIAR LOG: %s" % e) + diff --git a/main.py b/main.py index 7a3e9bd..4a12c07 100755 --- a/main.py +++ b/main.py @@ -1,51 +1,78 @@ -import sys, os, getopt -import configparser +import sys,getopt +from configparser import ConfigParser +from termos import servidores_pesquisa, Pesquisa +import datetime -def main(argv): +#variáveis globais +hoje = datetime.datetime.now().date() +str_hoje = hoje.strftime("%d/%m/%Y") +# corrigido string de captcha que estava incorreta no sistema da imprensa nacional e agora foi corrigida + +url = "http://pesquisa.in.gov.br/imprensa/servlet/INPDFViewer?jornal={0}&pagina={1}&data={2}&captchafield=firstAccess" + +config_smtp_servidor = '' +config_smtp_porta = '' +config_smtp_usuario = '' +config_smtp_senha = '' +config_download_dir = '' +def main(argv): try: + config = ConfigParser() + config_arquivo = os.path.join(os.path.dirname(__file__), 'doufinder.cfg') + + if os.path.isfile(config_arquivo): + config.read_file(open(config_arquivo),'UTF-8') + else: + raise FileNotFoundError - config = configparser.ConfigParser() - config.read_file(open('doufinder.cfg')) + if not config['EMAIL']['SMTP_SERVIDOR']: + raise Exception('Servidor SMTP não definido em "doufinder.cfg"') + else: + config_smtp_servidor = str(config['EMAIL']['SMTP_SERVIDOR']) + + if not config['EMAIL']['SMTP_PORTA']: + raise Exception('Porta SMTP não definida em "doufinder.cfg"') + else: + config_smtp_porta = int(config['EMAIL']['SMTP_PORTA']) + + config_smtp_usuario = str(config['EMAIL']['SMTP_USUARIO']) + config_smtp_senha = str(config['EMAIL']['SMTP_SENHA']) + + if config['OFFLINE']['DOWNLOAD_DIR']: + config_download_dir = os.path.join( + str(config['OFFLINE']['DOWNLOAD_DIR']), + hoje.strftime("%d-%m-%Y")) opts, args = getopt.getopt(argv, "e") - except getopt.GetoptError: - print("Erro de argumento\n") - sys.exit(2) - except getopt.GetoptError: - print("Erro de argumento\n") + except getopt.GetoptError as e: + print("%s: Erro de argumento\n" % type(e).__name__) sys.exit(2) - except FileNotFoundError: - print('Não foi possível ler o arquivo de configuração "./doufinder.cfg"\n') - sys.exit(3) + except FileNotFoundError as e: + print('s%: Não foi possível ler o arquivo "doufinder.cfg"\n' % + type(e).__name__) + sys.exit(4) + except BaseException as e: + print("%s: %s\n" % (type(e).__name__, e)) + sys.exit(4) if len(opts) > 0: for opt, arg in opts: if opt =='-e': print("Pesquisa na edição EXTRA ainda não implementada.") - sys.ext(4) - #extra() - #processar_pesquisa(515, True) - #processar_pesquisa(529, True) - #processar_pesquisa(530, True) + sys.exit(3) else: print("Erro de argumento\n") - sys.ext(2) + sys.exit(2) else: - processar_pesquisa(515) - processar_pesquisa(529) - processar_pesquisa(530) - - for servidor in servidores_pesquisa: - msg = '' - for termo in servidor.termos_pesquisa: - if len(termo.ocorrencias) > 0: - msg += "\n\n" + termo.valor + ":\n" - for ocorrencia in termo.ocorrencias: - msg += '\t' + ocorrencia + '\n' - - if msg is not '' : - enviar_log(msg, servidor.emails_notificacao, False) + pesquisa = Pesquisa(servidores_pesquisa) + pesquisa.processar(515) + pesquisa.processar(529) + pesquisa.processar(530) + + #depois de processada a pesquisa dos termos nos jornais + #enviar as ocorrencias para os e-mails informados no cadastro dos termos + pesquisa.enviar_ocorrencias() if __name__ == "__main__": main(sys.argv[1:]) diff --git a/termos.py b/termos.py new file mode 100644 index 0000000..7a2feae --- /dev/null +++ b/termos.py @@ -0,0 +1,22 @@ +from classes import Servidor, Termo + +#definindo lista de servidores e os termos definidos em termos.py +servidores_pesquisa = [] + +#COLOCAR OS TERMOS DA PESQUISA NESTE TRECHO DE CÓDIGO +##################################################### +#Ex.: + +termos = [Termo('FULANO DE TAL'), + Termo('MINISTERIO XYZ'), + Termo('AQUISIÇÃO DE')] + +servidores_pesquisa.append(Servidor('FULANO DE TAL',["email1@gmail.com", "email2@email.com"],termos)) + +termos = [Termo('CICLANO DE TAL'), + Termo('TERMO ABC'), + Termo('LICITAÇÃO'), + Termo('TCU')] +servidores_pesquisa.append(Servidor('CICLANO DE TAL',["emaildociclano@dominio.com.br"],termos)) + +#####################################################