def update(sql_uri, inicio, fim): engine = create_engine(sql_uri) Session = sessionmaker(bind=engine) session = Session() if inicio is None: qry = session.query(func.max( OVR.datahora).label('last_date')).filter(OVR.tipooperacao == 0) res = qry.one() last_date = res.last_date if last_date > datetime.today(): logger.warning( f'Data de inicio no banco está no futuro : {last_date} !!!') last_date = datetime.today() start = last_date - timedelta(days=14) else: start = datetime.strptime(inicio, '%d/%m/%Y') if fim is None: end = datetime.today() else: end = datetime.strptime(fim, '%d/%m/%Y') print(start, end) # recinto = Recinto() # recinto.cod_dte = 22 # recintos_list = [recinto] recintos_list = session.query(Recinto).filter( Recinto.cod_dte.isnot(None)).all() lista_recintos_fmas = get_lista_fma_recintos(recintos_list, start, end) processa_lista_fma(session, lista_recintos_fmas) update_cnpj_fiscalizado_historico(session)
def tomongo(self, fs): """Salva instância em GridFS MongoDB. Checa se arquivo existe antes de gravar. Se existir, retorna _id correspondente ao MD5 do conteúdo **IMPORTANTE** A checagem é realizada pelo nome do arquivo E pelo conteúdo, através de um digest MD5. Ou seja, serão aceitos dois arquivos no GridFS com mesmo nome e conteúdo diferente (o que pode indicar erro ou fraude na fonte das imagens e precisará ser tratado), só rejeitando no caso de o conteúdo ser o mesmo, que será interpretado como tentativa de carregar novamente o mesmo arquivo. O hash MD5 não é perfeito, podendo haver colisões, mas como é o padrão do MongoDB por ora será utilizado, mesmo porque a possibilidade de colisão no nome do arquivo E no hash é extremamente baixa. """ m = md5() m.update(self._content) grid_out = fs.find_one({'md5': m.hexdigest()}) if grid_out: if grid_out.filename == self._filename: logger.warning( self._filename + ' MD5(' + m.hexdigest() + ')' + ' tentativa de inserir pela segunda vez!!') # File exists, abort! return grid_out._id # Insert File return fs.put(self._content, filename=self._filename, metadata=self._metadata)
def call_model(model: str, image: Image)-> dict: """Grava requisição no redisdb e aguarda retorno até timeout. Args: model: string com uma chave do dicionário de modelos ativos image: PIL Image Returns: dict {'success', 'predictions', 'erro'} success: True ou False predictions: lista de dicts de predições em caso de sucesso erro: mensagem de erro se acontecer """ if platform == 'win32': return win32_call_model(model, image) logger.info('Enter Sandman - sending request to queue') # generate an ID then add the ID + image to the queue k = str(uuid.uuid4()) d = {'model': model, 'id': k, 'image': image} redisdb.rpush(PADMA_REDIS, pickle.dumps(d, protocol=1)) s0 = time.time() output = {'success': False, 'predictions': []} try: while True: # attempt to grab the output predictions output = redisdb.get(k) # check to see if our model has classified the input image if output is not None: output = output.decode('utf-8') output = json.loads(output) # delete the result from the database and exit loop redisdb.delete(k) break time.sleep(CLIENT_SLEEP) s1 = time.time() if s1 - s0 > CLIENT_TIMEOUT: # Timeout logger.warning('Timeout!!!! Modelo %s ID %s' % (model, k)) redisdb.delete(k) return {'success': False, 'erro': 'Timeout!!!'} finally: return output
def exporta_csv(): """Grava em arquivo parâmetros ativos. """ session = app.config.get('dbsession') try: riscos_out_filename = 'riscos_ativos' + \ datetime.strftime(datetime.now(), '%Y-%m%dT%H%M%S') + \ '.csv' riscos_ativos = riscosativos(session, current_user.name) with open(os.path.join(get_user_save_path(), riscos_out_filename), 'w', newline='') as riscos_out: for risco in riscos_ativos: linha_out = ';'.join( (risco.campo, risco.valor, risco.motivo)) riscos_out.write(linha_out + '\n') return redirect('static/%s/%s' % (current_user.name, riscos_out_filename)) except Exception as err: logger.warning(err, exc_info=True) flash(str(err)) return redirect(url_for('edita_risco'))
def rvf_OVR(): session = app.config.get('dbsession') mongodb = app.config.get('mongo_risco') rvf_id = request.args.get('rvf_id') tipo = request.args.get('tipo', 'OVR') try: rvf = get_rvf(session, rvf_id) if rvf is None: flash('rvf %s não encontrado.' % rvf_id) return redirect(url_for('pesquisa_rvf')) OVR_out_filename = '{}_FCC{}-{}.docx'.format( tipo, rvf_id, datetime.strftime(datetime.now(), '%Y-%m%dT%H%M%S')) rvf_dump = OVRDict(1).monta_rvf_dict(mongodb, session, rvf_id) if tipo == 'OVR': document = gera_OVR(rvf_dump, current_user.name) else: document = gera_taseda(rvf_dump, current_user.name) document.save(os.path.join(get_user_save_path(), OVR_out_filename)) return redirect('static/%s/%s' % (current_user.name, OVR_out_filename)) except Exception as err: logger.warning(err, exc_info=True) flash(str(err)) return redirect(url_for('rvf', id=rvf_id, _scheme='https'))
def processa_bson(): """Chama função do módulo dir_monitor. Para permitir o upload de BSON do AVATAR através da simples colocação do arquivo em um diretório. Neste módulo pode ser configurado o endereço de um diretório e o endereço do virasana. A função a seguir varre o diretório e, havendo arquivos, envia por request POST para o URL do virasana. Se obtiver sucesso, exclui o arquivo enviado do diretório. """ print('TESTE') logger.warning('Varrendo diretório...') dir, erros, excecoes = despacha_dir() logger.warning('Varreu diretório %s. Erros %s' % (dir, erros)) logger.warning('Atualizando metadata XML...') num2, num5 = processa_xml() logger.warning('Metadata XML atualizado. ' '%s novos nos últimos cinco dias, ' '%s novos nos últimos dois anos' % (num2, num5))
def classify_process(): # Load the pre-trained models, only once. # Then wait for incoming queries on redis modeldict = dict() logger.info('Carregando modelos Dinâmicos/processo') try: models = os.listdir(MODEL_DIRECTORY) load_models_new_process(modeldict, models) except FileNotFoundError: logger.warning('Caminho %s não encontrado!!!' % MODEL_DIRECTORY) logger.info('Carregando modelos HARDCODED') load_models_hardcoded(modeldict) logger.info('Fim dos carregamentos...') # continually poll for new images to classify while True: # attempt to grab a batch of images from the database time.sleep(SERVER_SLEEP) queue = redisdb.lrange(PADMA_REDIS, 0, BATCH_SIZE - 1) # loop over the queue if queue: cont = 0 model_key = 'nao definido' try: logger.debug('Processing image classify from queue') for q in queue: cont += 1 d = pickle.loads(q) model_key = d.get('model') model_item = modeldict.get(model_key) if model_item is None: try: model_key = str(model_key) except TypeError as err: logger.error(err, exc_info=True) model_key = 'ERRO!!' logger.debug('model_item None model_key %s' % model_key) # Se existir mas não está carregado, carrega do disco. if os.path.exists( os.path.join(MODEL_DIRECTORY, model_key)): load_models_new_process(modeldict, [model_key]) output = { 'success': False, 'erro': 'Modelo %s ainda não carregado.' + \ 'Tente novamente.' % model_key } else: logger.debug( 'Solicitado modelo não existente: "%s"' % model_key) output = { 'success': False, 'erro': 'Modelo não existente: %s.' % model_key, 'modelos': list(modeldict.keys()) } dump = json.dumps(output) redisdb.set(d['id'], dump) else: # Testar se é modelo dinâmico. Se for, não faz nada # pois há outro processo tratando. if not isinstance(model_item, Process): logger.debug('Enviando para thread %s %s' % (model_key, model_item)) t = Thread(target=model_predict, args=([model_item, d['id'], d['image']])) t.daemon = True t.start() # model_predict(model_item, d['id'], d['image']) except Exception as err: logger.error('Erro ao recuperar modelo %s' % model_key) logger.error(str(q)) logger.debug(err, exc_info=True) output = {'success': False, 'erro': str(err)} dump = json.dumps(output) redisdb.set(d['id'], dump) finally: # Testar se é modelo dinâmico. Se for, não faz nada # pois há outro processo tratando. if not isinstance(model_item, Process): redisdb.ltrim(PADMA_REDIS, cont, -1)
def grid_data(): """Executa uma consulta no banco. Monta um dicionário de consulta a partir dos argumentos do get. Se encontrar registro, retorna registro inteiro via JSON (metadados), o arquivo (campo content) fica em fs.chunks e é recuperado pela view image_id. """ # TODO: Refatorar conversões de/para MongoDB - dict - JSON (Ver Bhadrasana, tem algo feito nesse sentido) db = app.config['mongodb'] if request.method == 'POST': # print(request.json) query = request.json['query'] projection = request.json['projection'] query_processed = {} for key, value in query.items(): if isinstance(value, dict): value_processed = {} for key2, value2 in value.items(): try: value_processed[key2] = datetime.strptime( value2, '%Y-%m-%d %H:%M:%S') except: value_processed[key2] = mongo_sanitizar(value2) query_processed[key] = value_processed else: try: query_processed[key] = datetime.strptime( value, '%Y-%m-%d %H:%M:%S') except: query_processed[key] = mongo_sanitizar(value) # logger.warning(query) # logger.warning(query_processed) # query = {mongo_sanitizar(key): mongo_sanitizar(value) # for key, value in query.items()} # projection = {mongo_sanitizar(key): mongo_sanitizar(value) # for key, value in projection.items()} # logger.warning(projection) linhas = db['fs.files'].find(query_processed, projection) result = [] for linha in linhas: dict_linha = {} for key, value in linha.items(): if isinstance(value, dict): value_processed = {} for key2, value2 in value.items(): try: value_processed[key2] = datetime.strptime( value2, '%Y-%m-%d %H:%M:%S') except: value_processed[key2] = str(value2) dict_linha[key] = value_processed else: try: dict_linha[key] = datetime.strptime( value, '%Y-%m-%d %H:%M:%S') except: dict_linha[key] = str(value) result.append(dict_linha) else: filtro = { mongo_sanitizar(key): mongo_sanitizar(value) for key, value in request.args.items() } logger.warning(filtro) linhas = db['fs.files'].find(filtro) result = [{ '_id': str(linha['_id']), 'contentType': str(linha['metadata'].get('contentType')) } for linha in linhas] status_code = 404 if len(result) > 0: status_code = 200 return jsonify(result), status_code
def aplica_juncao_mongo(self, db, visao, parametros_ativos=None, filtrar=False, limit=0, skip=0): """Lê as coleções configuradas no mongo através de aggregates. Monta um pipeline MongoDB. Utiliza configurações da visao para montar um aggregate entre coleções MongoDB. Caso configurado, utiliza as colunas programadas para fazer 'projection', isto é, trazer somente estas do Banco. Também aplica 'match', filtrando os resultados. Args: db: MongoDB visao: objeto de Banco de Dados que espeficica as configurações (metadados) da base parametros_ativos: subconjunto do parâmetros de risco a serem aplicados filtrar: aplica_risco na consulta Returns: Lista contendo os campos filtrados. 1ª linha com nomes de campo. """ base = visao.base numero_juncoes = len(visao.tabelas) collection = None pipeline = [] for r in range(1, numero_juncoes): tabela = visao.tabelas[r] paifilhoname = base.nome + '.' + tabela.csv_table pipeline.append({ '$lookup': { 'from': paifilhoname, 'localField': tabela.primario.lower(), 'foreignField': tabela.estrangeiro.lower(), 'as': tabela.csv_table } }) pipeline.append({'$unwind': {'path': '$' + tabela.csv_table}}) painame = visao.tabelas[0].csv_table collection = db[base.nome + '.' + painame] tabelas = [tabela.csv_table for tabela in visao.tabelas] if visao.colunas: colunas = {'_id': 0} for coluna in visao.colunas: print('Coluna', coluna.nome) print('Tabelas', tabelas) if coluna.nome not in tabelas: colunas[coluna.nome.lower()] = 1 for tabela in tabelas[1:]: colunas[tabela + '.' + coluna.nome.lower()] = 1 pipeline.append({'$project': colunas}) print('FILTRAR', filtrar) if filtrar: print('Entrou em filtro!') filtro = [] if parametros_ativos: riscos = set( [parametro.lower() for parametro in parametros_ativos]) else: riscos = set( [key.lower() for key in self._riscosativos.keys()]) print('RISCOS', riscos) for campo in riscos: dict_filtros = self._riscosativos.get(campo) for tipo_filtro, lista_filtros in dict_filtros.items(): print(tipo_filtro, lista_filtros) # filter_function = filter_functions.get(tipo_filtro) for valor in lista_filtros: filtro.append({campo: valor}) for tabela in visao.tabelas: filtro.append( {tabela.csv_table + '.' + campo: valor}) if filtro: print('FILTRO', filtro) pipeline.append({'$match': {'$or': filtro}}) if limit: pipeline.append({'$limit': skip + limit}) if skip: pipeline.append({'$skip': skip}) print('PIPELINE', pipeline) mongo_list = list(collection.aggregate(pipeline)) # print(mongo_list) if mongo_list and len(mongo_list) > 0: first_line = mongo_list[0] result = [] header = [] for key, value in first_line.items(): # print('VALUE', key, value, type(value)) if isinstance(value, dict): for sub_key in value.keys(): header.append(key + '.' + sub_key) else: header.append(key) result.append(header) for linha in mongo_list: linha_lista = [] for campo in header: hieraquia = campo.split('.') valor = linha for nivel in hieraquia: valor = valor.get(nivel) linha_lista.append(valor) result.append(linha_lista) return result logger.warning('Mongo não retornou linhas!') return None