Todos os posts de Rafael Biriba

Retrospectiva 2010: Recordar é viver

2010 já acabou… e 2011 está só começando…

Como já é de costume, todo inicio de ano eu faço uma espécie de retrospectiva para mostrar os melhores posts, os mais visitados e também as estatísticas.

Se você não viu, veja aqui a retrospectiva de 2009.

Primeiro, vamos ver como foi o ano para o autor do blog(eu :))… 2010 foi um ano muito enrolado para mim…  últimos períodos da faculdade, trabalho de conclusão de curso (retivico.com, depois falo mais sobre ele), finalzinho do meu estágio e logo em seguida, minha efetivação como desenvolvedor da Globo.com. Juntando tudo isso e algumas coisas mais, fiquei sem tempo para dar uma atenção especial para o blog.

Bom, então seguindo com a retrospectiva 2010, em relação ao blog, vamos então ver os posts e estatísticas:

Os posts mais lidos pelo feed/rss:

Os posts mais visitados do blog:

Estatísticas de acesso:

Ano de 2010:
Visitantes: 45354
Páginas visualizadas: 81798
(Google Analytics)

Comparativo geral com 2009:
Visitas: Crescimento de 79%
Pageview: Crescimento de 64%

Mais um ano se passou… Conhecimentos foram compartilhados e a audiência subiu mais um pouquinho…

Aproveito a oportunidade para agradecer a todos os amigos, que me sugerem idéias e me incentivam diariamente a continuar escrevendo…

Agradeço também a você, que teve e continua tendo muita paciência para ler o que eu escrevo mesmo com alguns erros de português, mesmo discordando das minhas opniões… Muito obrigado! Afinal, de nada adianta um blog rico em conteúdo, sem nenhum leitor 😉

Para 2011, estou planejando algumas alterações significativas para o blog:

  • Uma seção dedicada para assuntos de Travian, já que os posts atuais fazem muito sucesso. Separando o tema em uma seção exclusiva, posso postar com mais frequencia, sem poluir muito a home do meu blog 😉
  • Transferir o blog para um servidor mais rápido – Já foi feito logo nos primeiros dias de 2011
  • Testar e instalar um plugin de cache para melhorar o desempenho do blog, servindo as páginas mais rapidamente.
  • Blogar com mais frequência e variar mais os assuntos. Aceito sugestões de assuntos para os post.

E não esqueçam que em fevereiro terá o aniversário de 2 anos do blog :D. Confira a festa do ano passado, 1 ano do blog. 😉

Então é isso… Feliz 2011 para todo mundo… \o/

Share

Não deixe de atualizar seu wordpress: versão 3.0.4 corrige falha de segurança

 

http://www.wordpress.org/

 

Dia 29 de dezembro a equipe do WordPress liberou a versão 3.0.4 com uma importante correção de segurança.

Um bug no core da biblioteca KSES foi corrigido. Essa biblioteca é usada em muitos lugares no wordpress, e parece que tem alguma ligaçao com a renderização dos htmls.

O wordpress.org não revela bem qual seria a vulnerabilidade, até para proteger os usuários que possuem as versões com a falha. Mas tudo indica um problema de XSS (Cross-site scripting), o que permitia até alteraçoes no blog, caso fosse bem explorada.

Pedido de atualização do wordpress para 3.0.4
Pedido de atualização do wordpress para 3.0.4

 

Infelizmente para que tem o blog em português, versão PT ou BR, ainda não tem essa atualização disponível. Resta sentar e esperar, ou então fazer a atualização na versão em inglês mesmo (US).

IMPORTANTE: Quem já possui o wordpress com a versão 3.*, esse update deve ser aplicado, pois foi considerado como (atualização crítica de segurança)!

Não se esqueça de fazer o backup antes de fazer qualquer atualização no seu blog…

Leia também: http://wordpress.org/news/2010/12/3-0-4-update/

Share

OI Velox invade a privacidade de seus usuários com campanha de seu navegador

Desde o dia 30 de novembro, muitos usuários do OI Velox vem reclamando de terem recebido um spam com a campanha publicitária do novo navegador (Imagem abaixo)

http://navegador.oi.com.br/
http://navegador.oi.com.br/

Não há nada de errado com o navegador disponibilizado pela empresa, a não ser, pela forma inusitada de como foi divulgada.

Infelizmente passei pela experiência na madrugada do dia 02/dez/2010, onde eu estava navegando no site do submarino, e do nada, a minha requisição foi interceptada pela oi velox, e no lugar do produto que escolhi, apareceu a publicidade do navegador oi. (Tela abaixo)

Agora, eu fico me perguntando… E se eu estivesse efetuando uma compra no site ? Essa campanha publicitária poderia atrapalhar e muito no processo.

Ou melhor, uma prova online, daqueles tipos que tem uma mensagem “Verifique sua conexão de internet, para que não haja interrupção durante o teste”. Esses tipos de provas são aplicadas por empresas de RH por exemplo.

Continuei olhando a página do navegador, e fiquei surpreso quando li o conteúdo dessa página…

Para quem não consegue ler da imagem, vou transcrever abaixo:
O serviço NÃO ESTÁ ATIVO para esta conta de usuário neste computador. Se desejar desativar também para todas as contas de usuário e todos os computadores em sua CASA, clique no botão “Desativar para a sua CASA”.

Não satisfeitos em interceptar a conexão no meu computador, ele ainda me diz que vai fazer isso com todos os computadores da casa. Não teve jeito, corri no meu outro computador (um desktop velhinho), e comecei a navegar até que finalmente a mensagem apareceu, e como sempre, indevidamente.

Investigando o problema mais a fundo, descobri que o site da OI cria cookies locais para identificar os usuários que optaram ou não pelo uso do navegador. Sabe o que isso significa ? Que se você limpar seus cookies, logo a mensagem do navegador da oi aparecerá para você novamente !!!

Não acredita que ele faz essas verificações com cookies ? É tudo tão ridículo, que está escrito na política de privacidade, no item cookies (http://navegador.oi.com.br/status/politica_de_privacidade.html)

Tenho certeza que existem leis que proibem esse tipo de atitude. Quando eu assinei o Oi Velox, assinei um provedor de internet e não lembro de ter aceitado nada referente a campanhas publicitárias, principalmente as que invadem a sua tela, interrompendo a minha experiência de navegação…

Agora, o que esse tal navegador faz ? Monitora você… Todos os links que você clicar, todas as buscas que fizer, ele armazena tudo… Com simples propósta de armazenar para te sugerir links de acordo com o seu perfil.

Mas na verdade esse rastreamento é de interesse da OI e seus parceiros, que permite a segmentação do público por publicidade fornecida. Assim fica mais fácil de mostrar anúncios de esporte para que navega muito nas páginas de esporte…

O pior dessa história toda, é que esse rastreamento não é explicado com clareza para os usuários. Não sabemos ao certo, o que pode ser feito com todos esses dados coletados e muito menos a que nível de segurança eles estão guardados.

Isso para mim é uma trapaça, onde é fornecido um serviço( como uma máscara) que promete facilitar a navegação, mas em troca, todo o seus histórico de acesso e navegação ficam a disposição da Oi…

O Serviço é tão ruim, que eu habilitei só para testar e também para poder escrever essa matéria, e depois não consegui achar nenhum link para desativar, ou quepudesse me informar se o serviço estava ativo ou não.

Depois de tanto procurar, achei o link abaixo e parece que consegui desativar. Mas infelizmente, não há nenhum link que possa me garantir que esse serviço não está ativo.

Conclusão: Recomendo que NÃO habilitem esse serviço !! Visite o link: http://navegador.oi.com.br/status/desativado.html e escolha a opção: Desativar para sua a casa. Na dúvida, exclua os seus cookies de navegação para garantir que ainda está no sigilo de sua navegação.

Curiosidade para reforçar a matéria… Você usuário velox, experimente digitar algum link errado… Ao invés de receber a tradicional página não encontrada, aparece uma página da oi, com muitos banners publicitários relacionado ao link que você digitou errado ! Sensacional não ? Até na página de erro existe uma exploração comercial…


Deixo essa matéria em aberto para quem quiser compartilhar a sua opnião…

Share

HTML5: Trocando mensagens entre a página e iframes

Por questões de segurança e privacidade, os navegadores impedem que haja comunicação entre os conteúdo de diferentes domínios. Ou seja, scripts em diferentes dominios (cross-domain) não podem se interagir.

Na prática seria assim… Já imaginou, se um simples anúncio do google adsense, pudesse controlar a página em que ele foi colocado ? Ele iria alterar o background, trocar titulos na página e bagunçar tudo.

Por isso essa é uma importante funcionalidade nos navegadores, pois evita com que páginas desconhecidas (em domínio diferente) de controlar a página atual em que está visitando.

Com o HTML5, podemos contornar esse problema facilmente. Utilizando o Cross-document messaging, podemos estabelecer comunicação entre páginas e documentos no html, sem se procupar com a origem do domínio. Foi desenvolvido justamente para permitir essa comunicação, sem colocar em risco a segurança da página. (cross-site scripting attacks).

Cross-site messaging funciona apenas no HTML5, e está disponível nas seguintes versões de navegadores:

  • Internet Explorer 8.0+
  • Firefox 3.0+
  • Safari 4.0+
  • Google Chrome 1.0+
  • Opera 9.5+

Vejamos então um exemplo prático:

Digamos que em sua página inicial, você tem o seguinte iframe.

1
<iframe id="exemplo-iframe" src="http://www.exemplo.com/teste.html"></iframe>

Se você quiser mandar o titulo do seu site para o iframe, você precisa usar o cross-document messaging pois ele está em um outro domínio. Veja abaixo como você faria para disparar essa mensagem:

1
2
3
4
<script language="javascript">
var iframe = document.getElementById("exemplo-iframe").contentWindow;
iframe.postMessage("Titulo do Site", "*"); 
</script>

Na linha 2 é onde obtemos o controle do iframe. Na linha 3 é onde disparamos a mensagem. Note que estamos passando um “*” como segundo argumento do postMessage, o que significa que a mensagem é enviada para todos os domínios. Poderiamos ser mais específicos e disparar apenas para o domínio do iframe (exemplo.com).

Agora, no lado do iframe, só falta receber essa mensagem. Veja abaixo o exemplo do código que o iframe deve carregar:

1
2
3
4
5
6
7
8
<script language="javascript">
function displayMessage(event) {
    var message = event.data;
    alert(message);
    event.source.postMessage("Recebido com sucesso!",  "*");
}
window.addEventListener("message", displayMessage, false);
</script>

Vou começar explicando pela linha 7,  onde é estabelecido o listener, que é responsável por “escutar” as mensagens recebidas e chamar a função displayMessage. Na linha 3, recebemos a mensagem numa variável. Na linha 4 exibimos ela no alert do javascript. Na linha 5, é disparado uma mensagem para o “remetente”, ou seja, podemos enviar uma mensagem para confirmar o recebimento por exemplo.

Lembrando que para que a mensagem enviada na linha 5 seja recebida corretamente pela sua página inicial, você tem que adicionar um listener, da mesma forma que foi feito no iframe. Fazendo assim, é possível fazer trocas de informações entre as páginas de diferentes domínios.

No exemplo acima, qualquer site estaria habilitado em trocar informações com aquela página do iframe (http://www.exemplo.com/teste.html) e dependendo do contexto e de como foi implementado, pode vir a ser uma falha de segurança, portanto, utilize com cuidado.

Share

Net-SFTP: Calculando o progresso do upload

Estou escrevendo esse post, para complementar o post sobre o timeout do net-sftp, onde fiquei devendo essa a solução de calculo do progresso…

Para obter o progresso durante o upload, você precisa usar o callback do método upload! e jogar numa variável os valores do tamanho local e do tamanho do arquivo no destino.

Vejamos um pequeno exemplo, retirado da documentação:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
require 'rubygems'
require 'net/sftp'
Net::SFTP.start('192.168.0.2', 'rafaelbiriba', {:password => 'teste', :timeout => 3}) do |sftp|
  sftp.upload!("/Users/rafaelbiriba/Projects/temp/video-teste-sftp.mp4", "/home/rafaelbiriba/video-teste-sftp.mp4") do |event, uploader, *args|
    case event
    when :open then
      # args[0] : file metadata
      puts "starting upload: #{args[0].local} -> #{args[0].remote} (#{args[0].size} bytes}"
    when :put then
      # args[0] : file metadata
      # args[1] : byte offset in remote file
      # args[2] : data being written (as string)
      puts "writing #{args[2].length} bytes to #{args[0].remote} starting at #{args[1]}"
    when :finish then
      puts "all done!"
    end
  end
end

No exemplo acima podemos verificar:

  • Ao abrir a conexão (when open), podemos chamar args[0].size e obter o tamanho total do arquivo
  • Durante a transferência (when put), ao chamar args[1] podemos obter o tamanho do arquivo remoto

Com isso, quando o tamanho total do arquivo for igual ao tamanho do arquivo remoto, então o upload estará terminado (100%). Para obter as porcentagens, basta fazer o cálculo.

Confira no exemplo abaixo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
require 'rubygems'
require 'net/sftp'
@total_size = 0
@remote_size = 0
@current_progress = 0
 
def update_sftp_progress
  progress = (@remote_size*100)/@total_size)
  if @current_progress < progress then
    @current_progress = progress
    puts "Uploading: #{@current_progress}%" 
  end
end
 
Net::SFTP.start('192.168.0.2', 'rafaelbiriba', {:password => 'teste', :timeout => 3}) do |sftp|
 sftp.upload!("/Users/rafaelbiriba/Projects/temp/video-teste-sftp.mp4", "/home/rafaelbiriba/video-teste-sftp.mp4") do |event, uploader, *args|
   case event
     when :open then
       @total_size = args[0].size
       puts "Starting upload..."
     when :put then
       @remote_size = args[1]
       update_sftp_progress
     when :finish then
       puts "Finished!"
     end
   end
end

Toda vez que o arquivo no destino for incrementado, o evento (:put) será disparado, chamando o método update_sftp_progress.

Nesse método é feito o cálculo da porcentagem(ver no exemplo acima). Ao invés de imprimir a porcentagem(com puts), você também pode salvar no banco de dados, ou utilizar o valor para fazer uma barra de progresso.

Espero ter ajudado, 😉

Share

Realidade aumentada no submarino: experimente as obras de arte antes de comprar

http://www.submarino.com.br/

Essa semana o submarino implementou um sistema com realidade aumentada, onde você pode experimentar uma obra de arte em sua parede, antes mesmo de comprar.
Confira você mesmo: http://www.submarino.com.br/portal/galeria_motor_ra

Para quem não sabe o que é isso, segue um pouco do conceito de Realidade Aumentada:

“Realidade Aumentada (RA) é uma linha de pesquisa dentro da ciência da computação que lida com integração do mundo real e elementos virtuais ou dados criados pelo computador (Retirado do wiki)”

Na prática, usamos a realidade aumentada da seguinte forma:
Um desenho é posicionado em algum lugar, de forma que essa figura seja a “única” no cenário. Então apontamos uma camera em direção ao desenho, e uma aplicação no computador transformará essa figura em algum elemento virtual.

Sendo assim, é possível fazer o que o submarino fez. Você imprime uma figura e cola na parede onde quer colocar a pintura. Depois disso, ele utiliza a sua webcam para capturar a imagem do ambiente e a aplicação troca a figura impressa por alguns quadros, e você pode ver virtualmente os quadros na sua parede, facilitando assim a escolha e a compra.

Hoje, a realidade aumentada já é utilizada em alguns lugares, como jogos e aplicativos comerciais.

No Big Brother Brasil (no inicio de 2010), a Globo.com usou também a realidade aumentada numa aplicação de interação virtual com os participantes.

Outro exemplo, são os aplicativos para iPhone, como o do Bradesco, que junto com a bússola, gps e a camera do aparelho, mostra a você onde tem um caixa mais próximo e a distância até ele.

Confesso que essa nova proposta do submarino foi bastante inovadora! Dá para aplicar o modelo com vários produtos… Já pensou poder ver qual tamanho de TV fica melhor na sua sala usando realidade aumentada ? Ou ver se o fogão branco combina mais com a sua cozinha do que um fogão preto ?

Embora já existam vários exemplos, acredito que seja uma tecnologia em crescimento e que ainda possui muitos pontos a serem explorados. Então, vamos esperar para ver as novidades… 😉

Share

[off-topic] Blogueiros de todo o mundo à favor da “água para todos” (Blog Action Day)

http://blogactionday.change.org/
http://blogactionday.change.org/

Blog Action Day é um evento anual que acontece todo dia 15 de outubro, onde blogueiros de todo o mundo se unem, publicando informações e levantando discussões sobre um importante problema global. Participei no ano passado  falando sobre as mudanças climáticas (ver post), esse ano será sobre a Água.

A campanha já conta com mais de 4950 blogs, 38 milhões de leitores e 137 países envolvidos (Dados obtidos em 15/10/2010 – http://blogactionday.change.org/)

Mas por que Água ?

Exatamente agora, bilhões de pessoas na terra não tem acesso a água limpa e segura para beber. O acesso a essa água não é só um direito humano, mas um problema ambiental. A água é um problema global e está afetando todos nós !

O que posso fazer para ajudar ?

O Blog Action Day 2010 está aí pra isso. Ajudar a divulgar o assunto para estimular as pessoas a economizar àgua e reconhecer que é um problema global. Blogueiros de mais de 125 países estarão escrevendo sobre isso nesse dia 15 de outubro.

Você também pode ajudar assinando a petição no final desse post!!!

Assuntos abordados pela campanha:

– O problema da escassez de água:

  • 40 bilhões de horas: Mulheres africanas caminham por mais de 40 bilhões de horas carregando mais de 18 kg de água impŕopria para beber. Ler mais >>>
  • 38.000 crianças por semana: Toda semana, morrem aproximadamente 38.000 crianças abaixo dos 5 anos por beber água em péssima condição. Ler mais >>>
  • Guerra pela água: A escassez de água será uma das causas dos conflitos na África. Ler mais >>>

– Países industrializados utilizando água em excesso:

  • Para produzir um hambuger são gastos 24 litros de água.Significa que são gastos 19.9 bilhões de litros de água para produzir apenas um hambuger para cada pessoa na Europa. Ler mais >>>
  • Para cada iPhone na sua bolsa são necessários meio litro de água para carregar. Não parece muito, mas são 80 milhões de iPhone ativos no mundo, o que significa que 40 milhões de litros de água são gastos. Ler mais >>>
  • Cada pessoa nos EUA compram uma média de 200 garrafas de água por ano. Aproximadamente 17 milhões de galões de óleo são usados para fazer as garrafas. Ler mais >>>

– Água e o ambiente:

  • Todo dia, 2 milhões de toneladas de lixo são jogados em fontes de água. Isso não só prejudica o ambiente, mas também ameaça as comunidades próximas. Ler mais >>>
  • Mortes e doenças causadas por poluição das águas costeiras custam mais de 12.8 bilhões de dolares para a econômia global. Ler mais >>>
  • Hoje, 40% dos rios e 46% dos lagos americanos estão tão poluidos que não se pode pescar nem nadar.  Ler mais >>>

– Videos da campanha: http://blogactionday.change.org/fundraise

Não fique de fora dessa luta! Ajude a campanha assinando a petição abaixo:

Share

IST-Rio: Inscrições abertas – Vestibular 2011: 1º semestre

 

http://www.faetec.rj.gov.br/ist-rio
http://www.faetec.rj.gov.br/ist-rio

Estão abertas as inscrições para o vestibular de acesso ao curso de Análise de Sistemas Informatizados do IST-Rio (Instituto Superior de Tecnologia em Ciência da Computação do Rio de Janeiro), para o primeiro semestre de 2011.

São oferecidas 30 vagas para o turno da manhã e 30 vagas para o turno da noite. As inscrições podem ser feitas pelo site da FAETEC, ou pelo link: http://200.150.155.210/faetec_2011.1/ na opção Vestibular Faetec – IST.

O período para inscrições termina dia 10 de novembro de 2010, segundo as informações no site da organizadora do concurso.

De acordo com o INEP/MEC o curso (Análise de Sistemas Informatizados do IST-Rio) é o 2º melhor do Rio de Janeiro e o 8º melhor do Brasil…

Não perca essa oportunidade! Qualquer dúvida ligue para (21) 2332-4048. Boa Sorte a todos os candidatos… 😉

Links Úteis:
Site do instituto: http://www.faetec.rj.gov.br/ist-rio/
Link direto para inscrição no vestibular: http://200.150.155.210/faetec_2011.1/Inscricao/Formulario.asp?opcao=4
Link direto para o edital: http://200.150.155.210/faetec_2011.1/Divulgacao/Edital%20Superior.pdf
Link direto para o anexo de datas: http://200.150.155.210/faetec_2011.1/Divulgacao/Calendario%20Superior.pdf
Link direto para o anexo de vagas: http://200.150.155.210/faetec_2011.1/Divulgacao/Quadro%20Vagas%20Superior.pdf
Link direto para referencia de estudo para a prova: http://200.150.155.210/faetec_2011.1/Divulgacao/Matriz%20Superior.pdf

Abaixo segue umas imagens do instituto:

istrio
Share

Net-sftp: Solução para timeout durante o upload

Desenvolvendo um script em ruby para upload de arquivos, utilizando a gem net-sftp, acabei encontrando um problema. A falta de timeout durante a transferência.

Decidi escrever esse post, para compartilhar a minha solução e também receber opniões e outras soluções para o problema. Fiz algo parecido quando escrevi o post sobre o cron de 15 em 15 segundos e obtive resultados bem legais.

Introdução ao problema
A gem net-sftp é bastante utilizada em scripts ruby que requerem alguma transferência de arquivo utilizando uma conexão segura, como por exemplo, upload, download, criação de diretórios e etc… Utilizando a gem net-ssh para estabelecer essa conexão.

Primeiramente, vamor ver um exemplo do problema:

1
2
3
4
5
require 'rubygems'
require 'net/sftp'
Net::SFTP.start('192.168.0.2', 'rafaelbiriba', {:password => 'teste', :timeout => 3}) do |sftp|
  sftp.upload!("/Users/rafaelbiriba/Projects/temp/video-teste-sftp.mp4", "/home/rafaelbiriba/video-teste-sftp.mp4")
end

O código acima faz o upload de um arquivo de mais de 400 Mb. Se durante o upload houver um problema na sua conexão, o upload fica “esperando” a rede voltar, o que é um problemão, pois ele trava a execução do script, sem dar nenhum sinal de vida.

De acordo com a documentação do net-sftp, você pode utilizar o método “upload” no lugar de “upload!” para não travar a execução do script. Mas ainda sim o problema continua. Fazendo isso, você vai precisar rodar um loop até que o upload termine. Ou seja, se a conexão cair, o método só vai terminar(e sair do loop) quando a conexão voltar. Então essa opção foi logo descartada.

O problema mesmo só acontece quando há perda de conexão depois que a sessão inicia. (O parâmetro :timeout apenas estabelece o limite de espera para iniciar a sessão e não durante a transferência dos arquivos.)

Se o net-sftp / net-ssh aceitasse a opção “ServerAliveInterval” (Parametro de configuração do ssh), ele iria verificar a conexão durante a transferência e ao alcançar o limite (“ServerAliveCountMax”) seria disparado o timeout. Infelizmente, de acordo com a documentação do net-ssh esses parâmetros não estão disponíveis.

Seguindo com a leitura e busca pela solução na documentação do net-sftp, achei uma possível pista para encontrar a solução:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
require 'rubygems'
require 'net/sftp'
Net::SFTP.start('192.168.0.2', 'rafaelbiriba', {:password => 'teste', :timeout => 3}) do |sftp|
  sftp.upload!("/Users/rafaelbiriba/Projects/temp/video-teste-sftp.mp4", "/home/rafaelbiriba/video-teste-sftp.mp4") do |event, uploader, *args|
    case event
    when :open then
      # args[0] : file metadata
      puts "starting upload: #{args[0].local} -> #{args[0].remote} (#{args[0].size} bytes}"
    when :put then
      # args[0] : file metadata
      # args[1] : byte offset in remote file
      # args[2] : data being written (as string)
      puts "writing #{args[2].length} bytes to #{args[0].remote} starting at #{args[1]}"
    when :finish then
      puts "all done!"
    end
  end
end

Acima temos um exemplo simples retirado da documentação para o controle do progresso de upload.

Quando o upload inicia, o case recebe o evento “:open” onde podemos obter o tamanho total do arquivo e logo em seguida recebe os eventos “:put” onde é possível verificar  o quanto (em bytes) do arquivo já foi enviado, possibilitando assim a criação da porcentagem do upload.

Como o foco aqui não é mostrar como obter o progresso (posso mostrar isso exclusivamente em outro post calculando o progresso durante o upload), não vou entrar muito em detalhes sobre isso. O que realmente inporta nesses eventos são que durante o upload (:put), ao perder a conexão, nenhum evento é disparado, ou seja, o script não tem como sabe que a conexão caiu e a execução fica travada no upload.

Minha solução:

Depois de todo esse estudo detalhado sobre o problema, comecei a pensar numa possível solução. Eu precisava utilizar alguma coisa que pudesse verificar e dar timeout no upload caso ele parasse de responder/transferir.

Foi então que pesquisei, testei e implementei o rufus-scheduler*,  um agendador de tarefas que roda dentro do script ruby(mas numa outra thread), onde posso definir um intervalo de execução para executar alguma coisa, como se fosse um cron. ( *Sugestão do @vicentemundim )

Então a solução foi: Assim que o upload começar, eu defino um tempo de 10 segundos para ele executar uma tarefa com “raise exception”. Então toda vez que o upload responder ao evento (:put), informando que conseguiu subir mais um trecho do arquivo, eu reseto o tempo de execução da tarefa e defino novamente em 10 segundos. Fazendo isso, quando a conexão cair ou o upload travar por algum motivo, ele vai parar de responder ao evento “:put”, e então a tarefa agendada para 10 segundos vai disparar o raise, interrompendo a execução do script.

Depois de alguns testes, tanto de desempenho quanto de falhas, percebi que essa resolução serviu perfeitamente. Segue o exemplo do código utilizado:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
require 'rubygems'
require 'rufus/scheduler'
require 'net/sftp'
 
@job = nil
@scheduler = Rufus::Scheduler::PlainScheduler.start_new  
def @scheduler.handle_exception (job, exception)
  abort(exception.message)
end
 
def job_scheduler
  @job.unschedule unless @job.nil?
  @job = @scheduler.every "10s" do
    raise "SFTP Connection Lost or upload freezed timeout"
  end    
end
 
Net::SFTP.start('192.168.0.2', 'rafaelbiriba', {:password => 'teste', :timeout => 3}) do |sftp|
  sftp.upload!("/Users/rafaelbiriba/Projects/temp/video-teste-sftp.mp4", "/home/rafaelbiriba/video-teste-sftp.mp4") do |event, uploader, *args|
    case event
    when :open then
      puts "starting upload: #{args[0].local} -> #{args[0].remote} (#{args[0].size} bytes}"
      job_scheduler
    when :put then
      puts "writing #{args[2].length} bytes to #{args[0].remote} starting at #{args[1]}"
      job_scheduler
    when :finish then
      puts "all done!"
     @job.unschedule unless @job.nil? 
    end
  end
end

Quando o upload inicia (:open) e durante a transferência (:put), ele chama o método job_scheduler que é responsável por resetar a tarefa anterior(se houver) e agendar uma nova com timeout de 10 segundos.

Conforme expliquei acima, se o upload travar, o tempo limite de 10 segundos é alcançado e uma exceção é disparada.

Como o agendador do rufus roda em outra thread, qualquer exceção disparada é capturada e tratada pelo próprio rufus, fazendo com que a execução do script continue. Então, sobrescrevi o método (handle_exception) e ao receber a exceção, gero um abort que irá interromper todo o script.

Infelizmente, são poucos os sites relacionados sobre esse assunto, o que dificultou bastante a busca e o desenvolvimento. Mesmo assim, acredito ter resolvido o problema com uma solução bem razoável.

Já falei em cima, mas vale ressaltar:
“Decidi escrever esse post, para compartilhar a minha solução e também receber opniões e outras soluções para o problema. Fiz algo parecido quando escrevi o post sobre o cron de 15 em 15 segundos e obtive resultados bem legais.”

Estou pensando em tentar solucionar isso direto no código do net-sftp e quem sabe mandar um patch para o autor. De qualquer forma, fico no aguardo de qualquer comentário e/ou soluções melhores.

handle_exception
Share

FFmpeg: Convertendo um video em um gif animado

FFmpeg: http://www.ffmpeg.org/

Há alguns dias atrás, me perguntaram se tinha como converter trechos de vídeos para um arquivo .gif, para ser usado em lugares que só aceitam imagens, como foruns, msn e etc…

Abaixo segue um exemplo simples que faz isso, usando FFmpeg:

ffmpeg -i teste.avi -pix_fmt rgb24 -f gif teste.gif

Detalhes:

  • -i = especifica o arquivo de entrada (teste.avi)
  • -pix_fmt = especifica o formato dos pixels (rgb24, formato suportado pelo gif  )
  • -f = força a saida para .gif
  • teste.gif é o arquivo de saída do comando

Se você precisa de uma solução mais específica, abaixo segue alguns outros comandos e as explicações dos parâmetros:

GIF com tamanho final específico e com loop:

ffmpeg -i teste.avi -pix_fmt rgb24 -r 10.0 -loop_output 0 -f gif -s 120x120 teste.gif

Detalhes:

  • -r = especifica o frame rate do gif
  • -loop_output = especifica quantas vezes o gif vai entrar em loop (zero para infinito)
  • -s = especifica o tamanho do gif em pixels

GIF com inicio definido pelo tempo e final limitado por frames:

ffmpeg -i widescreen.avi -pix_fmt rgb24 -r 10.0 -loop_output 0 -vframes 100 -ss 00:00:02 -f gif teste.gif

Detalhes:

  • -ss = especifica a posição inicial do video para gravação (formato: hh:mm:ss)
  • -vframes = limita a quantidade de frames que serão gravados a partir do video original
  • No exemplo, o gif será formado apenas pelos 100 primeiros frames depois da posição 2 segundos

GIF com inicio definido pelo tempo e final limitado pelo tempo:

ffmpeg -i widescreen.avi -pix_fmt rgb24 -r 10.0 -loop_output 0 -ss 00:00:02 -t 00:00:04 -f gif teste.gif

Detalhes:

  • -ss = especifica a posição inicial do video para gravação (formato: hh:mm:ss)
  • -t = especifica a posição final de gravação do video (formato: hh:mm:ss)
  • No exemplo, o gif será criado a partir do segundo 2 até o segundo 4 do vídeo.

Você também pode experimente a combinação dos parâmetros, até encontrar o comando que lhe sirva melhor… 😉

Share