Barcode4J en JRuby y Rails
Agosto 13th, 2010
En el post anterior había explicado el uso de Gbarcode, una librería para generación de códigos de barras con Ruby. El problema es que esta librería no se puede utilizar en Jruby ya que tiene extensiones nativas en C, cosa que Jruby aún no soporta.
Después de investigar alternativas de generación de codigos de barras para java como Zxing y Barbecue. Me quedé con Barcode4j por facilidad de implementación, documentación (la cual es muy completa) y sobre todo estabilidad.
A continuación paso a comentarles como utilizar esta librería en JRuby.
1) Lo primero es descargarse en paquete binario del sitio o bien de este enlace directo.
2) Al descomprimir el Zip, copiamos el contenido del directorio Build al directorio /lib de nuestra instalación de JRuby
3) Ahora vamos al código:
require 'java'
#Importamos algunas librerías que vamos a utilizar
import 'java.awt.image.BufferedImage'
import 'java.io.OutputStream'
import 'java.io.FileOutputStream'
#Importamos las librerías de los códigos de barras (Barcode4j) que necesitamos
import 'org.krysalis.barcode4j.impl.code39.Code39Bean'
import 'org.krysalis.barcode4j.impl.code128.Code128Bean'
import 'org.krysalis.barcode4j.impl.int2of5.Interleaved2Of5Bean'
import 'org.krysalis.barcode4j.impl.codabar.CodabarBean'
import 'org.krysalis.barcode4j.impl.code128.EAN128Bean'
import 'org.krysalis.barcode4j.impl.pdf417.PDF417Bean'
import 'org.krysalis.barcode4j.impl.upcean.EAN13Bean'
import 'org.krysalis.barcode4j.impl.upcean.EAN8Bean'
import 'org.krysalis.barcode4j.impl.upcean.UPCABean'
import 'org.krysalis.barcode4j.impl.datamatrix.DataMatrixBean'
import 'org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider'
import 'org.krysalis.barcode4j.tools.UnitConv'
#Creamos el Bean y establecemos los dpi y wide_factor
bean = Interleaved2Of5Bean.new()
dpi = 150
bean.wide_factor = 3
#Creamos la imagen
ofile = java.io.File.new('/home/laptop/barcodes/barcode.png')
out = FileOutputStream.new(ofile)
canvas = BitmapCanvasProvider.new(out,"image/x-png", dpi, BufferedImage::TYPE_BYTE_BINARY, false, 0)
#Generamos el código de barras
#El segundo parámetro que pasamos es el número del que deseamos generar el codigo de barras
bean.generate_barcode(canvas, '1234567890');
canvas.finish
out.close
Con esto, generamos una imagen con nuestro codigo de barras en /home/laptop/barcodes/barcode.png la cual se puede incluir en cualquier pdf/html/odf, etc.
Espero les sea útil. Cualquier duda, no duden en comentar.
Hay veces que el usuario necesita subir archivos, pero de una manera “masiva”, no guardando de a uno. Un claro ejemplo de esto es GoogleDocs,
que te deja subir varios documentos a la vez, antes de empezar a verlos.
Utilizando un plugin de jquery, en rails esto se hace de una manera muy transparente.
El plugin en cuestión se llama MultiFileUpload, en su página encontraremos una buena documentación de como usarlo correctamente
Lo que nos interesa es como implementarlo en rails y que todos estos archivos que seleccionamos se almacenen en nuestra base de datos.
Para comenzar tenemos que incluir las librerias del plugin en el aplication.html.erb
<% javascript_include_tag :default, 'multiple-file-upload/jquery.MultiFile.js', 'multiple-file-upload/jquery.MetaData.js' %>
En nuestra vista creamos el formulario, para subir los archivos
<% form_for(:archivo_digital, :html => {:multipart => true },:url => create_archivo_digital_path) do |f| %> <ul id="form"> <%= file_field_tag :files, :class => 'multi file', :name => 'pdf_files[]'%> <li> <%= f.submit 'Subir' %> <%= f.submit 'Cancelar' %> </li> </ul> <% end %>
Expliquemos un poco el código:
En necesario establecer :multipart => true, para que el formulario admita la carga de archivos.
file_field_tag nos crea el tag para poder abrir el cuadro de diálogo de carga de archivos de un navegador:
:class => ‘multi file’, esta clase es la que utiliza MultiFileUpload para hacer la magia de subir varios archivos
:name => ‘pdf_files[]‘ esto es muy necesario, porque el plugin crea un arreglo con todos los archivos, pero para que ruby sepa
que nos referimos a un arreglo tenemos que poner [].
Por último tenemos dos botones, el de Subir, que va a subir todos los archivos de una sola vez y el de Cancelar, que hará lo propio.
En nuestro controller vamos a tener
#Renderiza el formulario para subir los archivos def new @archivo_digital = ArchivoDigital.new respond_to do |format| format.html end end def create respond_to do |format| if params[:commit] == "Subir" unless params[:pdf_files].blank? params[:pdf_files].each do |archivo| params[:archivo_digital][:nombre_archivo] = archivo params[:archivo_digital][:archivo] = archivo.read @archivo_digital = ArchivoDigital.new(params[:archivo_digital]) if @archivo_digital.save flash[:notice] = 'Archivo agregado' end end format.html{redirect_to archivos_digitales_path} else flash[:error] = 'Debe seleccionar al menos un archivo' end else format.html{redirect_to archivos_digitales_path} end end end
Expliquemos un poco el código:
Sobre el primer método no hay mucho que decir, solo nos renderiza el formulario que creamos en el paso anterior
El método create es el que hace todo, para empezar tenemos una condición donde pregunta si params[:commit] == “Subir”
esto es para que diferencie entre el botón subir y el cancelar. Cuando presionamos un botón, rails inmediatamente manda un parámetro, llamado
commit con el nombre del botón. Con está condición lo que hacemos es darle tareas diferentes a cada botón.
Si no se cumple la condición, es porque se presionó el botón “Cancelar” y nos redirigirá al listado de archivos.
En caso de que la condición se cumpla, tenemos otro condicional: unless params[:pdf_files].blank?, esto es para saber si se seleccionó algun archivo_digital
y caso contrario muestra un flash[:error]. Si se cumple la condición, recorremos el arreglo y vamos guardando en nuestra base de datos el nombre del
archivo y el archivo en sí.
Bueno, esto es una manera sencilla de subir archivos de forma “masiva” con Jquery y Rails, cualquier cosa no duden en preguntar
JasperReports con Jruby y Rails
Julio 29th, 2010
Uno de los grandes problemas en el desarrollo con Ruby on Rails son los reportes multipágina. Debido a que el HTML (inclusive HTML 5) no soporta multipágina, si utilizamos Jruby tenemos la posibilidad de usar cualquier librería Java en nuestro desarrollo.
Afortunadamente en Java tenemos JasperReports (http://jasperforge.org/), una excelente solución al problema antes mencionado.
Para poder incluir un reporte realizado con JasperReports en nuestra aplicación Jruby necesitamos:
1) Descargar I-Report, la herramienta de administracion de reportes de JasperReports. http://jasperforge.org/projects/ireport y descomprimirlo.
2) Dentro del directorio del i-report, ir a modules/ext/ y copiar todos los archivos .jar (si, todos
) al directorio lib de la instalación de JRuby. De esta manera, ya incluimos las librerías necesarias y tenemos preparado nuestro JRuby para utilizar JasperReports.
3) Nos resta crear un reporte para prueba, si nunca hiciste un reporte con i-report: http://jasperforge.org//website/ireportwebsite/IR%20Website/ir_design_a_report.html?header=project&target=ireport
4) Finalmente el código para correr nuestro reporte es el siguiente:
require 'java'
import 'oracle.jdbc.OracleDriver' #Aqui necesitas Utilizar el Driver de la Base de datos que estas usando, en mi caso es oracle
import 'net.sf.jasperreports.engine.JasperCompileManager'
import 'org.apache.commons.dbcp.BasicDataSource'
import'java.util.HashMap'
import'net.sf.jasperreports.engine.JasperFillManager'
import'net.sf.jasperreports.engine.JasperExportManager'
#Creo el datasource
basicdatasource = BasicDataSource.new
basicdatasource.driver_class_name = 'oracle.jdbc.OracleDriver'
basicdatasource.username = 'usuario'
basicdatasource.password = 'password'
basicdatasource.url = 'jdbc:oracle:thin:@localhost:1521:XE'
basicdatasource.connection
conexion = basicdatasource.connection
#Compilamos el reporte
jasperReport = JasperCompileManager.compile_report('/url_de_tu_archivo_jrxml/reporte.jrxml')
#Para pasar los parámetros, definimos un objeto HashMap
m = HashMap.new
m.put('parametro_1','valor_parametro_1')
m.put('parametro_2','valor_parametro_2')
m.put('parametro_n','valor_parametro_n')
#Genero el reporte
jasperPrint = JasperFillManager.fill_report(jasperReport, m,conexion)
#Exporto el PDF
JasperExportManager.export_report_to_pdf_file(jasperprint, 'path_al_archivo_PDF.pdf')
Si deseamos generar reportes en Rails, podemos por ejemplo ubicar los reportes en el directorio public/reportes y utilizar send_file para enviarlos, por ejemplo:
JasperExportManager.export_report_to_pdf_file(jasperprint, RAILS_ROOT+"/public/reportes/reporte.pdf") send_file RAILS_ROOT+"/public/reportes/reporte.pdf"
Espero les sea de utilidad, cualquier cosa comenten y trataré de despejar dudas
Gbarcode. Codigos de barra con Ruby
Marzo 16th, 2010
Gbarcode es una librería de generación de códigos de barra para Ruby. Es una extensión de C que envuelve el proyecto GNU Barcode. Se distribuye en formato GEM
Link: http://gbarcode.rubyforge.org/
Ejemplo de uso:
require 'rubygems'
require 'gbarcode'
# Incluir el módulo
include Gbarcode
# Existen tres pasos para generar un codigo de barras
# 1) preparar el espacio para el string
# 2) codificar el string como un codigo de barras
# 3) imprimir el codigo de barras
# preparar el codigo de barras para el string "TEST1234"
bc = barcode_create("TEST1234")
# codificar el codigo de barras usando code 39,
# desde que code 39 no usa dígito de verificacion (checksum),
# lo podemos pasar en un flag
barcode_encode(bc, BARCODE_NO_CHECKSUM | BARCODE_39)
#imprimir el codigo de barras usando postcript
barcode_print(bc, File.new("testout.ps", "w"), BARCODE_OUT_PS)
# ó
barcode_print(bc, File.new("testout.eps", "w"), BARCODE_OUT_EPS)
Whenever: una manera sencilla de administrar tareas en Cron con Ruby
Marzo 15th, 2010
Si bien hace bastante tiempo que soy usuario de GNU/Linux, no suelo crear tareas en cron con frecuencia por lo que necesito investigar su poderosa sintáxis cada vez que debo crear trabajos que deben ejecutarse a intervalos regulares.
Hace poco por casualidad me topé con Whenever, una gema de Ruby que nos permite crear tareas en cron de manera muy sencilla. A través de un DSL nos abstrae de la complejidad de la sintáxis de cron. Whenever está muy integrado al framework de desarrollo web Ruby on Rails, aunque puede utilizarse en un programa independiente que genera salidas de tareas para cron y hasta actualiza el archivo crontab. En este post vamos a ver la manera de crear tareas con Whenever desde el punto de vista de un Administrador de Sistemas.
Spring. Decisiones de Control de Acceso
Marzo 11th, 2010
En el proceso de autenticación, una aplicación permitirá a usuarios autenticados una serie de servicios permitidos. Cuando este usuario intenta acceder a un recurso en la aplicacion, tiene que tomar la decisión sobre qué recursos son accesibles con los permisos que tiene asignados o con otras características.
La decisión si a determinado usuario se le permite acceder a un recurso dentro de la aplicación se llama “decisión de control de acceso”. Se basa en el estado de la autenticación del usuario, y de la naturaleza de los recursos y los atributos de acceso. En Spring security, las decisiones de control de acceso son llevados a cabo por los managers de decisión de acceso, los cuales deben implementar la interfaz AccessDecisionManager. Cada uno es libre de crear su propio manager de decisión de acceso implementando esta interfaz, de todas maneras Spring Security viene con tres managers que implementan esta interfaz basado en el método de votos.
REST con Rails
Diciembre 29th, 2009
El uso de REST con Ruby on Rails es extremadamente relajante, una vez que comienzas a utilizar REST y te acostumbras a trabajar de esa forma, no quieres volver a la forma tradicional. Esta es una guía de conceptos básicos de REST y su aplicación en Rails.
REST son las siglas de Representational State Transfer (Transferencia de Estado Representacional), es una técnica de arquitectura software para sistemas hipermedia distribuidos como la World Wide Web. El término se originó en el año 2000, en una tesis doctoral sobre la web escrita por Roy Fielding, uno de los principales autores de la especificación del protocolo HTTP y ha pasado a ser ampliamente utilizado por la comunidad de desarrollo.
Pequeña guía para la elección de un lenguaje de script
Septiembre 29th, 2009
Los lenguajes de script se vuelven cada día más populares en gran parte a su sencillez, expresividad y potencia, entre los más populares tenemos a Python, Perl, Groovy y Ruby. Cada uno tiene sus ventajas y desventajas y debemos tener en cuenta estas características para elegir la herramienta adecuada para el trabajo.
Esta pequeña guía (en inglés) presenta las características más importantes de cada uno, trayendo un poco de luz sobre el tema.
Findbugs: una aplicación para encontrar bugs potenciales en Java
Septiembre 10th, 2009

FindBugs es una aplicación desarrollada por la Universidad de Maryland cuyo objetivo es buscar bugs en programas Java. Está basado en el concepto de patrones de bug. Un patrón de bug es un idioma de código que a menudo es un error. Los patrones de bugs aparecen por una variedad de razones:
- Dificultad de algunas características del lenguaje.
- Falta de comprensión de los métodos de la API.
- Errores de variación cuando el código es modificado durante el mantenimiento.
- Una variedad de errores: errores de tipeo, uso incorrecto de los operadores booleanos, etc.
FindBugs usa análisis estático para inspeccionar el bytecode de Java en busca de patrones de bugs. Con análisis estático nos referimos a que puede encontrar errores simplemente inspeccionando el código de un programa: ejecutarlo no es necesario. Esto hace a FindBugs muy fácil de usar. En la práctica, la tasa de falsas advertencias reportadas por FindBugs es menor al 50%.
Instalación y ejecución
La manera más fácil de instalar FindBugs es bajar la distribución binaria que viene empaquetada en forma de archivo tar.gz o zip. FindBugs requiere JRE (or JDK) 1.5.0 o posterior para poder ejecutarse. Sin embargo puede analizar programas compilados en cualquier versión de Java. Un vez que lo bajamos lo descomprimimos de la siguiente manera:
tar -xvf findbugs-1.3.9.tar.gz cd findbugs-1.3.9/ java -jar lib/findbugs.jar
FindBugs clasifica los bugs en las siguientes categorías
- Correcto pero probable bug: un error de codificación aparente resultando en código que probablemente no era lo que el programador tenía en mente.
- Mala Prácticas: violaciones a las prácticas de codificación esenciales y recomendadas, por ejemplo: uso incorrecto del finalize.
- Código Dudoso: esto es código confuso, anómalo, o escrito de una manera que lleva a si mismo a errores, por ejemplo: casts sin confirmar, chequeos de nulos redundantes, etc.
Tiempo transcurrido en letras en ruby on rails
Julio 27th, 2009
Muchas veces necesitamos calcular y mostrar en una forma legible el tiempo transcurrido desde una fecha hasta el día de hoy. Por ejemplo en twitter podemos ver el tiempo transcurrido de un tweet hasta el momento.
![]()
En Rails este proceso es muy sencillo utilizando el helper time_ago_in_words(), enviando como parámetro la fecha en la que ocurrió el evento. Es importante que el parámetro que le enviamos sea una fecha, en caso contrario nos dará una excepción de error de tipo de datos.
Por ejemplo si queremos saber cuanto tiempo pasó desde que se creó un ticket en nuestra base de datos, en la vista colocamos :
Esto nos dará un resultado como el ejemplo de la imagen, supongamos que pasaron 7 días:
# => 7 days
Hasta alli todo perfecto, pero que pasa si queremos nuestro resultado en castellano?, tenemos que redefinir en nuestro application_helper el método distance_of_time_in_words, simplemente copiamos y pegamos el siguiente código en nuestro application_helper.rb (o en cualquier helper, si solo lo queremos usar en un lugar específico)
def distance_of_time_in_words(from_time, to_time = 0, include_seconds = false)
from_time = from_time.to_time if from_time.respond_to?(:to_time)
to_time = to_time.to_time if to_time.respond_to?(:to_time)
distance_in_minutes = (((to_time - from_time).abs)/60).round
distance_in_seconds = ((to_time - from_time).abs).round
case distance_in_minutes
when 0..1
return (distance_in_minutes == 0) ? 'menos de um minuto' : '1 minuto' unless include_seconds
case distance_in_seconds
when 0..4 then 'menos de 5 segundos'
when 5..9 then 'menos de 10 segundos'
when 10..19 then 'menos de 20 segundos'
when 20..59 then 'menos de um minuto'
else '1 minuto'
end
when 2..44 then "#{distance_in_minutes} minutos"
when 45..89 then 'aproximadamente 1 hora'
when 90..1439 then "aproximadamente #{(distance_in_minutes.to_f / 60.0).round} horas"
when 1440..2879 then '1 dia'
when 2880..43199 then "#{(distance_in_minutes / 1440).round} dias"
when 43200..86399 then 'aproximadamente 1 mes'
when 86400..525959 then "#{(distance_in_minutes / 43200).round} meses"
when 525960..1051919 then 'aproximadamente 1 año'
else "mas de #{(distance_in_minutes / 525960).round} años"
end
end
Luego probamos nustra aplicación nuevamente y veremos que el resultado cambio a:
# => 7 dias


