def despacha(filename, target, sync=SYNC): """Envia por HTTP POST o arquivo especificado. Args: file: caminho completo do arquivo a enviar target: URL do Servidor e API destino Returns: (Erro, Resposta) (True, None) se tudo correr bem (False, response) se ocorrer erro """ bson = open(filename, 'rb') files = {'file': bson} # login() rv = requests.post(target, files=files, data={'sync': sync}) if rv is None: return False, None try: response_json = rv.json() success = response_json.get('success', False) and \ (rv.status_code == requests.codes.ok) except json.decoder.JSONDecodeError as err: logger.error(err, exc_info=True) success = False return success, rv
def cadastra_rvf(session, user_name: str, params: dict = None, ovr_id: int = None) -> Optional[RVF]: rvf = None if ovr_id: ovr = get_ovr(session, ovr_id) if not ovr: return None if params is None: params = {} params['ovr_id'] = ovr.id params['numeroCEmercante'] = ovr.numeroCEmercante rvf = cadastra_rvf(session, user_name, params) elif params: rvf = get_rvf(session, params.get('id')) ovr_id = rvf.ovr_id if rvf.ovr_id else params.get('ovr_id') ovr = get_ovr(session, ovr_id) verifica_permissao_rvf(session, ovr, user_name) for key, value in params.items(): setattr(rvf, key, value) rvf.user_name = user_name rvf.datahora = handle_datahora(params) if rvf is not None: try: session.add(rvf) session.commit() session.refresh(rvf) gera_evento_rvf(session, rvf, user_name) except Exception as err: session.rollback() logger.error(err, exc_info=True) raise err return rvf
def gera_evento_rvf(session, rvf, user_name) -> Optional[EventoOVR]: """Gera Evento de RVF. Regras: - Se já existe EventoEspecial.RVF para o RVF, não cria mais - Somente cria se RVF tiver ao menos 3 imagens - Pode ser uma RVF marcada como inspecaonaoinvasiva. Neste caso é criado, caso não exista, o EventoEspecial.InspecaoNaoInvasiva, se não existir, mesmo sem imagens anexadas """ print(rvf.inspecaonaoinvasiva) if rvf.inspecaonaoinvasiva: tipoevento = session.query(TipoEventoOVR).filter( TipoEventoOVR.eventoespecial == EventoEspecial.InspecaoNaoInvasiva.value).first() else: tipoevento = session.query(TipoEventoOVR).filter( TipoEventoOVR.eventoespecial == EventoEspecial.RVF.value).first() if not tipoevento: if rvf.inspecaonaoinvasiva: logger.error('Tipo Evento InspecaoNaoInvasiva não cadastrado!!!') else: logger.error('Tipo Evento RVF não cadastrado!!!') return None if (not rvf.inspecaonaoinvasiva) and (len(rvf.imagens) < 3): return None evento = session.query(EventoOVR).filter(EventoOVR.ovr_id == rvf.ovr_id). \ filter(EventoOVR.motivo == 'RVF %s' % rvf.id). \ filter(EventoOVR.tipoevento_id == tipoevento.id).one_or_none() if not evento: params = {'tipoevento_id': tipoevento.id, 'motivo': 'RVF %s' % rvf.id, 'user_name': rvf.user_name, 'ovr_id': rvf.ovr_id } evento = gera_eventoovr(session, params, user_name=user_name) return evento
def get_pares(db, _id: ObjectId) -> Tuple[dict, dict]: """Monta pares de contêiner de trânsito. Monta, se houverem, pares de trânsito aduaneiro. Args: db: conexão ao mongo codigo_conteiner: número do contêiner Returns destino, origem -> -> dicts retirados do Mongo (_id, metadata.numeroinformado, metadata.dataescaneamento) """ try: destino = db.fs.files.find_one({'_id': _id}, { 'metadata.numeroinformado': 1, 'metadata.dataescaneamento': 1 }) metadata = destino['metadata'] origem = db.fs.files.find({'metadata.numeroinformado': metadata['numeroinformado'], 'metadata.dataescaneamento': {'$lt': metadata['dataescaneamento']}, 'metadata.recinto': {'$nin': recintos_destino}, 'metadata.contentType': 'image/jpeg'}, {'metadata.numeroinformado': 1, 'metadata.dataescaneamento': 1}). \ sort([('metadata.dataescaneamento', pymongo.DESCENDING)])[0] return destino, origem except Exception as err: logger.error(err, exc_info=True) return (None, None)
def get_pares_periodo(db, inicio: datetime, fim: datetime, save=False, limit=1000, outpath='pares_transito'): result = [] filtro = { 'metadata.dataescaneamento': { '$gt': inicio, '$lt': fim }, 'metadata.recinto': { '$in': recintos_destino }, 'metadata.contentType': 'image/jpeg' } cursor = db.fs.files.find(filtro, {'_id': 1}).limit(limit) for row in cursor: try: if save: # salva pares no disco grava_imagens(db, row['_id'], outpath) else: # retorna pares origem e destino result.append(get_pares(db, row['_id'])) except ValueError as err: logger.error(err) return result
def auto_contrafacao(): session = app.config['dbsession'] db = app.config['mongo_risco'] ovr_id = None tg_id = request.args.get('tg_id') try: usuario = get_usuario(session, current_user.name) if usuario is None: raise Exception('Erro: Usuário não encontrado!') if tg_id: tg = get_tgovr_one(session, tg_id) ovr_id = tg.ovr_id ovr_dict = OVRDict(FonteDocx.TG_Ficha).get_dict( db=db, session=session, id=tg.id) if ovr_dict: document = gera_auto_contrafacao(ovr_dict, current_user.name) nome = 'Auto de Infração' out_filename = '{}_{}_{}.docx'.format( nome, ovr_id, datetime.strftime(datetime.now(), '%Y-%m-%dT%H-%M-%S') ) document.save(os.path.join( get_user_save_path(), out_filename)) return redirect('static/%s/%s' % (current_user.name, out_filename)) except Exception as err: logger.error(err, exc_info=True) flash('Erro! Detalhes no log da aplicação.') flash(str(type(err))) flash(str(err)) return redirect(url_for('autos_contrafacao', ovr_id=ovr_id))
def ver_imagens_rvf(): session = app.config.get('dbsession') rvf_id = None idimagemativa = None anexos = [] marcas = get_marcas_choice(session) oform = ImagemRVFForm(marcas=marcas) try: rvf_id = request.args.get('rvf_id') idimagemativa = request.args.get('imagem') if rvf_id is None: raise Exception('RVF não informado!!!') rvf = get_rvf(session, rvf_id) anexos = get_ids_anexos_ordenado(rvf) aimagemrvf = get_imagemrvf_or_none(session, rvf_id, idimagemativa) if aimagemrvf is not None: oform = ImagemRVFForm(**aimagemrvf.__dict__, marcas=marcas) oform.rvf_id.data = rvf_id oform.imagem.data = idimagemativa except Exception as err: logger.error(err, exc_info=True) flash('Erro! Detalhes no log da aplicação.') flash(str(type(err))) flash(str(err)) return render_template('imagens_rvf.html', rvf_id=rvf_id, oform=oform, imagemativa=idimagemativa, anexos=anexos)
def moeda(value): value = convert_value(value) if isinstance(value, str): logger.error('moeda: %s' % value) return value return 'R$ {:,.2f}'.format(float(value)).replace(',', 'X'). \ replace('.', ',').replace('X', '.')
def processa_classes(engine, lista_arquivos): count_objetos = Counter() lista_erros = [] try: for arquivo in lista_arquivos: logger.info('(processa_classes)Processando arquivo xml %s' % arquivo) xtree = ElementTree.parse( os.path.join(mercante.MERCANTE_DIR, arquivo)) xroot = xtree.getroot() objetos = [] for node in xroot: classe = mercante.classes.get(node.tag) if classe: count_objetos[classe] += 1 objeto = classe() objeto._parse_node(node) objetos.append(objeto._to_dict()) df = pd.DataFrame(objetos) df.reset_index() df.to_sql(node.tag, engine, if_exists='append', index=False) except Exception as err: logger.error('Erro ocorrido no arquivo %s. %s' % (arquivo, err)) lista_erros.append(arquivo) return count_objetos, lista_erros
def consulta_padma(image, model): """Monta request para o PADMA. Trata JSON resposta. Args: image: bytes image model: nome do modelo a consultar Returns: dict com as predições """ global token data = {} data['image'] = image headers = {} result = {'predictions': [], 'success': False} s = requests.Session() username, password = get_service_password() if token is None: # print(username, password) r = login(username, password, s) try: r = s.post(PADMA_URL + '/predict?model=' + model, files=data, headers=headers) if r.status_code == 200: result = r.json() # print(r.json()) except JSONDecodeError as err: logger.error('Erro em consulta_padma(JSON inválido) %s HTTP Code:%s ' % (err, r.status_code)) return result
def dog_id(): session = current_app.config['db_session'] dog = None oform = DogForm() try: if current_user.name in NAOGOSTADECACHORRO: raise Exception('Usuário proibido. Não gosta de cachorro!') if request.method == 'POST': oform = DogForm(request.form) if oform.validate(): dog = Dog() dog.nome = oform.nome dog.formatura = oform.formatura session.add(dog) try: session.commit() except Exception as err: session.rollback() raise err else: flash(oform) else: dog_id = request.args.get('id') if dog_id: dog = session.query(Dog).filter(Dog.id == dog_id).one_or_none() oform = DogForm(**dog.__dict__) if dog is None: flash('Cachorro não encontrado!') except Exception as err: logger.error(err, exc_info=True) flash(str(err)) return render_template('dog.html', oform=oform)
def duas_casas_decimais(value): value = convert_value(value) if isinstance(value, str): logger.error('uma_casa_decimal: %s' % value) return value return '{0:,.2f}'.format(value).replace(',', 'X'). \ replace('.', ',').replace('X', '.')
def novo_docx(): """Cadastro um novo modelo docx""" session = app.config['dbsession'] db = app.config['mongo_risco'] try: modeloform = ModeloDocxForm(request.form) file = request.files.get('documento') if file: validfile, mensagem = \ valid_file(file, extensions=['docx']) if validfile: if request.form.get('incluir'): # Inclui docx no mongo inclui_docx(db, session, modeloform.filename.data, modeloform.fonte_docx_id.data, file) else: # Apenas preenche para teste rápido arquivos = gerar_arquivos_docx(db, session, file, modeloform.filename.data, modeloform.fonte_docx_id.data, modeloform.oid.data) formdocx = FiltroDocxForm() return render_template('gera_docx.html', formdocx=formdocx, modeloform=modeloform, arquivos=arquivos) else: flash(mensagem) except Exception as err: logger.error(err, exc_info=True) flash('Erro! Detalhes no log da aplicação.') flash(str(type(err))) flash(str(err)) return redirect(url_for('gera_docx'))
def sem_casa_decimal(value): value = convert_value(value) if isinstance(value, str): logger.error('sem_casa_decimal: %s' % value) return value return '{0:,.0f}'.format(value).replace(',', 'X'). \ replace('.', ',').replace('X', '.')
def processa_classes_em_lista(engine, lista_arquivos): count_objetos = Counter() lista_erros = [] for arquivo in lista_arquivos: xtree = ElementTree.parse(os.path.join(mercante.MERCANTE_DIR, arquivo)) xroot = xtree.getroot() objetos = [] for node in xroot: classe = mercante.classes_em_lista.get(node.tag) if classe: classe_pai = mercante.classes.get(node.tag) objeto_pai = classe_pai() objeto_pai._parse_node(node) tag_classe = classe._tag for subnode in node.findall(tag_classe): count_objetos[classe] += 1 objeto = classe(objeto_pai) objeto._parse_node(subnode) objetos.append(objeto._to_dict()) if objetos and len(objetos) > 0: df = pd.DataFrame(objetos) classname = objeto.__class__.__name__ try: df.to_sql(classname, engine, if_exists='append') except Exception as err: logger.error('Erro ocorrido no arquivo %s. %s' % (arquivo, err)) lista_erros.append(arquivo) return count_objetos, lista_erros
def edita_descricao_rvf(): session = app.config.get('dbsession') try: descricao = request.form.get('descricao') if descricao is None: raise ValueError('Digite a descrição') try: rvf_id = request.form.get('rvf_id') except TypeError: raise TypeError('Informe o id do RVF') except ValueError: raise ValueError('Informe id do RVF somente com números') arvf = session.query(RVF).filter(RVF.id == rvf_id).one_or_none() if arvf is None: return jsonify({'msg': 'RVF %s não encontrado' % rvf_id}), 404 if arvf.descricao is None: arvf.descricao = descricao else: arvf.descricao = arvf.descricao + ' ' + descricao session.add(arvf) session.commit() session.refresh(arvf) logger.info(arvf.descricao) return jsonify(arvf.dump()), 201 except Exception as err: logger.error(err, exc_info=True) return 'Erro! Detalhes no log da aplicação. ' + str(err), 500
def bar_plotly(linhas: list, nome: str) -> str: """Renderiza gráfico no plotly e serializa via HTTP/HTML.""" meses = { 1: 'Janeiro', 2: 'Fevereiro', 3: 'Março', 4: 'Abril', 5: 'Maio', 6: 'Junho', 7: 'Julho', 8: 'Agosto', 9: 'Setembro', 10: 'Outubro', 11: 'Novembro', 12: 'Dezembro' } try: # Converter decimal para float linhas_float = [] for linha in linhas[1:]: linha_float = [] for item in linha: if isinstance(item, Decimal): linha_float.append(float(item)) else: linha_float.append(item) linhas_float.append(linha_float) df = pd.DataFrame(linhas_float, columns=linhas[0]) df['strmes'] = df['Mês'].apply(lambda x: meses[int(x)]) df['Ano e Mês'] = df['Ano'].astype(str) + '-' + df['Mês'].astype(str).str.zfill(2) \ + '-' + df['strmes'].astype(str) + ' de ' + df['Ano'].astype(str) df = df.drop(columns=['Ano', 'Mês', 'strmes']) print(df.head()) df = df.groupby(['Ano e Mês']).sum() # Apenas para dar a ordem correta df = df.reset_index() # print(linhas) print(df.head()) # print(df.dtypes) x = df['Ano e Mês'].tolist() df = df.drop(columns=['Ano e Mês']) numeric_columns = df.select_dtypes(include=np.number).columns.tolist() data = [ go.Bar(x=x, y=df[column].tolist(), name=column) for column in numeric_columns ] plot = plotly.offline.plot( { 'data': data, 'layout': go.Layout(title=nome + ' soma mensal', xaxis=go.layout.XAxis(type='category')) }, show_link=False, output_type='div', image_width=400) return plot except Exception as err: logger.error(str(err), exc_info=True) return ''
def get_dados_conteiner(grid_data): try: metadata_carga = get_metadata_carga(grid_data) if metadata_carga: tipo, descricaotipo = get_tipo_manifesto(grid_data) if metadata_carga.get('vazio'): conteiner = metadata_carga.get('container') if isinstance(conteiner, list) and len(conteiner) > 0: conteiner = conteiner[0] if not conteiner: return '' tara = monta_float(conteiner.get('tara(kg)')) return 'Contêiner VAZIO Tara: %d %s' % (tara, descricaotipo) conhecimento = metadata_carga.get('conhecimento') if conhecimento is None: return '' if isinstance(conhecimento, list) and len(conhecimento) > 0: conhecimento = conhecimento[0] descricao = conhecimento.get('descricaomercadoria')[:240] descricao = descricao[:60] + ' ' + descricao[60:120] + \ ' ' + descricao[120:180] + ' ' + descricao[180:241] return '%s - %s' % (descricaotipo, descricao) except Exception as err: logger.error(err, exc_info=True) return ''
def processa_planilha(filename) -> Tuple[bool, str]: """Recebe nome de arquivo, processa, retorna False se ocorreram erros. """ def threaded_upload(recinto, mapa, df): headers = get_login_headers() count = upload_eventos(recinto, mapa, df, headers) logger.info('{} processados de {:d} linhas na planilha {}'.format( count, len(df), filename)) if 'BTP' in filename: recinto = 'BTP' mapa = mapa_BTP funcao_processamento = processa_planilha_BTP else: recinto = 'SBT' mapa = mapa_SBT funcao_processamento = processa_planilha_SBT df = [] try: df = funcao_processamento(filename) thread = Thread(target=threaded_upload, args=(recinto, mapa, df)) thread.daemon = True thread.start() return True, str(len(df)) except Exception as err: logger.error(err, exc_info=True) return False, str(err)
def model_process(model: str): try: local_model = BaseModel(os.path.join(MODEL_DIRECTORY, model)) except Exception as err: local_model = FailLoadModel(str(err)) logger.debug(err, exc_info=True) # continually poll for new images to classify while True: time.sleep(SERVER_SLEEP) queue = redisdb.lrange(PADMA_REDIS, 0, BATCH_SIZE - 1) if queue: logger.debug('Processo %s - processing image classify from queue' % model) for cont, q in enumerate(queue, 1): d = pickle.loads(q) model_key = d.get('model') logger.debug(model_key + ' - ' + model) if model_key == model: try: # t = Thread(target=model_predict, args=( # [local_model, d['id'], d['image']])) # t.daemon = True # t.start() model_predict(local_model, 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: redisdb.ltrim(PADMA_REDIS, cont, -1)
def aplicar_risco_mongo(self, visaoid, padraoid, parametros_ativos, dest_path): """Chama função de aplicação de risco e grava resultado em arquivo.""" mensagem = 'Aguarde. Aplicando risco no MongoDB. Visão: ' + visaoid self.update_state(state=states.STARTED, meta={'status': mensagem}) mysession = MySession(Base) dbsession = mysession.session conn = MongoClient(host=MONGODB_URI) db = conn[DATABASE] gerente = GerenteRisco() try: self.update_state(state=states.PENDING, meta={'status': mensagem}) lista_risco = gerente.aplica_risco_por_parametros( dbsession, visaoid=visaoid, padraoid=padraoid, parametros_ativos=parametros_ativos, base_csv=None, db=db) if lista_risco: csv_salvo = os.path.join( dest_path, datetime.today().strftime('%Y-%m-%d-%H:%M:%S') + '.csv') gerente.save_csv(lista_risco, csv_salvo) return {'status': 'Planilha criada com sucesso a partir do MongoDB'} except Exception as err: logger.error(err, exc_info=True) self.update_state(state=states.FAILURE, meta={'status': str(err)})
def inclui_risco(): session = app.config.get('dbsession') user_name = current_user.name campoid = request.form.get('campo') active_tab = request.form.get('active_tab', 'carga') if campoid == '0': flash('Selecionar campo') return redirect(url_for('edita_risco')) campo = dict(CAMPOS_RISCO[active_tab])[campoid] valor = request.form.get('valor') motivo = request.form.get('motivo') # print(user_name, campo, valor, motivo) try: insererisco(session, user_name=user_name, campo=campo, valor=valor, motivo=motivo) except Exception as err: logger.error(err, exc_info=True) flash('Erro ao incluir risco! ' 'Detalhes no log da aplicação.') flash(str(type(err))) flash(str(err)) return redirect(url_for('edita_risco', active_tab=active_tab))
def arquiva_base_csv(self, baseid, base_csv): """Copia CSVs para MongoDB e apaga do disco.""" # Aviso: Esta função rmtree só deve ser utilizada com caminhos seguros, # de preferência gerados pela própria aplicação self.update_state(state=states.STARTED, meta={'status': 'Aguarde. Arquivando base ' + base_csv}) mysession = MySession(Base) dbsession = mysession.session try: abase = dbsession.query(BaseOrigem).filter( BaseOrigem.id == baseid).first() self.update_state(state=states.PENDING, meta={ 'status': 'Aguarde... arquivando base ' + base_csv + ' na base MongoDB ' + abase.nome }) conn = MongoClient(host=MONGODB_URI) db = conn[DATABASE] GerenteRisco.csv_to_mongo(db, abase, base_csv) shutil.rmtree(base_csv) return {'status': 'Base arquivada com sucesso'} except Exception as err: logger.error(err, exc_info=True) self.update_state(state=states.FAILURE, meta={'status': str(err)})
def aplicar_risco(self, base_csv: str, padraoid: int, visaoid: int, parametros_ativos: list, dest_path: str): """Chama função de aplicação de risco e grava resultado em arquivo.""" mensagem = 'Aguarde. Aplicando risco na base ' + \ '-'.join(base_csv.split('/')[-3:]) self.update_state(state=states.STARTED, meta={'status': mensagem}) mysession = MySession(Base) dbsession = mysession.session gerente = GerenteRisco() try: self.update_state(state=states.PENDING, meta={'status': mensagem}) lista_risco = gerente.aplica_risco_por_parametros( dbsession, padraoid=padraoid, visaoid=visaoid, parametros_ativos=parametros_ativos, base_csv=base_csv) if lista_risco: csv_salvo = os.path.join( dest_path, datetime.today().strftime('%Y-%m-%d-%H:%M:%S') + '.csv') gerente.save_csv(lista_risco, csv_salvo) return {'status': 'Planilha criada com sucesso'} except Exception as err: logger.error(str(err), exc_info=True) self.update_state(state=states.FAILURE, meta={'status': str(err)})
def tag_del(): """Função para exclusão de tag na imagem Faz update no fs.files, excluindo do array o nome do usuário ativo e a tag passada, se existir. Args: _id: ObjectId do arquivo tag: String (app usa lista de códigos com tupla (id, desc)) Returns: json['success']: True ou False """ _id = request.values.get('_id') tag = request.values.get('tag') data = {'success': False} try: db = app.config['mongodb'] tags = Tags(db) data['success'] = tags.delete(_id=ObjectId(_id), usuario=current_user.id, tag=tag) data['tags'] = tags.list(ObjectId(_id)) except Exception as err: logger.error(err, exc_info=True) data['error'] = str(err) # raise return jsonify(data)
def ocorrencia_del(): """Função para exclusão de ocorrência na imagem Faz update no fs.files, excluindo do array a id_ocorrencia Args: _id: ObjectId do arquivo id_ocorrencia: String (texto) Returns: image_ocorrencia, passando data['success']: True ou False """ _id = request.values.get('_id') id_ocorrencia = request.values.get('id_ocorrencia') try: db = app.config['mongodb'] ocorrencias = Ocorrencias(db) success = ocorrencias.delete(_id=ObjectId(_id), id_ocorrencia=id_ocorrencia) except Exception as err: logger.error(err, exc_info=True) return jsonify({'erro': str(err)}) return image_ocorrencia(_id, success)
def ocorrencia_add(): """Função para inserção de ocorrência na imagem Faz update no fs.files, inserindo em um array o nome do usuário ativo e o texto da ocorrência passada. Args: _id: ObjectId do arquivo texto: String (texto) Returns: json['success']: True ou False """ _id = request.values.get('_id') texto = request.values.get('texto') try: db = app.config['mongodb'] ocorrencias = Ocorrencias(db) success = ocorrencias.add(_id=ObjectId(_id), usuario=current_user.id, texto=texto) except Exception as err: logger.error(err, exc_info=True) return jsonify({'erro': str(err)}) return image_ocorrencia(_id, success)
def similar_file(): """Retorna índice de imagens similares.""" if request.method == 'POST': # check if the post request has the file part file = request.files.get('file') validfile, mensagem = valid_file(file, extensions=['jpg', 'jpeg', 'png']) if not validfile: flash(mensagem) return redirect(request.url) content = file.read() img_search = app.config['img_search'] index = consulta_padma(content, 'index') # print(index) try: code = index.get('predictions')[0].get('code') except Exception as err: logger.error(err) code = None if code is not None: _ = img_search.get_chunk(file.filename, index=code) return redirect(url_for('similar', _id=file.filename)) else: flash('Erro ao consultar index no PADMA. Checar logs do PADMA') return render_template('upload_file.html')
def rvf_ordena_por_data_criacao(): session = app.config.get('dbsession') rvf_id = request.args.get('rvf_id') try: rvf_ordena_imagensrvf_por_data_criacao(session, rvf_id) except Exception as err: logger.error(err, exc_info=True) return jsonify({'success': False, 'msg': str(err)}), 500 return jsonify({'success': True}), 200
def imagens_container(rvf_id): session = app.config.get('dbsession') try: arvf = get_rvf(session, rvf_id) anexos = get_ids_anexos_ordenado(arvf) except Exception as err: logger.error(err, exc_info=True) return jsonify({'success': False, 'msg': str(err)}), 500 return jsonify(anexos), 200