Regalando cosas por Bluetooth

Posted: August 12th, 2009 | Author: FreedomCoder | Filed under: Open Source, Programming, linux | Tags: , , , | No Comments »

El año pasado Movistar había lanzado una campaña muy pedorra en el subte, en donde unos carteles en el piso te invitaban a prender tu Bluetooth y te enviaban un file. Lo que te enviaban era una simple imagen, con tanto texto que en mi celular era casi ilegible y no tenía consigna alguna.

Sin embargo esto sirvió para que me encaprichara y quisiera armar algo similar para la oficina, orientado a que un cliente que viene a una reunión se pueda llevar un regalo, que en este caso es un juego J2ME.

Hacerlo realmente es una boludez. El real problema, que no voy a tratar acá, es tener una placa Bluetooth soportada por Linux (creo que esta solución aplica Windows, pero no lo probé), lo que puede resultar complicado. Yo en mi anterior laptop fallé en cada intento. Hoy en día en mi MacBook anda todo out-of-the-box por suerte así que pude jugar un poco.

El protocolo que se utiliza para intercambiar cosas es Object Exchange (OBEX) y tenemos una excelente biblioteca llamada OpenObex. A nosotros nos interesa particularmente ObexFTP que nos da el File Transfer sobre Obex.

El primer problema que tuve es que en Jaunty no está el binding de ruby, por lo que me tuve que bajar el source y diff de Karmic y crear mis libobexftp-ruby_0.22-1_i386.deb y sus dependencias.

Salvando eso, con los ejemplos del wiki sale muy fácil. La biblioteca nos permite descubrir devices, abrir channels y enviar archivos en pocas líneas. Acá un en ruby ejemplo :

#!/usr/bin/env ruby
 
require 'obexftp'
 
puts "Scanning BT..."
intfs = Obexftp.discover(Obexftp::BLUETOOTH)
dev = intfs.first # Es un array, podríamos iterar sobre todas las encontradas
 
channel = Obexftp.browsebt(dev, Obexftp::PUSH)
 
cli = Obexftp::Client.new(Obexftp::BLUETOOTH)
puts cli.connectpush(dev, channel)
puts cli.put_file('ver.jpg')
puts cli.disconnect

Hacer lo mismo en Python, Perl o cualqueir otro lenguaje soportado es igual de simple.

Obviamente es muy minimalista: agarra el primer device encontrado, abre un channel para hacer un PUSH (si el device no soporta PUSH retorna -1 según creo), luego abre la conexión y le envía el archivo.

Desde el celular vemos un mensaje de que se está abriendo una conexión y luego el detalle de lo que se quiere enviar, nombre del archivo, tipo de archivo, tamaño, etc. Podemos aceptarlo o rechazarlo. De aceptarlo se descarga pero no se guarda ni se instala, es un paso extra que debemos decidir si lo hacemos o no.

Un problema que encontramos para enviar juegos es que algunos celulares están bloqueados para esa función (para así vendértelos por el portal WAP oficial de tu carrier). Ya lo pudimos probar con varios celulares Nokia, Motorola y Samsung y funciona razonablemente bien.

Sobre este ejemplo nosotros tenés un poco más de trabajo, ya que guardamos los device ID y el contenido enviado, así cuando volvés te damos un contenido diferente :) . Si además no podés recibir el juego, te pasamos una imágen simpática :P .

(Via El Futirifoken.) Original Link: Regalando cosas por Bluetooth


SQLite3/Ruby 1.2.5 Released!

Posted: July 25th, 2009 | Author: FreedomCoder | Filed under: Open Source, Programming, SQL | Tags: , , | No Comments »

I just released an updated version of SQLite3/Ruby, officially to RubyForge!

Read the news here

This release includes binaries for Windows, but not any kind of binary, but fat ones!

That means that using either 1.8 or 1.9 versions of Ruby you will be able to access SQLite3/Ruby bindings and script your craziest applications!

This also solves the major PITA for gem update that lot of user experienced in the past.

Don’t forget to read a getting started guide here

Now is time to hunt down MySQL gem author and politely ask him integrate my patches ;)

(Via DEV_MEM.dump_to(:blog) – Multimedia systems blog.) Original Link: SQLite3/Ruby 1.2.5 Released!


rails twitter search using search.atom

Posted: July 23rd, 2009 | Author: FreedomCoder | Filed under: Open Source, Programming | Tags: , , , | No Comments »

Recently, I had to create a twitter live feed for a work I’m doing…. so I found the gems for searching in twitter, but all of them were working with the search.json api, but since my client wanted the same results that he saw in twitter.search.com, I created a lib for that project (following the gem example code), in order to use the search.atom api and parse the xml results with hpricot.

If you deal with the same problem, here you have the code

require ‘rubygems’
require ‘net/http’
require ‘cgi’

class Twitter
TWITTER_SEARCH_API_URL = ‘http://search.twitter.com/search.atom’
DEFAULT_TIMEOUT = 5
HEADERS = { “Content-Type” => ‘application/rss+xml’,
“User-Agent” => ‘twitter-search’ }

def self.search(opts)
search_for = ‘#twitter’

url = URI.parse(TWITTER_SEARCH_API_URL)
url.query = sanitize_query(opts)

ensure_no_location_operators(url.query)

req = Net::HTTP::Get.new(url.path)
http = Net::HTTP.new(url.host, url.port)
http.read_timeout = DEFAULT_TIMEOUT

res = http.start { |h| h.get(”#{url.path}?#{url.query}”, HEADERS) }

if res.code == ‘404′
raise “Twitter responded with a 404 for your query”
end

self.parse_search(res.body)
end

def self.sanitize_query(opts)
if opts.is_a? String
“q=#{CGI.escape(opts)}”
elsif opts.is_a? Hash
“#{sanitize_query_hash(opts)}”
else
raise “sanitique_query expects a String or a Hash”
end
end

def self.sanitize_query_hash(query_hash)
query_hash.collect{|key, value| “#{CGI.escape(key.to_s)}=#{CGI.escape(value.to_s)}” }.join(’&’)
end

def self.ensure_no_location_operators(query_string)
if query_string.include?(”near%3A”) ||
query_string.include?(”within%3A”)
raise “near: and within: are available from the Twitter Search web interface, but not the API. The API requires the geocode parameter. See dancroak/twitter-search README.”
end
end

def self.parse_search(body)
doc = Hpricot.parse(body)

entries = []

items = (doc/:entry)
items.each do |raw_item|
entry = {}

entry

(Via Rorra’s blog.) Original Link: rails twitter search using search.atom


rake sh en otro directorio

Posted: July 17th, 2009 | Author: FreedomCoder | Filed under: Open Source, Programming, how-to, rake | Tags: , , , | No Comments »

Problema: Quiero ejecutar un comando desde otro directorio en rake (por ejemplo, ejecutar un makefile que está en un subdirectorio).
Solución: Agrego al rakefile la posibilidad de ejecutar comandos en otro directorio. Para eso, al principio de mi rakefile puse:


require 'fileutils'

def sh_in_dir( dirname, *args, &block )
  old_path = pwd
  FileUtils.chdir( dirname )
  sh( *args, &block )
  FileUtils.chdir( old_path )
end

Happy hacking,

Aureliano.

(Via aurelianito.) Original Link: rake sh en otro directorio


Sitemaps vía crawling

Posted: July 15th, 2009 | Author: FreedomCoder | Filed under: Open Source, Programming | Tags: , , | No Comments »

Hoy me pidieron agregar un Sitemap para uno de los trabajos que hicimos para el gobierno y me encontré con que los plugins que uso para esta tarea no me cerraban de forma cómoda. El problema es que este sitio tiene, además del contenido dinámico, muchas páginas estáticas que no puedo referenciar desde un modelo, por lo que debía forzarlas y era bastante molesto.

Buscando encontré una solución práctica para este caso (donde hay pocas páginas, menos de 1k) que usa un crawler para recorrer todo el sitio y obtener las URLs a agregar al sitemap. El script que presentan me sirvió, aunque tuve que hacerle algunos cambios menores.

El primer problema que tenía era que me agregaba páginas que no deben ir en un sitemap (ni ser indexadas) como las de login, recuperar clave, form de registración, etc. Por lo que tuve que modificar ligeramente el código para no seguir los enlaces que estuvieran marcados con rel="nofollow" y para eso modifiqué en el método extract_and_call_urls la última línea como sigue :

links.each{ |link|
   extract_and_call_urls(link.href) unless
      !can_follow?(link) || ignore_url?(link.href) ||
      @visited_pages.include?(link.href)
}

Y definiendo el nuevo método :

 def can_follow?(link)
   return false if link.nil? ||
   (link.attributes["rel"] && link.attributes["rel"].include?("nofollow"))
 
   true
 end

Entonces, cuando el crawler encuentra un enlace que el developer marcó que no debe seguirse en una indexación (esto es principalmente para los crawlers de los search engines) se ignora y no se agrega al sitemap.

El otro cambio menor fue que tenía algunas URLs con el path completo y por default siempre me agregaba al inicio el domain name, por lo que me quedaban URLs inválidas, por lo que hice la siguiente modificación :

# Antes
xml.loc(@starting_url + url)
 
# Después
xml.loc(url.include?(@starting_url) ? url : (@starting_url + url))

Una vez probado el script hice una tarea rake para poder correrla fácil desde un cronjob :

# lib/tasks/sitemap.rake
require 'lib/crawler'
 
desc "Generate the sitemap file"
task :sitemap => :environment do
  start_url = ENV["URL"] || "http://localhost:3000"
  Crawler.new(start_url, (ENV["CREDS"] if ENV["CREDS"]), ENV["QUIET"] || false, ENV["SITEMAP"] || false, ENV["DEBUG"] || false)
end

Y listo, lo último fue hacer un deploy y configurar un cron.dayli para que cree el sitemap actualizado :

rake sitemap URL=http://www.haciendoelcolon.buenosaires.gob.ar SITEMAP=true

Así una vez por día se actualiza el sitemap y se hace un ping a google para que sepa que debe pasar a reindexar el contenido.

Esto tiene varias desventajas (pero aún así para este sitio sirve a su propópito) :

  • No se puede priorizar cada tipo de contenido fácilmente
  • La fecha de última modificación es inexacta
  • Carga el webserver para generar el sitemap

Código completo : crawler.rb

(Via El Futirifoken.) Original Link: Sitemaps vía crawling


First stable beta of ESearchy is out!

Posted: July 14th, 2009 | Author: FreedomCoder | Filed under: Open Source, Programming, Security | Tags: , , , | No Comments »

Finally, after weeks of work, the first stable Beta of ESearchy is up and running in github’s gem repository.
Esearchy is a small library capable of searching the internet for email addresses. Currently, the supported search methods are engines such as Google, Bing, Yahoo, PGP servers, GoogleGroups, Linkedin, etc , but I intend to add many more.

Also, the library searches inside .pdf, .docx, .xlsx, .pptx, asn and .txt files for emails addresses and adds them to the list of found accounts. Finally, we have support for .docs files but for now only in Windows Platforms. (For more information visit: Github .

In order to install it you simple add the repository and then install the gem, as shown below.

  1. >  gem sources -a http://gems.github.com
  2. >  gem install FreedomCoder-esearchy

Once the gem is installed, you can create a new search opening and/or use the “esearchy” CLI tool but it’s really basic so far and it does not has all of the plugins.

  1. require ‘esearchy’
  2.  
  3. ESearchy::LOG.level = ESearchy::APP #Output to the stdout.
  4.  
  5. ESearchy.create "domain.com" do |d|
  6.   d.yahoo_key = "yourAPIkeygoeshere"
  7.   d.bing_key = "yourAPIkeygoeshere"
  8.   # if you want to also look in LinkedIn
  9.   d.company_name "Company Name"
  10.   #A user is needed in order to search within Linkedin
  11.   d.linkedin_credentials "myuser@linkedin.com", "mypwd"
  12.   d.maxhits = 50
  13.   d.search
  14.   d.save_to_file "company_emails.txt"
  15. end

If you have any comments, issues or want to submit a bug please do so on
http://github.com/FreedomCoder/esearchy/issues

Hopefully it will be useful to you.
:)

(Via 自由編碼人.) Original Link: First stable beta of ESearchy is out!


Random User Agents

Posted: July 13th, 2009 | Author: FreedomCoder | Filed under: Open Source, Programming | Tags: , , | No Comments »

While programming Esearchy I had to create a simple class to retrieve random user agents. You may say but why you would want something like this, and the answer is simple:
“Try to trick the search engines, so they would not block me”.

Yeah, I know this might not even works, but it’s still cool. =D

Well here it goes

Use it at your own discretion and listen to your ghost …

(Via 自由編碼人.) Original Link: Random User Agents


Rails edge, Ruby 1.9 style String interpolation support

Posted: July 13th, 2009 | Author: FreedomCoder | Filed under: Open Source, Programming, Rails | Tags: , , | No Comments »

Este es el primer post de una serie que he decidido comenzar titulada “Analizando commits de rails edge”. Aclaro que los post no van a tener orden alguno y que voy a comentar los que me llaman la atención a _mí_ :) .
En este caso el commit se trata de agregar a rails la nueva forma de interpolación de strings que trae ruby 1.9 ( la idea es que se pueda usar con versiones menores también), pueden ver el código en este archivo:

activesupport/lib/active_support/core_ext/string/interpolation.rb

Cómo uds sabrán en Ruby se pueden interpolar strings de la siguiente manera:

>>"%s, %s" % ["Masao", "Mutoh"]
=> "Masao, Mutoh"

Cómo lo explica el comentario en el código:

 # call-seq:
  #   %(arg)
  #   %(hash)
  #
  # Format - Uses str as a format specification, and returns the result of applying it to arg.
  # If the format specification contains more than one substitution, then arg must be
  # an Array containing the values to be substituted. See Kernel::sprintf for details of the
  # format string. This is the default behavior of the String class.
  #   * arg: an Array or other class except Hash.
  #   * Returns: formatted String
  # Example:
  #    "%s, %s" % ["Masao", "Mutoh"]
  #
  # Also you can use a Hash as the "named argument". This is recommended way so translators
  # can understand the meanings of the msgids easily.
  #   * hash: {:key1 => value1, :key2 => value2, ... }
  #   * Returns: formatted String
  # Example:
  #   For strings.
  #   "%{firstname}, %{familyname}" % {:firstname => "Masao", :familyname => "Mutoh"}
  #
  #   With field type to specify format such as d(decimal), f(float),...
  #   "%d, %.1f" % {:age => 10, :weight => 43.4}

Es decir que ahora podemos interpolar strings de la siguiente manera:

>> "%{firstname}, %{familyname}" % {:firstname => "Masao", :familyname => "Mutoh"}
ArgumentError: malformed format string - %{
	from (irb):2:in `%'
	from (irb):2
>>

Auuuchh! estoy probando con un irb con ruby 1.8.6, así que necesito requerir el archivo:

>> require 'activesupport/lib/active_support/core_ext/string/interpolation.rb'
=> true
>> "%{firstname}, %{familyname}" % {:firstname => "Masao", :familyname => "Mutoh"}
=> "Masao, Mutoh"

Ahora sí! podemos interpolar string nombrados pasando un hash como argumento, Hermoso!
Estuve mirando en los fuentes de Ruby 1.9 y no encuentro dónde está escrita esta nueva funcionalidad, el método que define la interpolación con”%” es rb_str_format_m y está en la línea número 1202 del archivo string.c en el trunk de ruby, pero sólo está la vieja forma de interpolación. Entonces dónde está ? Alguien sabe?
Es más hice esta prueba:

$ irb1.9
require 'activesupport/lib/active_support/string/interpolation.rb'
=> true
irb(main):002:0> "%{firstname}, %{familyname}" % {:firstname => "Masao", :familyname => "Mutoh"}
ArgumentError: malformed format string - %{
	from (irb):2:in `%'
	from (irb):2
	from /usr/bin/irb1.9:12:in `'

Y la versión que tengo de ruby 1.9 es:
ruby 1.9.0 (2008-06-20 revision 17482) [i486-linux]
Un poco vieja, probemos con ruby 1.9 compilado desde trunk
ruby 1.9.2dev (2009-07-11 trunk 24027) [i686-linux]

./ruby  -e 'puts "%{firstname}, %{familyname}" % {:firstname => "Masao", :familyname => "Mutoh"}'
Masao, Mutoh

Funcionó! entonces en algún lugar tiene que estar.

(Via Gastón Ramos – Ruby, Rails….) Original Link: Rails edge, Ruby 1.9 style String interpolation support


Stepping up as SQLite3/Ruby maintainer

Posted: July 13th, 2009 | Author: FreedomCoder | Filed under: Open Source, Programming, SQL | Tags: , , | No Comments »

So, I think this may be good news for some folks.

February 24, 2009 is the date that Jamis Buck marked as the end of several of his open source projects, including SQLite3/Ruby. (you can read the post here)

Previously, he asked for help updating SQLite3/Ruby to make it work on Windows.

That sad news left a lot of us with a bad taste, and very unhappy, not because we no longer will have someone to complain at, but because he no longer enjoyed working on those projects.

Over the past months I’ve been improving rake-compiler to be able to catch most of the building issues of several projects, including my own (I love to scratch my own itch).

As you have noticed on my “getting started with Rails and SQLite3″: http://blog.mmediasys.com/2009/07/06/getting-started-with-rails-and-sqlite3/ post, I successfully built, installed and used a SQLite3/Ruby gem on Windows.

The next question was, what to do? The work to get all those lovely gems was there, initial 1.9 was there, but was not official

While SQLite3/Ruby being the de-facto for getting started with Rails, we couldn’t let it die.

Enough words, sent some emails to Jamis and now I can publish those gems to RubyForge.

What all that babbling means?

This means:

  • My fork at GitHub is the new mainstream for the releases
  • I’m going to go over the open bugs and tickets and asses validity and relevancy based on work that was already done in my fork.
  • The release cycle has been improved and almost automated. It can be performed from Windows, Linux or OSX, even using latter to create Windows native gems.

Now, what happens with new features:

  • Pull requests with patches and bug fixes are going to be accepted.
  • New features will be evaluated as long they don’t impose structural changes and carry with them tests cases.
  • Patches that improve Ruby 1.9 compatibility are highly appreciated.

I don’t have strong knowledge of all the internals of this tool, so don’t expect earth breaking changes from me, except ensuring stability.

I hope this is good news to everybody. Now I’m going to stalk MySQL binding author and get permission to push those lovely gems ;-)

Cheers everybody!

(Via DEV_MEM.dump_to(:blog) – Multimedia systems blog.) Original Link: Stepping up as SQLite3/Ruby maintainer


Rails 2.3, rake y reenable method

Posted: July 13th, 2009 | Author: FreedomCoder | Filed under: Open Source, Programming, Rails | Tags: , , , , | No Comments »

Estoy terminando de hacer una migration a Rails 2.3 de la
app con la que estoy trabajando, resulta que me encontré con el siguiente tema:
Luego de instalar rails y migrar la app, llegó el momento de hacer un deploy a
staging, entonces me econtré con el siguiente error:

undefined method `reenable' for <Rake::Task db:schema:dump =>
[environment]>:Rake::Task

googleando un poco llegué a este link que dice que hay que instalar
la nueva versión de rake, investigando un poco más, llegué a este PATCH
que hace uso del método Rake::Task#reenable, el caso es que este método
se agrega e con la versión de rake 0.8.2 y como el pibe dice en el comentario
del patch, no hay problemas por que rails 2.3 require rake 0.8.3…. pero
que pasa cuando:

1- Instalo rails 2.3
2- Hago un ‘rake rails:freeze’
3- hago ‘cap staging deploy:migrations’

Y no tengo rails 2.3 instalado en el server y por eso justamente hice un freeze.

Si leemos la task que arma las dependencias de rails:

  s.add_dependency('rake', '>= 0.8.3')
  s.add_dependency('activesupport',    '= 3.0.pre' + PKG_BUILD)
  s.add_dependency('activerecord',     '= 3.0.pre' + PKG_BUILD)
  s.add_dependency('actionpack',       '= 3.0.pre' + PKG_BUILD)
  s.add_dependency('actionmailer',     '= 3.0.pre' + PKG_BUILD)
  s.add_dependency('activeresource',   '= 3.0.pre' + PKG_BUILD)

uando hacemos el freeze nos copia todas estas cosas menos el rake,
lo cual parece razonable. Pero creo debería agregar en config/environment.rb

config.gem “rake”, :version => ‘0.8.3′

Que opinan uds?

(Via Gastón Ramos – Ruby, Rails….) Original Link: Rails 2.3, rake y reenable method