como programar um wiki no linux.pdf

Upload: lucas-ribeiro-prado

Post on 31-Oct-2015

21 views

Category:

Documents


0 download

TRANSCRIPT

  • Os wikis vm revolucionando a Internet. Saiba como

    programar um com apenas 150 linhas de cdigo.

    por Jos Pedro Orantes e Jos Mara Ruz

    Como programar um wiki

    Wiki Python

    Nesta edio vamos construir um wiki simples, base-ado no site pioneiro do tipo, de Ward Cunningham. Seu wiki (ou mais corretamente, WikiWiki) o mais antigo do mundo: Cunningham & Cunningham, Inc. [1] (por falar nisso, consulte o maior wiki do planeta para obter

    informaes sobre ele em [2] ). O site bastante simples. Seu sistema foi criado com o

    objetivo de que as pessoas pudessem acrescentar informa-

    o. Assim o site poderia crescer sozinho. Vamos reproduzir

    grande parte dele com um programa em Python de apenas

    150 linhas, que deve ser baixado em [3] . Novamente, essa linguagem demonstra todo seu poder.

    Nosso prprio WikiWiki Criar um wiki no Python no to complicado como pode

    parecer. A receita :

    01 Muito CGI

    02 Um pouco de expresses regulares

    03 Um pouco de manipulao de diretrios

    04 Um servidor Web ao gosto do leitor (mas que suporte CGI)

    Com esses ingredientes vamos programar um wiki completo,

    que pode ser ampliado de acordo com a necessidade.

    roger stoll ww

    w.sxc.hu

    Figura 1: O pai de todos os wikis, criado por Ward Cunningham.

    Funcionamento Vamos ao primeiro passo para desenvolver qualquer programa:

    saber exatamente o que queremos. Seguindo as regras do c2.com, o wiki ser composto por pginas interligadas. Os links sero

    palavras-chave com um formato especial: elas sero formadas por

    duas palavras juntas (sem espaos ou separadores), cada uma

    comeando com uma letra maiscula. Isso pode parecer confuso,

    como veremos em alguns exemplos. Primeiro, con ra as palavras

    erradas, que no vo ser consideradas palavras-chave:

    P Ol

    P Uma Coisa

    www.linuxmagazine.com.br

    junho 2006 edio 20 67

    Programao

  • P Outra-Coisa

    P softwareLivre

    P 3porquinhos

    Nenhuma delas corresponde ao nosso padro. A seguir, as

    que se enquadram:

    P OlMundo

    P UmDoisTrs

    P LinuxMagazine

    P FreeBsd

    por isso que o termo original WikiWiki, em vez de

    simplesmente wiki.

    Agora que j vimos as palavras-chave, vamos ver como elas

    so utilizadas. A verdade que no h muito o que explicar, elas

    simplesmente devem ser digitadas e pronto! Por exemplo:

    Este um texto de um WikiWiki para a LinuxMagazine. Neste U

    exemplo, as palavras WikiWiki e LinuxMagazine devem se U

    converter automaticamente em palavras-chave.

    Cada palavra-chave digitada pode virar uma pgina. Caso ela

    no contenha nenhum texto associado com ela, um ponto de inter-

    rogao surge ao lado da palavra. Basta clicar nele para acrescentar

    o texto. Em textos prontos, basta clicar no boto Editar.

    O texto que vamos editar vai estar em formato HTML, assim pode-

    mos introduzir formataes como, por exemplo, listas ou negrito.

    Uma vez editadas, as pginas podero ser armazenadas e, a

    partir de ento, a verso modi cada j estar disponvel. Na teoria,

    no deveria ser possvel apagar pginas, j que o objetivo de um

    wiki acumular informao. Como a nica maneira de criar

    novas pginas adicionar palavras-chave a pginas existentes,

    assim asseguramos que qualquer pgina ser acessvel a partir

    de outra. Tudo estar interligado, no haver pginas soltas.

    CGI CGI (Common Gateway Interface) um protocolo que

    permite a um servidor web enviar e receber informaes

    de um programa externo. Basicamente, o servidor web

    delega a gerao das pginas a programas externos (que

    obtm parmetros para a criao de pginas a partir do

    servidor web).

    Esses parmetros podem ser enviados de duas maneiras

    distintas: GET e POST. Esses so os modos usados para a

    troca de informaes entre o navegador e o servidor de web.

    O GET simplesmente passa os parmetros atravs da URL

    (na barra de endereo do navegador) para o servidor.

    Quando visitamos muitas das pginas da Internet, pode-

    mos ver que a URL tem um formato parecido com http://www.algumaweb.org/algo.algo?variavel1=valor1&variavel2=valor.

    Nesse exemplo, o navegador est passando 2 variveis ao

    servidor ( variavel1 e variavel2 ). A URL usa o smbolo &

    para separar variveis entre si. No muito complicado.

    J o POST diferente: o navegador e o servidor trocam

    informaes usando o protocolo HTTP, de modo que no

    vemos as variveis sendo passadas.

    Para o nosso programa, o que importa no usar GET ou

    POST, mas o conceito de CGI. Nosso programa recolher

    variveis e gerar pginas dependendo delas.

    Para isso, usaremos o mdulo cgi do Python:

    import cgi

    Esse mdulo permite recolher as variveis passadas pelo

    servidor web. Para isso, temos que usar a funo cgi.Fiel-

    dStorage() . Ela fornece um dicionrio de objetos do tipo

    FieldStorage. Cada um contm a informao de uma das va-

    riveis. De toda essa informao, s nos interessa o valor da

    varivel, que podemos acessar com:

    variables = cgi.FieldStorage()

    valor = variables["nome"].value

    Assim poderemos obter o valor da varivel. Se for oferecido

    um dicionrio, poderemos consultar se h alguma vari-

    vel em particular usando o mtodo has_key() : variables.

    has_key(nome) .

    Formulrios A parte vital de um wiki o poder de editar o contedo das

    pginas. Para isso, usaremos formulrios em HTML para

    recolher as informaes e envi-las ao servidor web. Figura 2: Nosso formulrio de edio do wiki em Python.

    Programao

    68

    Python

    www.linuxmagazine.com.br

    junho 2006 edio 20

  • Os formulrios so compostos de muitos controles, como,

    por exemplo, botes, campos de texto, rtulos e arquivos.

    Precisamos de um formulrio com um campo extenso de texto

    e um boto para guardar o texto editado. Vamos ao bsico.

    Um formulrio HTML ca entre duas tags: e

    . A primeira delas leva a uma srie de dados que

    de nem o comportamento do formulrio. Queremos con-

    trolar o mtodo de envio (POST ou GET) e o programa que

    receber os dados (wiki.py).

    ...

    Dentro do formulrio so de nidos os controles que sero

    mostrados. Cada um deles, por sua vez, de ne uma srie de

    parmetros. O primeiro deles ser uma textarea.

    ...

    ...

    cols indica o nmero de colunas (de um tipo de largura)

    e rows , o nmero de linhas. O parmetro name de ne o

    nome com que o contedo da textarea ser enviado ao

    servidor web. Para simpli car, vamos usar o pouco ori-

    ginal nome de texto.

    O segundo tipo de controle de que necessitaremos input:

    ...

    ...

    Aqui vemos os dois tipos de que necessitamos. O parme-

    tro type usado para especi car o tipo, pois existem vrios

    diferentes. No nosso caso, teremos:

    submit , que gera um boto cujo ttulo recolhido do par-

    metro value . Esse boto, ao ser pressionado, envia os dados

    ao servidor; e hidden , que usado para passar ao servidor

    dados relacionados com controles. Em nosso caso, passamos

    a varivel editar=algo .

    Estrutura Nosso wiki funcionar assim: ao ser acessado pela primeira vez,

    no havendo variveis, ser gerada uma pgina de apresentao.

    Essa pgina ter um boto que nos permitir edit-la.

    Para isso, incluiremos um boto dentro do formulrio HTML,

    que enviar uma varivel editar , com a cadeia de caracteres

    WikiWiki como valor.

    Ao ser iniciado novamente, teremos uma varivel editar

    e, ao invs de gerar uma pgina, a aplicao buscar em seu

    diretrio por um arquivo WikiWiki.txt. Se ele exisitir, o texto

    ser carregado em uma textarea, que nos permitir edit-lo.

    Ele vir acompanhado de um boto armazenar, que, ao ser

    pressionado, envia duas variveis: armazenar, com o nome

    da pgina (WikiWiki, nesse caso); e texto, com o texto que

    editamos. Quando o wiki.py detectar as duas variveis, ir

    guardar o contedo do texto em um arquivo com o nome que

    contenha a varivel armazenar, concatenado com o .txt.

    O texto, antes de ser armazenado, analisado em uma busca

    por palavras-chave. No caso de elas existirem, ser realizada

    a seguinte alterao, no caso de existir a pgina (ou seja, o

    arquivo WikiWiki.txt ):

    ....WikiWiki... en ... U

    WikiWiki...

    ou realizar a seguinte alterao:

    ...WikiWiki... en ...WikiWiki ?...

    N o caso de no existir uma pgina, um ? deve ser colocado

    ao lado da palavra-chave para indicar que essa pgina deve

    ser criada. Para isso, teremos apenas que clicar sobre o ?,

    digitar o texto e clicar em Armazenar (como antes).

    Assim, teremos que controlar 4 situaes:

    P Se no houver variveis, geraremos a pgina de boas-vindas.

    Figura 3: Muito bem! Nossa pgina foi armazenada.

    www.linuxmagazine.com.br

    junho 2006 edio 20 69

    Python Programao

  • P Se houver a varivel pagina, carregaremos a correspondente.

    P Se existir a varivel editar, ento carregaremos a pgina

    indicada em modo de edio.

    P Se existirem as variveis armazenar e texto, vamos arma-

    zenar o texto enviado.

    Anlise do texto Para localizar as palavras-chave, usaremos expresses regula-

    res (abordadas na edio n 17 ). O importante agora localizar

    a expresso regular adequada ao formato palavra-chave. J

    vimos que elas so compostas de duas ou mais palavras, cada

    uma delas com a primeira letra em maiscula.

    Para indicar que queremos uma palavra com a primeira letra

    maiscula e pelo menos duas palavras, usamos a seguinte

    expresso regular: [A-Z][a-z]+ . Se quisermos indicar que

    so duas palavras, usaremos [A-Z][a-z]+[A-Z][a-z]+ . Para

    a possibilidade de mais de duas palavras, basta colocar a

    segunda parte entre parnteses e um +. Assim, chegamos

    nossa expresso regular:

    ([A-Z][a-z]+[A-Z][a-z]+)+[A-Z]*[a-z]*

    Agora que j podemos localizar as palavras-chave, vamos

    substitu-las no texto por links para suas respectivas pginas.

    Para isso, preciso gerar uma lista a partir dos resultados da

    expresso regular. a que entra a funo findall() , que

    fornece uma lista com todas as cadeias de caracteres que se-

    guem o padro de palavra-chave. Mas teremos um problema:

    algumas das cadeias de caracteres vo estar duplicadas.

    Como vamos limpar os valores duplicados da lista? Isso pode

    ser feito de muitas maneiras (algum na Internet bolou essa

    soluo: reduce(lambda 1, x: x not in 1 and 1.append(x)

    or 1, a, []) , sendo a a cadeia de caracteres. Mas explicar

    essa simples linha levaria um artigo inteiro). Mais simples

    empregar um pouco de matemtica.

    O Python permite a gerao de um conjunto a partir de

    uma lista. Um conjunto pode conter diversos elementos,

    mas sua quantidade no importa, o importante apenas

    que estejam presentes.

    Vamos supor que temos a lista: [1,1,1,3,4,5,5,6]

    e que geraremos um conjunto usando a funo

    set([1,1,1,3,4,5,6]). O resultado ser o conjunto

    {1,3,4,5,6}. O Python permite interferir sobre um con-

    junto, extraindo um elemento diferente de cada vez. Isso

    nos permite realizar o seguinte truque:

    01 >>> lista = [1,1,1,3,4,5,5,6]

    02 >>> conj = set(lista)

    03 >>> for elemento in conj:

    04 ... print "Elemento: ", elemento

    05 ...

    06 Elemento: 1

    07 Elemento: 3

    08 Elemento: 4

    09 Elemento: 5

    10 Elemento: 6

    11 >>>

    assim que converteremos nossa lista de palavras em

    um conjunto para coletarmos. Como j temos as palavras,

    teremos apenas que substitu-las pelos links correspon-

    dentes. Mas a pgina pode no existir. Ento, teremos que

    testar essa condio com um if. A sim substituiremos a

    palavra-chave no contedo da pgina pelo link.

    Usaremos a funo replace() do string.replace() , que

    aceita 2 parmetros. O primeiro a cadeia a ser substituda

    e o segundo, a cadeia que ser usada para substituio.

    Apenas uma execuo de replace() j vai realizar todas as

    substituies de uma vez. Essa a razo pela qual fizemos

    o truque do conjunto: se alguma cadeia de caracteres se

    repetisse na lista de palavras-chave, ocorreria o seguinte.

    Com a primeira, realizaramos a alterao:

    ...WikiWiki... -> ...WikiU

    Wiki...

    Mas, ao encontrar outra vez a palavra-chave WikiWiki

    na lista, substituiramos os WikiWiki recm-inseridos no-

    vamente pelo link: Figura 4: A criao de uma pgina com o formulrio vazio.

    Programao

    70

    Python

    www.linuxmagazine.com.br

    junho 2006 edio 20

  • ...WikiWiki... ->

    ......WikiWiki......"

    Esses mtodos so usados na funo analise() do arquivo

    wiki.py , vital para nosso programa.

    Gerao de HTML Bem, agora nos encarregaremos de gerar o HTML. Graas ao

    CGI, a tarefa consiste apenas em imprimir o cdigo HTML

    com print. O HTML devolvido pelo CGI tem uma peculia-

    ridade: deve ser enviado com uma tag que indica o tipo de

    informao que ele contm. Alm disso, essa tag tem que ir

    separada por dois carriage returns (enters) do resto da pgina.

    O cdigo em questo :

    print "Content-Type:text/html"

    print

    print

    Os prints sem parmetros imprimem os enters. Para faci-

    litar o design do cdigo, dividimos a gerao da pgina em

    3 funes:

    def cabealho(titulo)

    def corpo(titulo, texto)

    def editarCorpo(titulo,texto)

    def rodape()

    Toda pgina ter um cabealho, que imprime a parte no

    visvel, como as tags , e um rodap, que fechar a

    pgina HTML ( ). No meio estar o corpo,

    que pode ser gerado por corpo() ou por editarCorpo() .

    Essa segunda funo abre um formulrio para a edio do

    contedo da pgina.

    O texto da funo corpo() gerado normalmente usando

    uma varivel conteudo do tipo string . Dependendo das

    circunstncias, conter uma informao ou outra.

    As funes

    def pagina(titulo, texto)

    def editarPagina(titulo, texto)

    se encarregam de gerar as pginas usando as 3 funes an-

    teriores. Isso simpli ca muito o cdigo e nos permite gerar

    pginas de maneira simples.

    Cada vez que temos que interagir com o sistema de arqui-

    vos, usamos:

    def carregaPagina(titulo)

    def armazenaPagina(titulo,texto)

    A funo carregaPagina() devolve o contedo da pgina

    que passada como parmetro.

    ltimos detalhes Temos que levar em considerao que o programa wiki.py

    deve ter permisses para escrita no diretrio onde ele se

    encontra, visto que a que os arquivos so depositados.

    Tambm temos que lhe dar permisso de execuo (basta o

    comando chmod + x wiki.py ).

    Resta apenas copiar o wiki.py para o diretrio referente

    ao localhost/cgi-bin , para que ele seja executado quando

    digitamos no navegador: http//localhost/cgi-bin/wiki.py. Aparecer ento uma pgina como a mostrada na gura 4 .

    Au

    tore

    s Jos Pedro Orantes Casado cursa o 3 ano de Engenharia Tcnica em Informtica de Sistemas e, h muitos anos, usa linux como ferramen-ta de trabalho e sistema operacional de escritrio. Jos Mara Ruz est nalizando seu projeto de concluso de curso de Engenharia Tcnica em Informtica de Sistemas e est h mais de 7 anos usando e desenvolvendo Software Livre (h dois anos no FreeBSD).

    Informaes [1] Cunningham & Cunningham, Inc.: http://c2.com

    [2] Ward Cunningham, Wikipdia: pt.wikipedia.org/wiki/Ward_Cunningham

    [3] Download do cdigo wiki.py: www.linuxmagazine.com.br/issue/20/wiki.zip

    Figura 5: A pgina de boas-vindas do nosso wiki.

    www.linuxmagazine.com.br

    junho 2006 edio 20 71

    Python Programao