Exemplo n.º 1
0
def gera_arquivo(lista_final, prefixo, dir_arquivo, labels):
    '''
    Recebe lista final e lista de argumentos da execução (nome do arquivo original e colunas a serem manipuladas) e grava novo arquivo .csv
    '''
    try:
        diretorio_saida, arquivo = _identifica_diretorio(dir_arquivo)
        diretorio = os.path.join(diretorio_saida,
                                 'files_%s' % arquivo.replace('.csv', ''))

        if not os.path.exists(diretorio):
            os.makedirs(diretorio)

        novo_arquivo = os.path.join(diretorio, '%s_%s' % (prefixo, arquivo))

        with open(novo_arquivo, 'w', encoding=_encoding) as saida:

            if label_key not in labels:
                labels.insert(0, label_key)

            dict_writer = csv.DictWriter(saida,
                                         fieldnames=labels,
                                         delimiter=';')
            # dict_writer = csv.DictWriter(saida, fieldnames=labels, delimiter=';', dialect='excel')
            dict_writer.writeheader()
            for l in lista_final:
                dict_writer.writerow(l)

        Logger.debug('prep_files: Arquivo %s_%s criado.' % (prefixo, arquivo))
    except (IOError, TypeError, csv.Error) as e:
        Logger.error('prep_files: Erro ao criar arquivo: %s' % e)
Exemplo n.º 2
0
def _identifica_diretorio(caminho_completo):
    try:
        arquivo = os.path.basename(caminho_completo)
        diretorio = os.path.dirname(caminho_completo)
        Logger.debug("prep_geocode: %s, %s" % (diretorio, arquivo))
        return diretorio, arquivo
    except Exception as e:
        Logger.error('Erro ao manipular o diretório: %s' % e)
Exemplo n.º 3
0
 def manipula_arquivo(self, arquivo, delimitador):
     path_arquivo = prep_files.formata_nome_arquivo(arquivo)
     if path_arquivo != '' and os.path.exists(path_arquivo):
         self._arquivo = path_arquivo
         self._delimitador = delimitador
         self._dados_arquivo_original, self._colunas_disponiveis = prep_files.lista_colunas_e_dados(
             self._arquivo, self._delimitador)
     else:
         Logger.error('"%s": arquivo não encontrado' % arquivo)
Exemplo n.º 4
0
    def _processa(self):
        status, http_code, message = prep_geocode.testa_conexao(self._url)
        Logger.debug('_processa: %i, %s, %s' % (status, http_code, message))

        if status == OK and http_code != 200:
            Logger.debug('status_operacao_changed: FAIL, %s, %s' %
                         (http_code, message))
            self.status_operacao_changed.emit(FAIL, http_code, message)
            return
        elif status == FAIL:
            Logger.debug('status_operacao_changed: FAIL, 0, "%s"' % message)
            self.status_operacao_changed.emit(FAIL, 0, message)
            return

        colunas = self._colunas_escolhidas[:]
        dados_preparados = prep_files.prepara_dados(
            self._dados_arquivo_original, colunas)
        dados_padronizados = prep_files.padroniza_dados(dados_preparados)

        prep_files.gera_arquivo(self._dados_arquivo_original, 'original',
                                self._arquivo, self._colunas_disponiveis)

        labels_arquivo_geocode = [
            'KEY', 'COLUNA_PESQ', 'DADO_COMPL_PESQ', 'DADO_PESQ',
            'LOCAL_ENCONTRADO', 'SIMILARIDADE', 'LAT', 'LONG'
        ]

        fatias = list(
            prep_geocode.fatia_lista(dados_padronizados,
                                     self._registros_por_arquivo))
        val = 0

        try:
            for v in fatias:
                val += 1
                dct_pesquisa = {
                    'prioridade': colunas,
                    'dados': v,
                    'geocode_service': self._url
                }
                lista_final = prep_geocode.gera_lista_final(
                    dct_pesquisa, self.atualiza_progresso)
                prep_files.gera_arquivo(lista_final, 'geocode' + str(val),
                                        self._arquivo, labels_arquivo_geocode)
        except ThreadInterrompidaError:
            Logger.debug('** interrompido pelo usuário')
            self.status_operacao_changed.emit(INTERRUPTED, 0, '')
            return

        self.arquivos_gerados.emit(self.lista_arquivos_gerados())

        # Fecha pop up de progresso
        Logger.debug('status_operacao_changed: OK, 0, ""')
        self.status_operacao_changed.emit(OK, 0, '')
Exemplo n.º 5
0
def testa_conexao(geocode_service):
    '''
    Recebe a descrição de um local e faz a pesquisa do mesmo na API de geocodificação
    '''
    try:
        consulta = geocode_service + '/?{0}' if geocode_service[
            -1] != '/' else geocode_service + '?{0}'
        parametros = urllib.parse.urlencode({'localidade': '', 'limite': '1'})
        result = urllib.request.urlopen(consulta.format(parametros))
        http_code = result.code
        return OK, http_code, result.read()
    except Exception as e:
        Logger.error(
            'prep_geocode: Erro ao consultar API de geocodificação: %s' % e)
        return FAIL, 0, '%s' % e
Exemplo n.º 6
0
def padroniza_dados(dados):
    '''
    Recebe lista de dicionários com chave e colunas a serem geocodificadas, aplica a função 'troca_verbetes' para cada coluna e retorna nova lista.
    '''
    try:
        for d in dados:
            c = d.keys()
            chaves = list(c)
            chaves.remove(label_key)
            for k in chaves:
                valor = d[k]
                d[k] = _troca_verbetes(valor)
        return dados
    except Exception as e:
        Logger.error(
            'prep_files: Erro ao padronizar dados para geocodificação: %s' % e)
Exemplo n.º 7
0
def prepara_dados(dados, campos_selecionados):
    '''
    Recebe lista dos dados do arquivo original e as colunas a serem geocodificadas. Retorna lista de dicionários com a chave e com as colunas recebidas.
    '''
    try:
        dados_pesquisa = []
        for d in dados:
            dct = {}
            dct[label_key] = d[label_key]
            for c in campos_selecionados:
                if c in list(d.keys()):
                    dct[c] = d[c]
            dados_pesquisa.append(dct)
        return dados_pesquisa
    except Exception as e:
        Logger.error(
            'prep_files: Erro ao preparar dados para geocodificação: %s' % e)
Exemplo n.º 8
0
def _avalia_resultado(dado_busca, str_json):
    '''
    Recebe a string resultante da consulta à API e a string consultada.
    Retorna dicionário com local encontrado, similaridade e coordenadas (latitude e longitude)
    '''
    try:
        geojson = loads(str_json)
        features = geojson['features']

        if features:
            dados = []
            for f in features:
                # nome_local = f['properties']['nome'].encode('utf8')
                nome_local = f['properties']['nome']

                local = {
                    'LOCAL_ENCONTRADO': nome_local,
                    'COORDENADAS': f['geometry']['coordinates']
                }
                dados.append(local)

            for d in dados:
                # similaridade = round(SequenceMatcher(None, d['LOCAL_ENCONTRADO'].ljust(maior).upper(), dado_busca.upper()).ratio(), 5)
                similaridade = round(
                    SequenceMatcher(None, d['LOCAL_ENCONTRADO'].upper(),
                                    dado_busca.upper()).ratio(), 5)
                d.update({'SIMILARIDADE': similaridade})

            dados_ordenados = sorted(dados, key=itemgetter('SIMILARIDADE'))
            melhor_resultado = dados_ordenados[-1]
            melhor_resultado.update({
                'LONG': melhor_resultado['COORDENADAS'][0],
                'LAT': melhor_resultado['COORDENADAS'][1]
            })
            del melhor_resultado['COORDENADAS']

            return melhor_resultado
        else:
            resultado = {}
            return resultado

    except Exception as e:
        Logger.error('prep_geocode: Erro ao gerar lista final: %s' % e)
Exemplo n.º 9
0
    def filtra_dados(self, filtro_coluna, filtro_valor):
        Logger.debug("%s, %s" % (filtro_coluna, filtro_valor))

        if filtro_coluna in self.colunas_disponiveis:
            dados = self._dados_arquivo_original[:]

            for linha in dados:
                if linha[filtro_coluna] != filtro_valor:
                    self._dados_arquivo_original.remove(linha)

            if len(self._dados_arquivo_original) == 0:
                self._dados_arquivo_original = dados[:]
                self._filtro_ignorado = True
            else:
                self._filtro_ignorado = False
        else:
            self._filtro_ignorado = False

        Logger.debug(
            'Filtro: %i registro(s) para {%s: %s}' %
            (len(self._dados_arquivo_original), filtro_coluna, filtro_valor))
Exemplo n.º 10
0
def _consulta_api(local, geocode_service):
    '''
    Recebe a descrição de um local e faz a pesquisa do mesmo na API de geocodificação
    '''
    try:
        consulta = geocode_service + '/?{0}' if geocode_service[
            -1] != '/' else geocode_service + '?{0}'
        parametros = urllib.parse.urlencode({
            'localidade': local,
            'limite': '33'
        })
        url = consulta.format(parametros)
        Logger.debug('prep_geocode: %s' % url)
        result = urllib.request.urlopen(url)
        result_set = result.read()
        str_json = result_set.decode('utf-8')
        return str_json

    except Exception as e:
        Logger.error(
            'prep_geocode: Erro ao consultar API de geocodificação: %s' % e)
Exemplo n.º 11
0
def lista_colunas_e_dados(arquivo_original, delimitador):
    '''
    Abre arquivo csv original e adiciona uma chave única a cada registro. Retorna lista de registros (cada registro é um dicionário) e lista com elementos do cabeçalho do arquivo original.
    '''
    try:
        with open(arquivo_original, encoding=_encoding) as arquivo:
            dict_reader = csv.DictReader(arquivo, delimiter=str(delimitador))
            # dict_reader = csv.DictReader(arquivo, delimiter=str(delimitador), dialect='excel')
            headers_arquivo = dict_reader.fieldnames
            linhas = []
            for l in dict_reader:
                if None not in l.keys() and None not in l.values():
                    key = uuid.uuid4()
                    l[label_key] = str(key)
                    linhas.append(l)

        Logger.debug('prep_files: linhas = %i.' % len(linhas))
        return linhas, headers_arquivo

    except (IOError, TypeError, csv.Error) as e:
        Logger.error('prep_files: Erro ao manipular arquivo original: %s' % e)
        raise e
    except Exception as e:
        Logger.error('prep_files: Verifique o arquivo csv de entrada: %s' % e)
        raise e
Exemplo n.º 12
0
def _consulta_geocode(string_pesquisa, coluna, geocode_service):
    '''
    Recebe a string a ser geocodificada e sua coluna correspondente.
    Consulta a API de geocodificação e avalia o resultado, retornando o dicionário que será inserido na lista final.
    '''
    try:
        dct = {}
        encontrou = False

        str_pesquisa = _remove_acentos(string_pesquisa)
        dado_reduzido = _reduz_dado(str_pesquisa)

        for d in dado_reduzido[::-1]:
            str_json = _consulta_api(d, geocode_service)
            resultado_consulta = _avalia_resultado(d, str_json)

            if resultado_consulta:
                dct.update({
                    'COLUNA_PESQ': coluna,
                    'DADO_COMPL_PESQ': dado_reduzido[-1],
                    'DADO_PESQ': d
                })
                dct.update(resultado_consulta)
                encontrou = True
                break

        if encontrou == False:
            dct.update({
                'COLUNA_PESQ': 'ALL',
                'DADO_COMPL_PESQ': 'ALL',
                'DADO_PESQ': 'ALL',
                'LONG': 'NOT FOUND',
                'LAT': 'NOT FOUND',
                'LOCAL_ENCONTRADO': 'NOT FOUND',
                'SIMILARIDADE': 0.0
            })
        return dct

    except Exception as e:
        Logger.error('prep_geocode: Erro ao montar novo registro: %s' % e)
Exemplo n.º 13
0
    def lista_arquivos_gerados(self):
        try:
            diretorio, arquivo_saida = prep_files._identifica_diretorio(
                self._arquivo)
            diretorio_saida = os.path.join(
                diretorio, 'files_%s' % arquivo_saida.replace('.csv', ''))

            if os.path.exists(diretorio_saida):
                lista_arquivos = os.listdir(diretorio_saida)
                lista_arquivos_ordenada = sorted(lista_arquivos)

                text_label = 'Arquivos gerados:\n\t' + diretorio_saida

                for i in lista_arquivos_ordenada:
                    text_label += ('\n\t\t' + i)

            else:
                text_label = 'Houve um problema ao acessar o diretório de saída. Verifique se novos arquivos foram gerados no diretório do arquivo csv original.'
        except Exception as e:
            Logger.error('%s' % e)
            raise e
            text_label = 'Verifique se novos arquivos foram gerados no diretório do arquivo csv original.'
        Logger.debug(text_label)
        return text_label
Exemplo n.º 14
0
def gera_lista_final(dct_pesquisa, atualiza_progresso=lambda: True):
    '''
    Recebe dicionário com dados do arquivo CSV (lista de dicionários com a chave e com as colunas a serem geocodificadas) e lista de colunas na ordem em que deve ser feita a geocodificação. Monta a lista final que será gravada em novo arquivo csv aplicando a função _consulta_geocode para cada registro.
    '''
    try:
        dados = dct_pesquisa['dados']
        colunas = dct_pesquisa['prioridade']
        geocode_service = dct_pesquisa['geocode_service']
        dados_finais = []
        total = len(dados)
        ct = 1

        for d in dados:
            lb_key = 'KEY'
            key = d[lb_key]
            dct = {lb_key: key}

            for c in colunas:
                if c in list(d.keys()):
                    result_set = _consulta_geocode(d[c], c, geocode_service)
                    dct.update(result_set)
                    if dct['SIMILARIDADE'] != 0.0:
                        break

            dados_finais.append(dct)

            # Atualiza contador de progresso
            if not atualiza_progresso(ct):
                raise ThreadInterrompidaError()
            else:
                Logger.debug('prep_geocode: {0} de {1}'.format(ct, total))
                ct += 1

        return dados_finais

    except ThreadInterrompidaError as e:
        Logger.error(
            'prep_geocode: interrupção por usuário foi detectada: %s' % e)
        raise e

    except Exception as e:
        Logger.error('prep_geocode: Erro ao gerar lista final: %s' % e)
Exemplo n.º 15
0
    def filtra_coluna(self, coluna):
        Logger.debug('coluna = "%s"' % coluna)
        self._valores_filtrados = []
        self._coluna_filtrada = coluna

        if coluna in self._colunas_disponiveis:
            conj_valores = set()

            for dado in self._dados_arquivo_original:
                conj_valores.add(dado[coluna])
                if len(conj_valores) >= 100:
                    break

            valores_unicos = list(conj_valores)
            muitos_valores = '%d valores possíveis.' % len(valores_unicos)
            self._valores_filtrados.extend(valores_unicos if len(
                valores_unicos) <= 100 else [muitos_valores])
            Logger.debug('%d valores encontrados para a coluna "%s".' %
                         (len(valores_unicos), coluna))
        else:
            self._valores_filtrados = []
            Logger.debug('0 valor encontrados para a coluna "%s".' % coluna)

        self.valores_filtrados_changed.emit(self._valores_filtrados)
Exemplo n.º 16
0
 def adiciona_coluna(self, coluna):
     Logger.debug("adiciona '%s'" % coluna)
     self._colunas_escolhidas.append(coluna)
Exemplo n.º 17
0
 def operacao_terminada(self, status, http_code, mensagem):
     """Faz limpeza de thread depois que ela termina."""
     Logger.debug('operacao_terminada: %i, %s, "%s"' %
                  (status, http_code, mensagem))
     self._thread_operacao.join()
Exemplo n.º 18
0
 def cancela_operacao(self):
     """Deve ser chamado de fora de thread."""
     Logger.debug('cancela_operacao() chamado.')
     self._thread_operacao.stop()
     self._thread_operacao.join()
Exemplo n.º 19
0
 def remove_coluna(self, coluna):
     Logger.debug("removendo '%s'" % coluna)
     self._colunas_escolhidas.remove(coluna)
Exemplo n.º 20
0
 def define_quantidade_registros(self, qtd_registros: int):
     tam = len(self._dados_arquivo_original)
     qtd_registros = int(qtd_registros)
     Logger.debug('Contador de %s elementos selecionado' % qtd_registros)
     self._registros_por_arquivo = tam if (qtd_registros
                                           == -1) else qtd_registros
Exemplo n.º 21
0
import uuid

from config import API_USER_NAME, API_USER_PASS, LOG_LEVEL
from flask import request, Response
from logger import StdoutLogger

basic_logger = StdoutLogger(LOG_LEVEL)


class LoggingMiddleware(object):
    def __init__(self, logger: StdoutLogger, api_method, api_path, **kwargs):
        self.logger = logger
        self.extra = {
            'api_id': uuid.uuid4(),
            'api_method': api_method,
            'api_path': api_path
        }
        if kwargs:
            self.extra.update(kwargs)

    def debug(self, msg):
        self.logger.debug(msg, extra=self.extra)

    def info(self, msg):
        self.logger.info(msg, extra=self.extra)

    def warning(self, msg):
        self.logger.warning(msg, extra=self.extra)

    def error(self, msg):
        self.logger.error(msg, extra=self.extra)
Exemplo n.º 22
0
 def inicia_operacao(self):
     """Deve ser chamado de fora de thread."""
     Logger.debug('inicia_operacao() chamado.')
     self.status_operacao_changed.connect(self.operacao_terminada)
     self._thread_operacao = ThreadCancelavel(target=self._processa)
     self._thread_operacao.start()