1 de agosto de 2011

Gerar JSON a partir de objeto Ruby

Que eu saiba não existe algo pronto no Ruby que, a partir de um objeto, gere um Json com todas as propriedades dele.

Encontrei na web um exemplo que mostra como criar um módulo que gera o Json de todas as propriedades de algum objeto.

Porém este exemplo assume apenas que as propriedades sejam simples. Quando a propriedade for um Array (que não inclui o módulo em sua origem), ele chega vazio no Json.

Fiz duas adaptações no exemplo:
1) Gerar Json de elementos simples de um Array
2) Gerar Json dos elementos (do Array) que têm o módulo incluído



Então, o código abaixo deve funcionar :)

p = Person.new
p.name = "Leandro"
p.age = 24

n1 = Note.new("first note")
a1 = Address.new("cool!")
n1.addresses = []
n1.addresses << a1

n2 = Note.new("last note")

p.notes = []
p.notes << n1
p.notes << n2

p.simple_notes = []
p.simple_notes << "abc"
p.simple_notes << "123"
  
p.to_json
Tente imprimir "p.to_json" e verás todas as propriedades em cascata bonitinhas dentro do Json!

18 de abril de 2011

Enviar email utilizando Java

Criei uma estrutura em Java para enviar emails de forma simples. Basta apenas configurar o host do smtp (algum personalizado ou o próprio Gmail).

Forma de uso (mais detalhes no Github.):

13 de abril de 2011

Truncate com Jquery

Eu estava precisando truncar (cortar, diminuir) o tamanho de um texto na página e dar a opção para o usuário expandir/esconder, porém as bibliotecas disponibilizadas são muito pesadas.

Fiz um script, curto, simples, que trunca o texto selecionado recebendo a quantidade máxima de caracteres, e coloca um link para o usuário expandir/esconder o texto.

Além de ser leve tem a vantagem de manter o conteúdo do elemento original, permitindo assim a visualização do mesmo caso o browser não carregue javascript corretamente.

var len = $("#longText").text().length;
if (len > maxCharacters) {
    var truncated = $("#longText").text().
        substring(0, maxCharacters);
    truncated = truncated.replace(/\w+$/, '');
    var spanTruncate = "";
    $("#longText").after(spanTruncate);
    $("#longText").hide();
    $("#truncate").html(truncated);
    var linkToggle = "
more" $("#truncate").after(liknToggle); $("#truncate").show(); }

O evento para quando o usuário clicar no link expandir/esconder:
$("#toggle").click(function(event) {
    event.preventDefault();
    if ($(this).html() == "hide") {
        $("#longText").hide();
 $("#truncate").show();
 $(this).html("more");
    } else {
 $("#truncate").hide();
        $("#longText").show();
 $(this).html("hide");
    }
});

O código completo, com um exemplo de como utilizar, está disponibilizado no meu Github, para que possa ser melhorado sempre por quem estiver interessado em contribuir com o projeto.

Gerador de thumbnails em Java

Resolvi compartilhar um gerador de thumbnail de imagens muito útil que sempre utilizo.
Basicamente o código recebe o arquivo de origem, o destino, a largura e a altura máxima do thumbnail a ser gerado.

É tudo muito simples e requer apenas a biblioteca padrão awt do Java.

Primeiro vamos ler o arquivo de origem:
FileInputStream input = new FileInputStream(source);
BufferedImage bufImage = ImageIO.read(input);

Agora precisamos calcular o scale, que será o índice para redimensionar a área da imagem. Se a altura original da imagem for maior, o scale será o resultado da divisão da altura do thumb pela altura original. E vice- versa.
double scale1 = (double) width / (double) bufImg.getWidth();
double scale2 = (double) height / (double) bufImg.getHeight(); 
double resultScale = scale1 > scale2 ? scale2 : scale1;

Utilizando o resultado obtido para o cálculo do redimensionamento:
int realWidth = bufImg.getWidth();
int realHeigth = bufImg.getHeight();
BufferedImage imageScaled = new BufferedImage((int) (
    w * resultScale), (int) (h * resultScale), 
    BufferedImage.TYPE_INT_RGB);

Só o BufferedImage gerado não basta. É necessário, por fim, desenhar os gráficos da imagem novamente com os novos parâmetros calculados:
Graphics2D g2 = scaled.createGraphics();
g2.setComposite(AlphaComposite.Src);
g2.drawImage(img.getScaledInstance((int) (realWidth * resultScale), 
    (int) (realHeigth * resultScale), Image.SCALE_SMOOTH),
    0, 0, (int) (w * resultScale), (int) (h * resultScale), null);
g2.dispose();

// Escrevendo no arquivo de sáida
ImageIO.write(imageScaled, "JPG", output);

Código completo:
public class ThumbGenerator {

    public static boolean generate (File source, File dest, 
                   int height, int width) throws IOException {
        if (source != null && dest != null) {
     FileInputStream input = new FileInputStream(source);
     try {
                BufferedImage bufImage = ImageIO.read(input);
  if(bufImage != null) {
      double scale = calcScale(bufImage, width, height);
      BufferedImage imageScaled = scale(bufImage, scale);
      FileOutputStream fos = new FileOutputStream(dest);
      ImageIO.write(imageScaled, "JPG", fos);
      fos.close();
                    input.close();
      return true;
  }

     } catch (Exception e) {
         e.printStackTrace();
     }
 }
 return false;
    }

    private static double calcScale(BufferedImage img, 
                                      int width, int height) {
        double scale1 = (double) width / (double) img.getWidth();
        double scale2 = (double) height / (double) img.getHeight();
        double scale = scale1 > scale2 ? scale2 : scale1;
 return scale;
    }

    private static BufferedImage scale(BufferedImage img, 
                                               double scale) {
        int w = img.getWidth();
        int h = img.getHeight();
        BufferedImage scaled = new BufferedImage((int) (w * scale), 
                (int) (h * scale), BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = scaled.createGraphics();
        g2.setComposite(AlphaComposite.Src);
        g2.drawImage(img.getScaledInstance((int) (w * scale), 
                (int) (h * scale), Image.SCALE_SMOOTH),
                0, 0, (int) (w * scale), (int) (h * scale), null);
        g2.dispose();
        return scaled;
    }
}

Daí é só chamar:
ThumbGenerator.generate(imgSource, output, 400, 400); 
// Ver resultado no arquivo output

ThumbGenerator.generate(imgSource, output, 400, 600); 
ThumbGenerator.generate(imgSource, output, 600, 400); 
ThumbGenerator.generate(imgSource, output, 100, 100); 

4 de abril de 2011

Parser HTML com Java

Fazer parser HTML é uma tarefa extramamente complicada, visto que HTML não é uma linguagem regular, e por isso o uso de expressões regulares em HTML é, na maioria das vezes, inconsistente.

Para facilitar a manipulação de páginas HTML, o time do Apache Maven desenvolveu a biblioteca HTML Parser.

Esta biblioteca visa a simplicidade e performance em manipular HTML. Basicamente trabalha na extração de objetos DOM, que são armazenados em árvores, permitindo assim uma fácil manipulação.
Encapsulei a tarefa de navegar entre todos os nós da árvore de forma recursiva, permitindo assim a manipulação de uma página HTML completa sem expressão regular:
String marcaCarro = MyHtmlParser.getContent(resourceHtml, "div class\"carroStyle\"");
Se existir mais de um elemento com o mesmo atributo na página, basta informar qual a posição passando um terceiro argumento:
String marcaCarro2 = MyHtmlParser.getContent(resourceHtml, "div class\"carroStyle\"", 2);
Subi este projeto no meu Github, livre a todos que quiserem ajudar a melhorá-lo.