def analisa_esp_intervalo(txt, prc): """Destrincha a cadeia {txt}, que deve ser dois números de poltrona separados por hifen ('-'). Retorna uma lista de pares, cada par com um número de poltrona e o preço dado {prc}. """ global cache, nome_tb, letra_tb, colunas, diags ini_esp_fin_esp = txt.split('-') if len(ini_esp_fin_esp) != 2: raise ErroAtrib("sintaxe inválida em intervalo de poltronas: \"" + txt + "\"") alfabeto = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ini_esp = ini_esp_fin_esp[0] ini_int, ini_let = analisa_esp_numero(ini_esp) ini_let_ix = alfabeto.find(ini_let) fin_esp = ini_esp_fin_esp[1] fin_int, fin_let = analisa_esp_numero(fin_esp) fin_let_ix = alfabeto.find(fin_let) if ini_int > fin_int or ini_let_ix > fin_let_ix: raise ErroAtrib("sintaxe inválida em intervalo de poltronas (ordem): \"" + txt + "\"") nums_prc = [].copy() for num_int in range(ini_int, fin_int + 1): for num_let_ix in range(ini_let_ix, fin_let_ix + 1): num_let = alfabeto[num_let_ix] num = "%d%s" % ( num_int, num_let) nums_prc.append((num, prc)) return nums_prc
def analisa_esp_numero(txt): """Destrincha a cadeia {txt}, que deve ser um número de poltrona: um inteiro não negativo sequido opcionalmente de uma letra maiúscula. Devolve o inteiro como {int} e a letra como {string}. Se não houver letra, o segundo resultado é a cadeia vazia.""" global cache, nome_tb, letra_tb, colunas, diags txt = txt.strip(" ") if len(txt) < 1: raise ErroAtrib("sintaxe inválida em número de poltrona: \"" + txt + "\"") mt = re.search(r'[^0-9]', txt) # Retorna um objeto do tipo {Match}, ou {None}. # sys.stderr.write("txt = '%s' mt = '%s'\n" % (txt, str(mt))) if mt: # Tem letra: i = mt.start() # Indice inicial. num_int_esp = txt[0:i].strip(" ") num_let_esp = txt[i:] # sys.stderr.write("txt = '%s' num_int_esp = '%s' num_let_esp = '%s'\n" % (txt, num_int_esp, num_let_esp)) assert len(num_let_esp) > 0 if len(num_let_esp) != 1: raise ErroAtrib("sintaxe inválida em número de poltrona (letra): \"" + num_let_esp + "\"") num_let = num_let_esp else: # Não tem letra: num_int_esp = txt num_let = "" # sys.stderr.write("txt = '%s' num_int_esp = '%s' num_let = '%s'\n" % (txt, num_int_esp, num_let)) if len(num_int_esp) == 0: num_int = 0 else: try: num_int = int(num_int_esp) except: raise ErroAtrib("sintaxe inválida em número poltronas (inteiro): \"" + num_int_esp + "\"") return num_int, num_let
def processa(ses, args): try: if not sessao.eh_administrador(ses): raise ErroAtrib("Precisa ser administrador para executar esse comando.") campos = ['email', 'CPF'] if not verifica_pelo_menos_um_campo(campos, args): raise ErroAtrib("Pelo menos ou o CPF ou o email precisa estar preenchido") # Em virtude da função {verifica_pelo_menos_um_campo}, temos a garantia de haver pelos menos o CPF ou o email if 'email' in args: id_usuario = usuario.busca_por_email(args['email']) else: id_usuario = usuario.busca_por_CPF(args['CPF']) if id_usuario is None: raise ErroAtrib("Não foi encontrado um usuário com os dados fornecidos") bloco = html_lista_de_usuarios.gera([id_usuario]) pag = html_pag_generica.gera(ses, bloco, None) return pag except ErroAtrib as ex: erros = ex.args[0] # Repete a página com mensagem de erro: pag = html_pag_buscar_usuarios.gera(ses, args, sessao.eh_administrador(ses), erros) return pag
def verifica_campos(dict, campos): """ Garante que todos os campos da busca são suportados pelo Objeto_Compra e pelo menos campo um campo de busca está definido com algo diferente de None.""" for campo_busca in list(dict.keys()): if campo_busca not in campos: raise ErroAtrib("Campo \"%s\" inválido" % campo_busca) for campo in campos: if campo in dict and dict[campo] is not None: return raise ErroAtrib("Pelo menos um campo deve ser especificado") return
def processa(ses, atrs): try: # Separa o atributo 'poltronas' em {val_pos}: if 'poltronas' in atrs: esp_pols = atrs[ 'poltronas'] # String que especfica poltronas e preços. del atrs['poltronas'] else: raise ErroAtrib("Coloque as poltronas do trecho.\"") # Tenta criar o trecho: assert 'encerrado' in atrs if atrs['encerrado'] == 'on': atrs['encerrado'] = True # Necessario? trc = trecho.cria(atrs) pols = poltrona.cria_conjunto(trc, esp_pols) # Mostra o trecho criado: pag = html_pag_trecho.gera(ses, trc, None, "Trecho criado") except ErroAtrib as ex: erros = ex.args[0] # Repete a página de acrescentar trecho com os mesmos argumentos e mens de erro: pag = html_pag_trecho.gera(ses, None, atrs, erros) return pag
def cria_conjunto(trc, txt): global cache, nome_tb, letra_tb, colunas, diags assert trc != None and type(trc) is trecho.Objeto_Trecho assert txt != None and type(txt) is str id_trc = trecho.obtem_identificador(trc) # Obtém a lista de números de poltronas e respectivos preços: nums_precos = analisa_esp_conjunto(txt); pols = [].copy() for num, prc in nums_precos: if diags: sys.stderr.write("criando poltrona \"%s\" ($ %.2f) no trecho \"%s\"\n" % (num, prc, id_trc)) erros = [].copy() erros += valida_campo.numero_de_poltrona("número de poltrona", num, False) erros += valida_campo.preco("preço", prc, False) if len(erros) > 0: raise ErroAtrib(erros) pol_atrs = { 'id_trecho': id_trc, 'numero': num, 'preco': prc, 'oferta': False, 'bagagens': None, 'id_compra': None, 'fez_checkin': False, 'embarcou': False } pol = cria(pol_atrs) pols.append(pol) return pols
def processa(ses, args): # Determina se o usuário corrente {usr_ses} é administrador: if ses is None: usr_ses = None admin = False else: usr_ses = sessao.obtem_usuario(ses) assert usr_ses is not None admin = usuario.obtem_atributos(usr_ses)['administrador'] id_usr = args["id_usuario"] if "id_usuario" in args else None assert id_usr is not None, "id_usuario obrigatório para atualizar" usr = usuario.busca_por_identificador(id_usr) # Tenta editar o usuário: try: if usr == None: raise ErroAtrib("esse usuário não existe") atrs_muda = args.copy() del atrs_muda["id_usuario"] usuario.confere_e_elimina_conf_senha(atrs_muda) usuario.muda_atributos(usr, atrs_muda) # Mostra de novo a página de alterar com dados novos: args_novos = usuario.obtem_atributos(usr) pag = html_pag_usuario.gera(ses, usr, args_novos, None) except ErroAtrib as ex: erros = ex.args[0] # Repete a página de cadastrar com os mesmos argumentos e mens de erro: pag = html_pag_usuario.gera(ses, usr, args, erros) return pag
def muda_atributos(ses, mods_mem): global cache, nome_tb, letra_tb, colunas, diags erros = valida_atributos(ses, mods_mem) if len(erros) != 0: raise ErroAtrib(erros) objeto.muda_atributos(ses, mods_mem, cache, nome_tb, letra_tb, colunas, def_obj_mem) return
def muda_atributos(pol, mods_mem): global cache, nome_tb, letra_tb, colunas, diags assert pol != None and type(pol) is poltrona.Objeto_Poltrona erros = valida_atributos(pol, mods_mem) if len(erros) != 0: raise ErroAtrib(erros) objeto.muda_atributos(pol, mods_mem, cache, nome_tb, letra_tb, colunas, def_obj_mem) return
def cria(atrs_mem): global cache, nome_tb, letra_tb, colunas, diags erros = valida_atributos(None, atrs_mem) if len(erros) != 0: raise ErroAtrib(erros) trc = objeto.cria(atrs_mem, cache, nome_tb, letra_tb, colunas, def_obj_mem) assert type(trc) is trecho.Objeto_Trecho return trc
def confere_e_elimina_conf_senha(args): senha = (args['senha'] if 'senha' in args else None) if senha != None and senha != '': # Senha está sendo alterada/definida. Precisa confirmar senha: if 'conf_senha' not in args: raise ErroAtrib([ "campo 'Confirmar Senha' 'e obrigatório", ]) else: if senha != args['conf_senha']: raise ErroAtrib([ "senhas não batem", ]) # Remove o campo 'conf_senha', não mais necessários if 'conf_senha' in args: del args['conf_senha'] return
def cria(atrs_mem): global cache, nome_tb, letra_tb, colunas, diags if diags: mostra(0,"poltrona_IMP.cria(" + str(atrs_mem) + ") ...") erros = valida_atributos(None, atrs_mem) if len(erros) != 0: raise ErroAtrib(erros) pol = objeto.cria(atrs_mem, cache, nome_tb, letra_tb, colunas, def_obj_mem) assert type(pol) is poltrona.Objeto_Poltrona return pol
def analisa_esp_preco(txt): """Destrincha a cadeia {txt}, que deve ser um preço de poltrona no formato "{R}.{CC}" onde {R} é um ou mais dígitos decimais, e {CC} é dois dígitos decimais".""" global cache, nome_tb, letra_tb, colunas, diags try: prc = float(txt) except: raise ErroAtrib("sintaxe inválida em preço de poltronas: \"" + prc_esp + "\"") return prc
def muda_atributos(cpr, mods_mem): global cache, nome_tb, letra_tb, colunas, diags assert cpr != None and type(cpr) is compra.Objeto_Compra erros = valida_atributos(cpr, mods_mem) if len(erros) != 0: raise ErroAtrib(erros) objeto.muda_atributos(cpr, mods_mem, cache, nome_tb, letra_tb, colunas, def_obj_mem) return
def cria(atrs_mem): global cache, nome_tb, letra_tb, colunas, diags if diags: mostra(0, "usuario_IMP.cria(" + str(atrs) + ") ...") erros = valida_atributos(None, atrs_mem) if len(erros) != 0: raise ErroAtrib(erros) usr = objeto.cria(atrs_mem, cache, nome_tb, letra_tb, colunas, def_obj_mem) assert type(usr) is usuario.Objeto_Usuario return usr
def processa(ses, args): if ses == None or not sessao.aberta(ses): return html_pag_mensagem_de_erro.gera(ses, "Sessão deveria estar aberta") try: carrinho = sessao.obtem_carrinho(ses) id_carrinho = compra.obtem_identificador( carrinho) if carrinho != None else None if not sessao.eh_administrador(ses): # Usuário comum só pode buscar as próprias compras: usr = sessao.obtem_usuario(ses) # Dono da sessao. usr_id = usuario.obtem_identificador(usr) if not (args['cliente'] == None or args['cliente'] == usr_id): raise ErroAtrib("Você não tem acesso a essa informação") args['cliente'] = usr_id # Se recebeu parâmetro genérico "passageiro", converte ele para "doc_pass" ou # "nome_pass" if 'passageiro' in args: matchList = re.findall( "([0-9]{2}[\.]?[0-9]{3}[\.]?[0-9]{3}[\/]?[0-9]{4}[-]?[0-9]{2})|([0-9]{3}[\.]?[0-9]{3}[\.]?[0-9]{3}[-]?[0-9]{2})", args['passageiro']) # É um documento if len(matchList) > 0: args['doc_pass'] = args['passageiro'] # É um nome else: args['nome_pass'] = args['passageiro'] del args['passageiro'] campos = ['cliente', 'status', 'nome_pass', 'doc_pass'] verifica_campos(args, campos) cprs_ids = compra.busca_por_campos(args) cprs = map(lambda id_compra: compra.busca_por_identificador(id_compra), cprs_ids) ver = True if sessao.eh_administrador( ses) or args['cliente'] == sessao.obtem_usuario(ses) else False bloco = html_lista_de_compras.gera(cprs, ver, id_carrinho) pag = html_pag_generica.gera(ses, bloco, None) return pag except ErroAtrib as ex: erros = ex.args[0] # Repete a página com mensagem de erro: pag = html_pag_buscar_compras.gera(ses, args, sessao.eh_administrador(ses), erros) return pag
def muda_atributos(usr, mods_mem): global cache, nome_tb, letra_tb, colunas, diags erros = valida_atributos(usr, mods_mem) if len(erros) != 0: raise ErroAtrib(erros) sys.stderr.write("\n") sys.stderr.write("usr antes = %s\n" % str(usr)) sys.stderr.write("mods_mem = %s\n" % str(mods_mem)) objeto.muda_atributos(usr, mods_mem, cache, nome_tb, letra_tb, colunas, def_obj_mem) sys.stderr.write("usr depois = %s\n" % str(usr)) sys.stderr.write("\n") return
def analisa_esp_grupo(txt): """Destrincha a cadeia {txt}, no formato descrito na função {cria_conjunto}, exceto que não deve conter nenhum ponto-e-vírgula (';'). Deve terminar com dois-pontos (':') e o preço. Retorna uma lista de pares, cada par com um número de poltrona e esse preço.""" global cache, nome_tb, letra_tb, colunas, diags nums_esp_prc_esp = txt.split(':') if len(nums_esp_prc_esp) != 2: raise ErroAtrib("sintaxe inválida em grupo de poltronas: \"" + txt + "\"") nums_esp = nums_esp_prc_esp[0] prc_esp = nums_esp_prc_esp[1] prc = analisa_esp_preco(prc_esp) nums_prc = analisa_esp_lista(nums_esp, prc) return nums_prc
def processa(ses, args): try: # Por via das dúvidas: if args == None: args = {}.copy() erros = [].copy() # Obtem os campos sem defaults: origem = args['origem'] if 'origem' in args else None dia_partida = args['dia_partida'] if 'dia_partida' in args else None destino = args['destino'] if 'destino' in args else None dia_chegada = args['dia_chegada'] if 'dia_chegada' in args else None # Verifica campos obrigatórios: if origem == None and destino == None: erros.append( "um dos campos 'origem' e 'destino' deve ser especificado") if dia_partida == None: erros.append("o campo 'dia_partida' deve ser especificado") if dia_chegada == None: erros.append("o campo 'dia_chegada' deve ser especificado") # Obtem horas e providencia defaults: hora_partida = args[ 'hora_partida'] if 'hora_partida' in args else "00:00" hora_chegada = args[ 'hora_chegada'] if 'hora_chegada' in args else "00:00" if len(erros) > 0: raise ErroAtrib(erros) # Monta datas completas: data_min = dia_partida + " " + hora_partida + " UTC" data_max = dia_chegada + " " + hora_chegada + " UTC" # Busca trechos: trcs_ids = trecho.busca_por_origem_e_destino(origem, destino, data_min, data_max) trcs = map(lambda id_trecho: trecho.busca_por_identificador(id_trecho), trcs_ids) alterar_trcs = sessao.eh_administrador(ses) bloco = html_lista_de_trechos.gera(trcs, alterar_trcs) pag = html_pag_generica.gera(ses, bloco, None) return pag except ErroAtrib as ex: erros = ex.args[0] # Repete a página com mensagens de erro: admin = sessao.eh_administrador(ses) pag = html_pag_buscar_trechos.gera(ses, args, admin, erros) return pag
def cria(cliente, nome_pass, doc_pass): global cache, nome_tb, letra_tb, colunas, diags atrs_mem = { 'cliente': cliente, 'status': 'comprando', 'nome_pass': nome_pass, 'doc_pass': doc_pass } erros = valida_atributos(None, atrs_mem) if len(erros) != 0: raise ErroAtrib(erros) cpr = objeto.cria(atrs_mem, cache, nome_tb, letra_tb, colunas, def_obj_mem) assert type(cpr) is compra.Objeto_Compra return cpr
def processa(ses, args): usr_ses = None if ses == None else sessao.obtem_usuario(ses) assert sessao.eh_administrador( ses) # O dono da sessão deve ser administrador. try: if not 'id' in args: pag = html_pag_mensagem_de_erro.gera( ses, 'É necessário adicionar um ID para pesquisar.') return pag id = args['id'] if len(id) != 10: raise ErroAtrib("O identificador \"" + id + "\" é inválido") letra = id[0] if letra == "U": usr = usuario.busca_por_identificador(id) if usr == None: raise ErroAtrib("Não existe usuário com identificador " + id) usr_atrs = usuario.obtem_atributos(usr) usr_atrs['id_usuario'] = usuario.obtem_identificador(usr) pag = html_pag_usuario.gera(ses, usr, usr_atrs, None) elif letra == "C": cpr = compra.busca_por_identificador(id) if cpr == None: raise ErroAtrib( "Não existe pedido de compra com identificador" + id) pag = html_pag_compra.gera(ses, cpr, None, None) elif letra == "T": trc = trecho.busca_por_identificador(id) if trc == None: raise ErroAtrib( "Não existe trecho de viagem com identificador" + id) pag = html_pag_trecho.gera(ses, trc, None, None) elif letra == "S": ses_a_ver = sessao.busca_por_identificador(id) if ses_a_ver == None: raise ErroAtrib("Não existe sessão com identificador" + id) pag = html_pag_sessao.gera(ses, ses_a_ver, None) elif letra == "A": pol = poltrona.busca_por_identificador(id) if pol == None: raise ErroAtrib("Não existe poltrona com identificador" + id) pag = html_pag_poltrona.gera(ses, pol, None, None) else: raise ErroAtrib("Classe de objeto \"" + letra + "\" inválida") except ErroAtrib as ex: erros = ex.args[0] return html_pag_mensagem_de_erro.gera(ses, erros) return pag
def processa(ses, args): # Obtem usuário e carrinho de compras: assert ses != None # Comando não deveria ser acessível a usuário não logado. usr_ses = sessao.obtem_usuario(ses) assert usr_ses != None # Paranóia. admin = usuario.obtem_atributo(usr_ses, 'administrador') assert not admin # Admnistrador não deveria ter acesso a este cmd. #Obtem a poltrona a comprar: id_pol = args['id_poltrona'] if 'id_poltrona' in args else None assert id_pol != None # Paranóia (formulário ou botão deve fornecer) pol = poltrona.busca_por_identificador(id_pol) assert pol != None # Paranóia. # Obtém carrinho do usuário: carr = sessao.obtem_carrinho(ses) assert carr != None # Todo cliente comum deve ter carrinho. id_carr = compra.obtem_identificador(carr) try: if not poltrona.pode_comprar(usr, pol, carr): # Não deveria acontecer, mas em todo caso: raise ErroAtrib("Esta poltrona não está disponível") # Muda a poltrona para comprada poltrona.muda_atributos(pol, { 'id_compra': id_carr }) # Mostra o carrinho do usuário com a poltrona comprada: pag = html_pag_compra.gera(ses, cpr, excluir, None) except ErroAtrib as ex: erros = ex.args[0] # Se o trecho da poltrona estiver disponível, mostra o trecho para outra compra: id_trc = poltrona.obtem_atributo(pol, 'id_trecho') assert id_trc != None # Paranoia. trc = trecho.busca_por_identificador(id_trc) assert trc != None # Paranoia. if trecho.verificar_disponibilidade(trc) and trecho_eh_compativel(cpr, trc): # Usuário pode comprar outra poltrona deste trecho: pag = html_pag_trecho.gera(ses, trc, None, erros) else: # Usuário não pode comprar nenuma poltrona neste trecho. # Volte para a página principal. # !!! Deveria buscar e mostrar roteiros de mesma origem e destino !!! pag = html_pag_principal.gera(ses, erros) return pag
def processa(ses, args): try: # Por via das dúvidas: if args == None: args = {}.copy() erros = [].copy() # Verifica e obtem campos obrigatórios: for ch in ('origem', 'dia_min', 'destino', 'dia_max'): if not ch in args: erros.append("O campo '%s' deve ser preenchido" % ch) # Obtem parâmetros obrigatórios da busca: origem = args['origem'] if 'origem' in args else None; dia_min = args['dia_min'] if 'dia_min' in args else None; destino = args['destino'] if 'destino' in args else None; dia_max = args['dia_max'] if 'dia_max' in args else None; # Obtem parãmetros opcionais, com defaults: hora_min = args['hora_min'] if 'hora_min' in args else "00:00"; hora_max = args['hora_max'] if 'hora_max' in args else "23:59"; # Monta as datas para busca: data_min = dia_min + " " + hora_min + " UTC" data_max = dia_max + " " + hora_max + " UTC" # Verifica se intervalo é razoável: !!! Deveria exigir mais que 1 minuto !!! if data_min >= data_max: erros.append("Intervalo de datas inválido") if len(erros) > 0: raise ErroAtrib(erros) # Chamando a busca recursiva: soh_disponiveis = True roteiros = roteiro.descobre_todos(origem, data_min, destino, data_max, soh_disponiveis) # Monta página com resposta: roteiros_html = html_lista_de_roteiros.gera(roteiros) pag = html_pag_generica.gera(ses, roteiros_html, None) return pag except ErroAtrib as ex: erros = ex.args[0] # Repete a página com mensagens de erro: pag = html_pag_sugerir_roteiros.gera(ses, erros) return pag
def cria(usr, cookie, carrinho): global cache, nome_tb, letra_tb, colunas, diags atrs_mem = { 'usr': usr, 'criacao': datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S %z"), 'fechamento': datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S %z"), 'abrt': True, 'cookie': cookie, 'carrinho': carrinho } erros = valida_atributos(None, atrs_mem) if len(erros) != 0: raise ErroAtrib(erros) ses = objeto.cria(atrs_mem, cache, nome_tb, letra_tb, colunas, def_obj_mem) assert type(ses) is sessao.Objeto_Sessao return ses