terça-feira, 31 de agosto de 2010

Botão Add This para adicionar seu post em qualquer rede

No Site aos Pedaços de hoje vamos falar sobre o botão Add This, que você pode colocar no seu blog ou site para que as pessoas possam repassar adiante seu post.

O Add This é uma ferramenta legal porque, além de integração nativa com o blogger, te dando o código pronto sem você ter que quebrar muito a cabeça, ele te dá estatísticas por e-mail, dizendo quem clicou  no que e repassou pra onde.

Para iniciar acesse o site http://www.addthis.com/ e escolha seu tipo de site, blog ou CMS, escolha o estilo do botão e integre com uma conta do google analytics se você possuir. Não falaremos sobre o  google analytics nesse post, talvez futuramente.

O código para colocar o  botão no blog é este:

<!-- AddThis Button BEGIN -->
<div><a expr:addthis:title='data:post.title' expr:addthis:url='data:post.url' class='addthis_button'><img src="http://s7.addthis.com/static/btn/v2/lg-share-en.gif" width="125" height="16" alt="Bookmark and Share" style="border:0"/></a>
<script type="text/javascript">var addthis_config = {"data_track_clickback":true};</script>
<script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#username=vitorrubio"></script></div>
<!-- AddThis Button END -->


Veja no site oficial as instruções para inserção do código.


O resultado é este:





Bookmark and Share


Repare que o código do botão mescla html, javascript e objetos serializados com JSON. Repare também que, se você obteve co código sem estar logado, o código conterá um username provisório e randômico, mas se você obteve o código depois de logado no site o código conterá seu username.




Para instalar:

Clique em Edit HTML para editar o html do blog.



Clique para marcar o "Expand Widget Templates"



Procure por um lugar onde as variáveis do script são acessíveis e conhecidas, por exemplo o post footer, para ficar no rodapé de cada post. Particularmente eu coloquei em cima de cada post, na própria div dedicada a ele também daria certo, mas é melhor seguir o manual ;)


Por último salve o template e o layout.




Por enquanto é isso, espero que tenha sido útil, Have Fun ;)

Sugestões para o google groups

Seria legal se pudéssemos criar pastas no google groups, ou que pelo menos fosse integrado com o google docs. Outra coisa legal seria um arquivo enviado por e-mail para o grupo ir direto para a seção de arquivos. Coloquei a sugestão no grupo dedicado a isso, vamos ver se rola.

I'd like to suggest folder/directory creation in google groups. It's

possible to upload files, but it's impossible to create folders or
direcotories to  organize these files.

Other good improve would be to automatically put in group files those
files sent to group by e-mail.

Another suggestion are integration between google docs and google
groups.


Outra coisa que falta é filtrar os buzz. Os buzz são legais, mas receber todos eles na sua caixa de entrada pelo pop3 não é legal. 

quinta-feira, 26 de agosto de 2010

Busca de CEP com o Lazarus - Parte 3 - XML Document

Na postagem anterior aprendemos como usar a classe THTTPSend da biblioteca synapse para criar consultar o serviço de consulta de cep e receber um xml com as informações sobre o endereço.

Hoje vamos ver como criar uma classe para encapsular todo esse mecanismo e fazer com que os atributos dessa classe sejam os dados do endereço.

Primeiro de tudo vamos criar um arquivo chamado LazCep.pas e a classe LazCep. Repare nas units que temos que adicionar no uses.

uses
  Classes, SysUtils, DOM, XMLRead, httpsend, dialogs;

type

         { TLazCep }

         TLazCep = class
         private

                FXML: DOMString;
                FCEP: DOMString;

                FXMLDoc: TXMLDocument;

                //sets
                procedure SetCep(const vCep: DOMString);

                //gets
                function GetCep: DOMString;
                function GetLogradouro: DOMString;
                function GetCidade: DOMString;
                function GetEstado: DOMString;
                function GetBairro: DOMString;
                function GetIBGEEstado: DOMString;
                function GetIBGECidade: DOMString;
                function GetIBGEVerificador: DOMString;

                //internal functions
                function GetXmlNode(const vNodeName: DOMString): DOMString;
         public
               constructor Create;
               destructor Destroy;
               procedure Consultar;
               function GetXML: DOMString;
               property Cep: DOMString read GetCep write SetCep;
               property Logradouro: DOMString read GetLogradouro;
               property Cidade: DOMString read GetCidade;
               property Estado: DOMString read GetEstado;
               property Bairro: DOMString read GetBairro;
               property IBGEEstado:DOMString read GetIBGEEstado;
               property IBGECidade:DOMString read GetIBGECidade;
               property IBGEVerificador: DOMString read GetIBGEVerificador;

         end; 

Feito isso pressione shift+ctrl+c para criar o esqueleto da classe. Implemente a classe de modo que a propriedade CEP seja um simples Get e Set, mas dê atenção especial aos métodos consultar e GetXmlNode.


{ TLazCep }

procedure TLazCep.SetCep(const vCep: DOMString);
begin
     FCEP:=vCep;
end;

function TLazCep.GetCep: DOMString;
begin
     Result := FCEP;
end;

function TLazCep.GetLogradouro: DOMString;
begin
     Result := GetXmlNode('logradouro');
end;

function TLazCep.GetCidade: DOMString;
begin
    Result := GetXmlNode('cidade');
end;

function TLazCep.GetEstado: DOMString;
begin
    Result := GetXmlNode('uf');
end;

function TLazCep.GetBairro: DOMString;
begin
   Result := GetXmlNode('bairro');
end;

function TLazCep.GetIBGEEstado: DOMString;
begin
    Result := GetXmlNode('ibge_uf');
end;

function TLazCep.GetIBGECidade: DOMString;
begin
    Result := GetXmlNode('ibge_municipio');
end;

function TLazCep.GetIBGEVerificador: DOMString;
begin
     Result := GetXmlNode('ibge_municipio_verificador');
end;

function TLazCep.GetXmlNode(const vNodeName: DOMString): DOMString;
begin

  Result := FXMLDoc.FindNode('webservicecep').FindNode('retorno').FindNode(vNodeName).TextContent;

end;

constructor TLazCep.Create;
begin
  //constructor
end;

destructor TLazCep.Destroy;
begin
     //destructor
end;

procedure TLazCep.Consultar;
var

    host: string;

    {streams que conterão o resultado do site}
    Response: TMemoryStream;
    S: TStringStream;

begin

  host := 'http://www.buscarcep.com.br/?' + 'cep='+FCEP+'&formato=xml&chave='+UrlEncode('1Z3s3/2ZjDt.dcyiLuBy/6mitlDNgt/');

  {destruindo o XMLDoc caso já exista}
  if(FXMLDoc <> nil) then
  try
       FXMLDoc.Free;
  except
  end;

  FXMLDoc := nil;

  try

    {criando os streams que conterão o resultado do site}
    Response:=TMemoryStream.Create;

    {consultando com httpGetText ou httpGetBinary}
    if HttpGetBinary(host, Response) then
    begin

         {posiciona o stream de resposta no inicio}
         Response.Seek(0, soFromBeginning);
         {Cria e Lê o documento XML a partir da stream}
         ReadXMLFile(FXMLDoc, Response);
         {posiciona o stream de resposta no inicio novamente}
         Response.Seek(0, soFromBeginning);
         {Copia o stream de resposta para um string stream, recém criado, para extrair dele uma string}
         S := TStringStream.Create(FXML);
         S.CopyFrom(Response, Response.Size-1);
         s.Seek(0, soFromBeginning);
         {atribui o conteudo todo a propriedade XML da classe, para termos acesso ao xml de retorno}
         FXML:= s.DataString;

         {coloco o encoding desejado}
         FXMLDoc.Encoding:='iso-8859-1';

    end;
  finally
    Response.Free;
    S.Free;
  end;
end;  



function TLazCep.GetXML: DOMString;
begin
  Result := FXML;
end;


end.    

Na seção implementation dessa unit colocamos o método estático que criamos na primeira parte desse tutorial, para encoding de URL.


O ponto principal aqui é o método Consultar. Repare que criamos um FXMLDoc: TXMLDocument como campo privado da classe TLazCep, certo? Esse atributo será destruido e recriado toda vez que se consultar um CEP, para limpar a estrutura XML que ele já tinha.


Logo depois criamos um memory stream, mas pode ser um string stream ou mesmo um stringList, dependendo de como você quer fazer


Posicionamos esse stream no início (não precisa fazer isso se for uma string), criamos e alimentamos o XMLDocument e ainda extraimos o conteudo do XML para um atributo da classe, para consulta ou conferência.


Depois disso a function GetXmlNode traz o conteudo do nó correto do XML, que tem o nome do dado que queremos.

Result := FXMLDoc.FindNode('webservicecep').FindNode('retorno').FindNode(vNodeName).TextContent; 

Logo depois disso podemos usar GetXmlNode para cada um dos gets das propriedades da classe. Todas são somente leitura, exceto a CEP, e todas tem um get como este:

function TLazCep.GetLogradouro: DOMString;
begin
     Result := GetXmlNode('logradouro');
end;  

Exceto a CEP, já que é por ela que começamos.


Como vimos, obrigatoriamente um TXMLDoc deve ser criado pelo método estático global AKA procedure ReadXMLFile, que cria o objeto XMLDoc e popula seu conteudo através de uma stream. Enquanto o XMLDoc está na unit DOM, a procedure ReadXmlFile está na unit XMLRead.


Repare também que não fizemos o request HTTP com o HTTPSend "na unha", mas usamos a procedure HTTPGetBinary da unit HTTPSend que faz exatamente o que fizemos no último tutorial:

function HttpGetBinary(const URL: string; const Response: TStream): Boolean;
var
  HTTP: THTTPSend;
begin
  HTTP := THTTPSend.Create;
  try
    Result := HTTP.HTTPMethod('GET', URL);
    if Result then
    begin
      Response.Seek(0, soFromBeginning);
      Response.CopyFrom(HTTP.Document, 0);
    end;
  finally
    HTTP.Free;
  end;
end; 

Até agora usamos o método HTTPGetBinary em conjunto com MemoryStreams. Podemos usar HTTPGetText em conjunto com StringLists, conforme segue:

procedure TLazCep.ConsultarString;
var
    host: string;

    {StringList que conterão o resultado do site}
    Response: TStringList;
    S: TStringStream;

begin

  host := 'http://www.buscarcep.com.br/?' + 'cep='+FCEP+'&formato=xml&chave='+UrlEncode('1Z3s3/2ZjDt.dcyiLuBy/6mitlDNgt/');

  {destruindo o XMLDoc caso já exista}
  if(FXMLDoc <> nil) then
  try
       FXMLDoc.Free;
  except
  end;

  FXMLDoc := nil;

  try

    {criando o stringlist que conterão o resultado do site}
    Response:=TStringList.Create;

    {consultando com httpGetText ou httpGetBinary}
    if HttpGetText(host, Response) then
    begin

         {capturamos em uma string o conteudo do response}
         FXML:=Response.Text;
         {criamos uma string stream a partir dele para alimentar o XMLDoc}
         S := TStringStream.Create(FXML);
         {Criamos e alimentamos o XMLDoc}
         ReadXMLFile(FXMLDoc, S);

         {coloco o encoding desejado}
         FXMLDoc.Encoding:='iso-8859-1';

    end;
  finally
    Response.Free;
    S.Free;
  end;
end;   

Essa classe ainda não funciona com proxy. Para funcionar com proxy precisaremos usar recursos especiais que serão vistos nos próximos tutoriais.

Outra coisa que precisamos é validar e disparar a mensagem de erro correta caso o xml venha vazio ou caso não seja possível estabelecer uma conexão.

Nos próximos artigos veremos como usar esta classe e como fazer essas alterações necessárias.

Ainda precisamos cuidar de conversões e codificações UTF-8 etc por causa de acentos e outros sinais diacríticos.


No próximo artigo faremos mais melhorias nesta classe. E no final poderemos fazer download do código fonte completo. Até lá :)


Ir Para:


Parte 1 | Parte 2 | Parte 3 | Parte 4 | Parte 5

Seu Blog pode virar um livro


Mais um da série "Site aos Pedaços"!
O "gadeject" da vez não é bem um penduricalho, mas é a dica para um concurso, ondeseu blog será votado.  Você pode "pendurilhar" no seu blog a imagem com o link para votação.

Isso me faz lembrar, saudosamente (ou não) o tempo em que o top 30 era "O" medidor de popularidade de um site e todo mundo queria fazer algo para ser "notado" e "votado".

Dessa vez aderindo ao concurso 2° prêmio blog books irei mostrar como você pode colocar a imagem que o site do concurso oferece dentro do link para votação no seu blog e colocar em um canto qualquer. 

Não que eu tenho esperanças de que um dia meu blog vire livro, pois o conteudo é pouco e ainda está mal organizado, além de ser diverso: os artigos tem pouca relação um com o outro. 

1° Entre no site e se cadastre, colocando suas informações de contato e redes sociais, bem como informações do seu blog: http://blogbooks.com.br/
2° Efetue login no sistema e entre na página http://blogbooks.com.br/blogs/meuBlog para ver o seu link de voto e escolher uma imagem para que possa ser votada.
3° Entre no designer de seu blog e adicione um gadjet de HTML/Javascript: 
4° Coloque a imagem dentro de uma tag "A" apontando para o link de votação.









O código será  o seguinte: 
<a href="http://blogbooks.com.br/blogs/votando/YmxvZ2Jvb2tzXzEyMzQ=" border=0><img src="http://blogbooks.com.br/img/selo_pequeno.gif" border="0" /></a>



E o resultado será:

5° Escolha uma posição de destaque mas que não comprometa a usabilidade de seu blog nem seja muito "agressiva".

6° Divulgue e pronto! Agora cuide do conteúdo do seu blog para que seja didático e instrutivo (no caso de blogs técnicos) ou prazeiroso de se ler na maioria dos casos. Cuide para que o conteúdo tenha divisões e sequências lógicas, como um livro, e suas chances serão maiores.

Have Fun ;)

terça-feira, 17 de agosto de 2010

Adicionando botão Like ao seu blog

Este post é mais um da série "Site aos Pedaços" mostrando mais um "gadeject" que você pode "pendurilhar" no seu blog ou site.

Faz parte da política de boa vizinhança citar a fonte. No caso minhas fontes foram o Blog Mamanunes e o Vagabundia mas acredito que a própria documentação das api's do facebook deve ser bem rica em dicas desse tipo.

Primeiro de tudo você deve saber que a edição do template do seu blog se dá em XML e não em HTML. Isso quer dizer que certos caracteres especiais devem ser substituidos por HTML entities para que funcione. Além disso algumas expressões vistas aqui serão comandos próprios do XML do blogger, que ele interpreta e substitui a sua maneira. Por isso é diferente colocar o  botão like no Blogspot e colocar no Wordpress ou mesmo no HTML puro.

Para HTML puro o código deveria ser esse:

(...)
<iframe src="http://www.facebook.com/plugins/like.php?href=http://vitorrubio.blogspot.com/2010/08/busca-de-cep-com-o-lazarus-parte-1.html&layout=button_count&show_faces=false&width=450&height=60&action=like&font=tahoma&colorscheme=dark" allowTransparency='true' frameborder='0' scrolling='no' style='border:none; overflow:hidden; width:450px; height:60px'/>
(...)

Com o seguinte resultado:



Agora para funcionar no blogger, devemos primeiro encontrar onde publicar. Clique em design e edição do HTML no seu blog e no código procure pela linha:

<div class="post-footer-line post-footer-line-1">

Abaixo dessa linha você já pode colar  o código acima com algumas modificações:
1) Na URL você deverá colocar data:post.url. Este é um comando que diz ao Blogger para usar a url para o post correspondente.
2) Substituir caracteres especiais por Entities, por exemplo substituir < por < e > por >
3) Como o atributo src será validado e concatenado pelo blog, sendo uma "expressão" a ser "calculada" via programação, todo  o atributo src deve ser precedido de expr:

O comando ficará assim:


(...)
<iframe expr:src='&quot;http://www.facebook.com/plugins/like.php?href=&quot; + data:post.url+ &quot;&amp;layout=button_count&amp;show_faces=false&amp;width=450&amp;height=60&amp;action=like&amp;font=tahoma&amp;colorscheme=dark&quot;' allowTransparency='true' frameborder='0' scrolling='no' style='border:none; overflow:hidden; width:450px; height:60px'/>
(...)


Pronto! Agora você pode "pendurilhar" mais essa ferramenta para integração com mídias sociais.

Have Fun ;)

Busca de CEP com o Lazarus - Parte 2 - HTTPSend

Na primeira parte deste tutorial vimos como criar uma função para UrlEncode, ou seja, codificar uma Url para que substitua caracteres especiais por caracteres de escape tornando-a assim uma url válida.

Nesta segunda parte do nosso tutorial de busca de CEP com  o lazarus vamos dar uma breve introdução à classe THTTPSend da unit httpsend, biblioteca Synapse.

Para isso, crie um formulário com 3 edits (edCep, edChave e edUrl) e dois memos (mRequest e mResponse) que servirão, respectivamente, para digitar o CEP a ser procurado, a chave cadastrada no serviço http://www.buscarcep.com.br/. O edUrl será somente leitura e conterá a url composta depois de ter a chave codificada com urlEncode.

Os memos mRequest e mResponse mostrarão, respectivamente, informações do request (pedido) feito ao servidor web e a resposta deste.

Coloque um botão chamado btTesteHttpSend para codificarmos nosso exemplo. Ao final da montagem da form ela ficará como na figura 1:

Figura1 - form principal com 3 edits e dois memos
Não se esqueça de colocar a unit httpsend no uses da unit 1.

Por enquanto não vamos tratar sobre proxy, então, se sua conexão usar proxy recomendo a você usar outro computador / outra conexão ou conversar com o administrador da rede para que  o site http://www.buscarcep.com.br/ entre na lista de excessões do proxy e passe diretamente por ele.


O que precisamos fazer é compor a url como especificado no serviço, passando os parâmetros:
cep=[cep]
formato=xml
chave=[chave cadastrada] separados por "&". Poderemos atribuir a url concatenada à propriedade text do edUrl. 


Depois devemos criar um objeto THTTPSend e executar um comando GET na Url contida em edUrl.Text.


Caso obtivermos sucesso a propriedade Document do HTTPSend terá um stream com todos os bytes que o servidor nos respondeu, no caso um XML, mas poderia ser uma página html, uma imagem etc.


Os principais comandos do protocolo HTTP são GET (que "pede" por dados) e o POST (que envia dados). Quando usamos um Browser, por exemplo, usamos GET sempre que digitamos uma URL ou que usamos uma tag img e esta tem uma url que aponta para uma imagem. Aliás, todas as tags que contem uma URL farão novos gets. Um POST é feito sempre que se preenche e envia um formulário. 


Podemos nos comunicar usando  o protocolo HTTP mesmo sem usar um browser, usando os comandos GET e POST. Além disso, há outros protocolos que podem ser "encapsulados" dentro de HTTP para outras finalidades, por exemplo os SOAP Webservices, que encapsulam dados em um envelope  SOAP e enviam para o servidor através de um POSt. Há outras formas de se fazer webservices mas não vamos discuti-las aqui. 


A cada requisição (mensagem GET ou POST enviada pelo browser ou outro programa) enviada para o servidor este pode responder com um número de status ou ResultCode. 


Uma descrição completa de como funciona o protocolo HTTP pode ser visto na wikipedia ou no W3C

O código para criar a requisição e consultar o site encontra-se abaixo:

procedure TForm1.btTesteClick(Sender: TObject);
var
  HTTP: THTTPSend;
  sucesso: boolean;
begin

  sucesso := false;
  HTTP := THTTPSend.Create;
  try

    edUrl.Text:= 'http://www.buscarcep.com.br/?' + 'cep='+edCep.Text+'&formato=xml&chave='+UrlEncode('1Z3s3/2ZjDt.dcyiLuBy/6mitlDNgt/');
    sucesso := HTTP.HTTPMethod('GET', edUrl.Text);
    mResquest.Lines.Add('URL: ' + edUrl.Text);
    mResquest.Lines.add('---------------------');
    mResquest.Lines.Add(HTTP.Headers.Text);
    mResquest.Lines.add('---------------------');
    mResquest.Lines.add(HTTP.ResultString);
    mResquest.Lines.add(inttostr( HTTP.ResultCode));

    if sucesso then
    begin
        HTTP.Document.Seek(0, soFromBeginning);
        mResponse.Lines.LoadFromStream(HTTP.Document);
    end;
  finally
    HTTP.Free;
  end;
end;  


Como vimos, a cada ação que fazemos jogamos um registro no mRequest para termos um log, no entanto as linhas mResquest.Lines.Add(HTTP.Headers.Text); e mResquest.Lines.add(inttostr( HTTP.ResultCode)); são as mais importantes porque nos mostram os cabeçalhos http enviados e o resultado, respectivamente.

O resultado que esperamos é OK 200. Há uma série de outros resultados que você pode consultar aqui no W3C.

Como resultado da execução, deverá aparecer no seu memo mRequest o seguinte:


"Conversas" HTTP:
============
URL: http://www.buscarcep.com.br/?cep=01136-001&formato=xml&chave=1Z3s3%2F2ZjDt%2EdcyiLuBy%2F6mitlDNgt%2F
---------------------
HTTP/1.1 200 OK
Date: Tue, 17 Aug 2010 15:47:11 GMT
Server: Apache
X-Powered-By: PHP/5.3.2
Content-Length: 597
Keep-Alive: timeout=1, max=100
Connection: Keep-Alive
Content-Type: application/xml; charset="iso-8859-1"


---------------------
OK
200


E no mResponse o seguinte xml:

XML:
101136001SPS?o PauloBarra FundaRuado Bosque- de 1161/1162 ao fim2010-08-07 05:23:091sucesso. cep encontrado local10353550303550308


Como podemos ver na figura 2:
Figura2 - O programa em execução.


A próxima parte deste tutorial ensinará como usar a classe TXMLDocument para ler e interpretar esse XML, seguido pela parte 4 que mostrará como criar uma classe e encapsular tanto a requisição GET com o HTTPSend como a leitura do XML, fazendo com que as informações de endereço, cidade etc vão direto às propriedades da classe. Por último mostraremos, na parte 5, como podemos adaptar nosso request com HTTPSend para usar proxy.

Até lá ;)

Ir Para:


Parte 1 | Parte 2 | Parte 3 | Parte 4 | Parte 5

quinta-feira, 12 de agosto de 2010

Busca de CEP com o Lazarus - Parte 1 - UrlEncode

Buscar um endereço através do CEP é importante, tanto para manter as informações do seu cadastro corretas como para evitar fraudes e prejuizos.

Existem vários serviços na web para a busca de CEP, dentre eles podemos citar:

http://www.byjg.com.br/site/xmlnuke.php?xml=onlinecep
e
http://www.buscarcep.com.br/

Neste tutorial vamos aprender a usar o http://www.buscarcep.com.br/ para pesquisar CEP's e auto-preencher formulários de cadastro, usando o lazarus. Tudo o que veremos aqui pode ser aplicado a qualquer outra tecnologia, desde que você saiba lidar com a "matéria prima" necessária.

Matéria prima:
1) Alguma biblioteca para se fazer requisições http a qualquer site.
2) Alguma biblioteca para manupulação de XML
3) Você deve se cadastrar no site http://www.buscarcep.com.br/ e obter uma chave gratuita. A chave gratuita dá o direito a até 10 consultas por minuto. Guarde esta chave.

Primeiro passo: vamos usar a biblioteca synpase para fazer as requisições ao site. Para isso devemos fazer download da mesma no site oficial http://www.ararat.cz/synapse/doku.php da mesma forma que fizemos no tutorial de lazarus + twitter

Você pode colocar os fontes em um diretório que esteja no search path do lazarus ou no mesmo diretório que o programa. Como nosso programa é simples e não pretendemos alterar a biblioteca vamos usar a segunda opção que é mais fácil. Caso use esta biblioteca em muitos projetos a primeira opção torna-se obrigatória.

Antes de começar a mecher com a biblioteca synapse precisaremos criar uma função de UrlEncode. Explicando: alguns caracteres não podem aparecer numa url porque são caracteres especiais, destinados a comandos. Esse é o caso da barra / (separa diretorios/recursos) da interrogação ? (separa url de parâmetros) e assim por diante.

Para que esses caracteres especiais possam ser colocados numa URL eles precisam ser codificados de uma forma especial que usa o caractere % como escape. Por exemplo o caractere         é representado por %20. Esse 20 é hexadecimal e corresponde ao decimal 32, ou seja, o código do espaço na tabela ascii.

Como a chave obtida no site pode ter caracteres especiais, criaremos uma função pública estática e global para transformar alguns caracteres especiais em caracteres "escapados" com %.

Usaremos dois vetores e um laço for aninhado para criar essa função. Não é a maneira mais performática, podemos melhorar isso depois, mas é a mais fácil de se entender e portar para outras linguagens.

function UrlEncode(url: DOMString): DOMString;
var
   substitutos:      array[1..20] of  string = ('%21', '%2A', '%27', '%28', '%29', '%3B', '%3A', '%40', '%26', '%3D', '%2B', '%24', '%2C', '%2F', '%3F', '%25', '%23', '%5B', '%5D', '%2E');
   substituidos:  array[1..20] of  char = ('!', '*', '''', '(', ')', ';', ':', '@', '&', '=', '+', '$', ',', '/', '?', '%', '#', '[', ']', '.');
   i, j: integer;
   tmp: string;
begin
     for i := 1 to Length(url) do
     begin
          for j := 1 to 20 do
          begin
               if url[i] = substituidos[j] then
               begin
                  tmp := substitutos[j];
                  break;
               end
               else
                   tmp := url[i];
          end;
          Result := Result + tmp;
     end;
end; 

Declare esta função na seção implementation e coloque seu cabeçalho na seção interface de sua unit.

function UrlEncode(url: DOMString): DOMString;

Repare aqui que o tipo de entrada e retorno da função é uma DOMString. DOMString nada mais é do que uma WideString de 16 bits normal. Você pode substituir por WideString ou adicionar a unit DOM no seu uses. Perceberá que na unit DOM DOMString está defibido como DOMString = WideString;

Mais tarde falaremos da Unit DOM, necessária para se trabalhar com XML, mas já adiantando: sempre que trabalhar com XML estará trabalhando com Widestrings, que precisarão ser corretamente convertidas para utf-8 a fim de serem exibidas corretamente nos edits e memos.

Informações adicionais
UrlEncode no .net: http://msdn.microsoft.com/pt-br/library/zttxte6w(VS.90).aspx
UrlEncode no php: http://php.net/manual/en/function.urlencode.php
Página que codifica URL's: http://www.albionresearch.com/misc/urlencode.php
A melhor referência sobre UrlEncode: http://www.w3schools.com/TAGS/ref_urlencode.asp

Ir Para:


Parte 1 | Parte 2 | Parte 3 | Parte 4 | Parte 5

terça-feira, 10 de agosto de 2010

Strings e Delphi 2010 na Clube Delphi 120

Saiu um artigo meu na Revista Clube Delphi 120 sobre strings no Delphi 2010, como migrar, como usar, como elas funcionam e o que mudou com o Unicode.

Na verdade esse assunto daria muito mais "pano pra manga" e apenas os esboçamos.  Sugiro que o leitor acesse o site do Unicode Consortium e observe a quantidade de material que exsite por lá: desde tabelas de caracteres até algoritmos para implementar todas as novas peculiaridades que um sistema multilingue, multicaracter e "multitamanho" deve ter. Especialmente como são formados os caracteres e como são mapeados e classificados, utf8, utf16, utf32 e assim por diante.

Esqueça de vez a antiquíssima tabela ASCII com seus meros 127 caracteres mais os extendidos. As novas linguagens, principalmente as dinâmicas, já são todas unicode e essa mudança no Delphi 2010 não é só esperada como é muito bem-vinda.

Recentemente eu estava conversando com  o Marlon Nardi sobre o problema de você ter um sistema feito em Delphi 7 que usa o SQLServer e tentar migrar para o Delphi 2010. Ao tentar salvar um registro você pode receber exceptions de tipos incompatíveis: string e WideString. Isso se dá porque as strings que estão vindo para o DataSet, sejam constantes, variáveis, edits ou controles data aware já são todas widestrings, mas os TPersistentFields adicionados aos formulários não. Solução: apagar os persistent fields de todos os formularios e adicionar novamente.

Talvez ajude a agilizar se você abrir com o notepad++ todos os dfm e .pas e trocar o nome da classe antiga (TStringField dependendo da versão do delphi, do banco, do dataset/tecnologia usado) pelo nome da classe nova para lidar com widestrings (TWideStringField dependendo de um monte de fatores, claro).

O melhor a fazer seria evitar de se usar os persistent fileds e controles data aware e usar uma camada intermediária para fazer esse "meio de campo". Isso tornaria essas migrações muito mais fáceis.

Espero que gostem do artigo. Os estudantes de linguas/letras gostarão especialmente das tabelas de caracteres do site da Unicode. Lá existem até tabelas dos alfabetos élficos do universo de Tolkien, muito interessante.

sexta-feira, 6 de agosto de 2010

Linux, windows, cloud computing e uma geração de pnéis

Sobre linux, windows, linguagens de programação


Aqui passeando pela net, por motivos um tanto quanto estranhos, resolvi pesquisar sobre o  Kurumin, projeto que como todos sabemos
já está oficialmente descontinuado, e que uma tentativa de continuação gerou alguns atritos entre seus desenvolvedores.
Encontrei um link interessante aqui http://www.gdhpress.com.br/blog/linux-desktop/, onde Morimoto fala que o linux no Desktop já não é tão importante assim, tendo em vista que ele já domina nos servidores e nos sistemas embarcados, e que nos desktops o que irá imperar são as aplicações na nuvem.


Existem muitos comentários, mas este em especial, do próprio morimoto me chamou a atenção:

Eu considero que proposta político-filosófica tem mais atrapalhado do que ajudado na popularização do Linux. Essa insistência em tentar associar "software-livre" com socialismo, militância e movimentos de esquerda é um fator que causa mais aversão ao sistema do que qualquer deficiência técnica.


Concordo plenamente tanto com o artigo como com o comentário.

Já fiz muitos posts apaixonados sobre tecnologias (Delphi) e Sistemas operacionais livres.
A grande realidade é que nenhuma dessas tecnologias realmente embarcará se não te ajudar a:
1) Ganhar dinheiro
ou
2) Economizar dinheiro
ou ainda
3) Economizar tempo e ganhar entretenimento


Computadores são mais do que simples máquinas. E saber programar é antes de tudo um exercício de administração. Parece um paradoxo dizer que programação (geralmente asociada a área de exatas)
se relacione com administração, mas você tem muitas coisas a administrar: tempo, performance, espaço em disco, espaço em memória etc... As vezes forças mutuamente exclusivas devem ser equilibradas.
Um exemplo disso é um compressor de arquivos, como winzip. A opção mais rápida compacta menos, gerando um arquivo maior e maior ocupação de espaço. A opção que compacta mais exige mais processamento, demora mais para compactar.

Acredito que o kurumin teve seu início, meio e um fim digno, mas toda distro linux, por ser livre, é mais efêmera. Elas tem um tempo de vida mais curto no desktop.
O windows é um SO que já mudou totalmente, várias vezes, mas continua com o mesmo nome e a mesma marca. Já o linux ele evolui através de distros.
A distro do momento agora, para desktop, é o ubuntu (entre algumas outras muito interessantes). Mas isso pode logo mudar.

O linux em desktop parece que nunca vai pegar. Isso porque os jogos, em sua maioria, não rodam no linux, pelo menos não sem um grande esforço e queima de neurônios por parte do usuário.
E é perfeitamente compreensível que o usuário não queira queimar neurônios em seu período de lazer.
Agora em dispositivos móveis e servidores o linux é imbatível e não tem pra ninguém.

Esse artigo explica muito bem porque alguns encontram dificuldades e até gentem uma certa aversão pelo linux:
http://apimente-br.tripod.com/LNW.htm 

Eles tentam encontrar no linux um windows legal e de graça. Não. O linux é outro SO, outro tipo de SO. Talvez o ReactOS um dia seja esse windows livre. Vale a pena conhecer: http://www.reactos.org/en/index.html

Uma coisa que parece uma tendência, e que se fala muito, é de computação na nuvem ou cloud computing.

Além de hospedagem para aplicações e serviços esse novo hype engloba as proprias aplicações em si. Um exemplo é o Google docs, google apps e EyeOs (meu preferido).

Muitos aplicativos completos, e até jogos rodam hoje a partir do browser, e novas tecnologias como Yui, mootols, JQuery e silverlight tornam as aplicações web cada vez mais parecidas com aplicações desktop.

Nesse novo contexto os browsers são o SO da nova era, e o javascript e html são como Assembly para esses novos SO's.
Por favor, isso é apenas uma metáfora, porca eu confesso, mas não é para ser levado ao pé da letra.
 
Sou meio cético quanto a cloud computing. Isso porque parece um retrocesso e uma volta aos terminais burros. Se cada ano que passa as hd's, processadores e memórias ficam maiores e mais poderosos me parece um contra-senso, desperdício e até uma afronta ao meio ambiente jogar tudo na web e manter o seu ambiente vazio.
Além disso você deve partir do pressuposto de que a web é 100% confiável, infalível e que qualquer indivíduo que faça algo ilegal na web possa ser identificado, o que demanda o cadastro de um documento no serviço da web, que por sua vez acaba com o anonimato na rede.
Em vez dessa volta ao terminal burro eu acredito em computação ubíqua, onde os seus arquivos e programas não estarão apenas no servidor da web, mas onde você quiser: computador, celular, notebook, televisão. E com sincronia. Cada vez que você atualiza um documento do seu celular, por exemplo, o documento é sincronizado com os outros lugares onde ele é armazenado.
Lógico que todos os seus documentos não vão caber no celular, mas eles podem ser "browseados" (que anglicismo tosco meu Deus) a partir da web ou de seu PC, baixados para o celular e editados sob demanda, voltando para o lugar de onde vieram e retransmitindo as atualizações. Tudo isso, claro, com controle de versão e tunel do tempo, igual o google wave.
Além disso é necessária uma inteligência para, ao se compartilhar arquivos com os amigos, ter a opção de compartilhar, em vez de cópias de um arquivo, O MESMO arquivo, para que todos possam editar ao mesmo tempo.

Uma outra coisa, interessante, seria toda uma infraestrutura de processamento paralelo. Já que as casas vão ser equipadas (se já não o são) com vários dispositivos inteligentes, como celulares, computadores, videogames e televisores, porque não compartilhar/dividir o processamento?
Assim, cada vez que um aparelho precisasse fazer um processamento difícil, como a renderização de um gráfico 3d, poderia "pedir ajuda" para um que estivesse ocioso, como a TV.
Para evitar que todos os aparelhos ficassem ligados ao mesmo tempo desperdiçando energia elétrica o usuário poderia assinar um serviço de processamento/servidor online. Isso sim seria a verdadeira cloud computing: caso uma aplicação necessitasse de uma grande demanda de cálculos e processamento, como um game, ele poderia, através da computação paralela/clustering, dividir o processamento (ou uma porcentagem dele) com um servidor online pelo qual você paga uma assinatura para usar processamento dele em cluster.


Bom, viajei?

quarta-feira, 4 de agosto de 2010

Só dá aula quem quer MUITO

Estava eu no curso de pós graduação da Fatec-SP, disciplina "Didática do Ensino Superior" quando o professor Hiromasa Nagata (Ninja! Grande Guru!) indica o texto http://www.gazetadopovo.com.br/ensino/conteudo.phtml?tl=1&id=975973&tit=Professor-vai-virar-artigo-de-luxo

 

Triste, mas verdadeiro.

Postagens populares

Marcadores

delphi (60) C# (31) poo (21) Lazarus (19) Site aos Pedaços (15) sql (13) Reflexões (10) .Net (9) Humor (9) javascript (9) ASp.Net (8) api (8) Básico (6) Programação (6) ms sql server (5) Web (4) banco de dados (4) HTML (3) PHP (3) Python (3) design patterns (3) jQuery (3) livros (3) metaprogramação (3) Ajax (2) Debug (2) Dicas Básicas Windows (2) Pascal (2) games (2) linguagem (2) música (2) singleton (2) tecnologia (2) Anime (1) Api do Windows (1) Assembly (1) Eventos (1) Experts (1) GNU (1) Inglês (1) JSON (1) SO (1) datas (1) developers (1) dicas (1) easter egg (1) firebird (1) interfaces (1) introspecção (1) memo (1) oracle (1) reflexão (1)