Vous êtes sur la page 1sur 5

Programao

roger stoll www.sxc.hu

Como programar um wiki

Wiki Python
Os wikis vm revolucionando a Internet. Saiba como programar um com apenas 150 linhas de cdigo.
por Jos Pedro Orantes e Jos Mara Ruz
esta edio vamos construir um wiki simples, baseado 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 informao. 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.

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, conra as palavras erradas, que no vo ser consideradas palavras-chave: P Ol P Uma Coisa

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.

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


junho 2006 edio 20

www.linuxmagazine.com.br

67

Programao

Python

Outra-Coisa 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:
P P

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, podemos 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

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 interrogao 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 podemos introduzir formataes como, por exemplo, listas ou negrito. Uma vez editadas, as pginas podero ser armazenadas e, a partir de ento, a verso modicada 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.

Esse mdulo permite recolher as variveis passadas pelo servidor web. Para isso, temos que usar a funo cgi.FieldStorage(). Ela fornece um dicionrio de objetos do tipo FieldStorage. Cada um contm a informao de uma das variveis. 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 varivel em particular usando o mtodo has_key(): variables. has_key(nome).

Formulrios
Figura 2: Nosso formulrio de edio do wiki em Python. 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.

68

junho 2006

edio 20 www.linuxmagazine.com.br

Python

Programao

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: <form> e </form>. A primeira delas leva a uma srie de dados que de nem o comportamento do formulrio. Queremos controlar o mtodo de envio (POST ou GET) e o programa que receber os dados (wiki.py).
<form method="POST"action="wiki.py"> ... </form>

Figura 3: Muito bem! Nossa pgina foi armazenada. 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.
... <textarea cols="55" rows="10"name="texto"></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 simplicar, vamos usar o pouco original nome de texto. O segundo tipo de controle de que necessitaremos input:
... <input type="submit" value="Editar"> </input> <input type="hidden" name="editar" value="algo"> </input> ...

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 ...<a href="wiki.py=?pagina=WikiWiki"> U

Aqui vemos os dois tipos de que necessitamos. O parmetro type usado para especicar o tipo, pois existem vrios diferentes. No nosso caso, teremos: submit, que gera um boto cujo ttulo recolhido do parmetro 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.

WikiWiki</a>...

ou realizar a seguinte alterao:


...WikiWiki... en ...WikiWiki <a href="wiki.U py=?pagina=WikiWiki">?</a>...

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.

No 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.
junho 2006 edio 20

www.linuxmagazine.com.br

69

Programao

Python

Se houver a varivel pagina, carregaremos a correspondente. Se existir a varivel editar, ento carregaremos a pgina indicada em modo de edio. P Se existirem as variveis armazenar e texto, vamos armazenar o texto enviado.
P P

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. Para localizar as palavras-chave, usaremos expresses regulaVamos supor que temos a lista: [1,1,1,3,4,5,5,6] res (abordadas na edio n 17). O importante agora localizar e que geraremos um conjunto usando a funo a expresso regular adequada ao formato palavra-chave. J set([1,1,1,3,4,5,6]). O resultado ser o conjunto vimos que elas so compostas de duas ou mais palavras, cada {1,3,4,5,6}. O Python permite interferir sobre um conuma delas com a primeira letra em maiscula. junto, extraindo um elemento diferente de cada vez. Isso Para indicar que queremos uma palavra com a primeira letra nos permite realizar o seguinte truque: maiscula e pelo menos duas palavras, usamos a seguinte expresso regular: [A-Z][a-z]+. Se quisermos indicar que 01 >>> lista = [1,1,1,3,4,5,5,6] so duas palavras, usaremos [A-Z][a-z]+[A-Z][a-z]+. Para 02 >>> conj = set(lista) a possibilidade de mais de duas palavras, basta colocar a 03 >>> for elemento in conj: segunda parte entre parnteses e um +. Assim, chegamos 04 ... print "Elemento: ", elemento nossa expresso regular: 05 ...

Anlise do texto

06 Elemento: 1 ([A-Z][a-z]+[A-Z][a-z]+)+[A-Z]*[a-z]* 07 Elemento: 3 08 Elemento: 4 09 Elemento: 5 10 Elemento: 6 11 >>>

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 seguem 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)

assim que converteremos nossa lista de palavras em um conjunto para coletarmos. Como j temos as palavras, teremos apenas que substitu-las pelos links correspondentes. 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... -> ...<a href="wiki.pl$pagina=WikiWiki">WikiU Wiki</a>...

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

Mas, ao encontrar outra vez a palavra-chave WikiWiki na lista, substituiramos os WikiWiki recm-inseridos novamente pelo link:

70

junho 2006

edio 20 www.linuxmagazine.com.br

Python

Programao

...<a href="wiki.pl$pagina=WikiWiki">WikiWiki</a>... -> ...<a href="wiki.pl$pagina=...<a href="wiki.pl$paginaU =WikiWiki">WikiWiki</a>...">...<a href="wiki.pl\$U pagina=WikiWiki">WikiWiki</a>...</a>..."

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 peculiaridade: 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 def carregaPagina(titulo) def armazenaPagina(titulo,texto)

Figura 5: A pgina de boas-vindas do nosso wiki. Cada vez que temos que interagir com o sistema de arquivos, usamos:

Os prints sem parmetros imprimem os enters. Para facilitar 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()

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.

Toda pgina ter um cabealho, que imprime a parte no visvel, como as tags <title>, e um rodap, que fechar a pgina HTML (</body> </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)

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 Jos Pedro Orantes Casado cursa o 3 ano de Engenharia Tcnica em Informtica de Sistemas e, h muitos anos, usa linux como ferramenta 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).
junho 2006 edio 20

se encarregam de gerar as pginas usando as 3 funes anteriores. Isso simplica muito o cdigo e nos permite gerar pginas de maneira simples.

Autores

def editarPagina(titulo, texto)

www.linuxmagazine.com.br

71

Vous aimerez peut-être aussi