El tamaño máximo de un archivo que puedes almacenar en una USB (fat32) es de 2Gb (o 4Gb si estas utilizando LFS).

Si quieres copiar un archivo con un tamaño mayor, en linux, puedes hacerlo mediante el comando split, por ejemplo

split -b 2048 image.iso

que nos producirá una serie de archivos

image.isoaa
image.isoab
image.isoac
...

Después para juntarlos utilizamos el comando cat

cat image.iso* > ~/image.iso

El comando anterior no nos muestra un avance del progreso. Para ver el progreso podemos utilizar el comando pv, para instalarlo ejecuta sudo apt-get install pv y lo utilizas de la siguiente manera

cat image.iso* | pv -s $(du -cb image.iso* | grep total | awk '{print $1}') > ~/image.iso

Fuentes:
http://unix.stackexchange.com/questions/24630/whats-the-best-way-to-join-files-again-after-splitting-them
http://www.catonmat.net/blog/unix-utilities-pipe-viewer/
http://en.wikipedia.org/wiki/File_Allocation_Table#FAT32
http://unix.stackexchange.com/questions/41550/find-the-total-size-of-certain-files-within-a-directory-branch

Para la digitalización de documentos utilizamos escáneres que producen archivos TIFF, estos permiten almacenar varias imágenes en el mismo archivo. Estas imágenes se guardan en una base de datos para su posterior consulta.

Para poder desplegar estas imágenes en una aplicación web, necesitamos convertirlas a un formato estándar para la web (JPG, PNG ó GIF). Esto se puede lograr utilizando la librería image magick. Para usarla en Java existen 2 opciones: JMagick e im4java. Decidí utilizar im4java debido a los riesgos de usar JNI en una aplicación web (http://im4java.sourceforge.net/docs/faq.html)

Lo primero es agregar la dependencia de im4java a nuestro proyecto, archivo pom.xml si usas maven o agregar el jar a tu build path.

   <dependency>
      <groupId>org.im4java</groupId>
      <artifactId>im4java</artifactId>
      <version>1.4.0</version>
   </dependency>

Utilizamos un arreglo de bytes para cargar la imágen desde la base de datos y lo pasamos como un stream a la librería im4java para seleccionar la página que deseamos convertir al formato jpg.

    public byte[] getPagina(Integer pagina) throws Exception{
        byte[] imgPagina = null;
        byte[] imagen = loadImageFromDatabase();
        try{
        IMOperation op = new IMOperation();
        op.addImage(String.format("-[%d]", pagina - 1)); // read from stdin and specify page number with 1-based index
        op.addImage("jpg:-");               // write to stdout in jpg-format
        ByteArrayInputStream fis = new ByteArrayInputStream(imagen);
        ByteArrayOutputStream fos = new ByteArrayOutputStream();
        // Pipe pipe = new Pipe(fis,fos);
        Pipe pipeIn  = new Pipe(fis,null);
        Pipe pipeOut = new Pipe(null,fos);
        // set up command
        ConvertCmd convert = new ConvertCmd();
        convert.setInputProvider(pipeIn);
        convert.setOutputConsumer(pipeOut);
        convert.run(op);
        imgPagina = fos.toByteArray();
        }catch(Exception e){
            throw new Exception(
                    "Error al obtener la imágen de la página " + pagina, e);
        }
        return imgPagina;
    }

este método lo podemos utilizar en un servicio web/servlet para servir la imágen a través de una url

    @GET
    @Path("documento/{id}/imagen/pagina/{numero}")
    @Produces("image/jpeg")
    public Response getPaginaPromocion(@PathParam("id")Integer id, @PathParam("numero")Integer numero){
        Response response = null;
        try{
            Documento doc = Documento.get(id);
            response = Response.ok(doc.getPagina(numero), "image/jpeg").build();
        }catch(Exception e){
            String error = String.format("Error al obtener la página %d del documento %s", numero, id);
            log.error(error, e);
            response = Response.serverError().entity(String.format("{\"response\": {\"status\": -1, \"data\": \"%s\"}}", error)).build();
        }
        return response;
    }

Fuentes:

http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=16615#p61020
http://stackoverflow.com/questions/4809314/imagemagick-is-converting-only-the-first-page-of-the-pdf
http://im4java.sourceforge.net/docs/dev-guide.html#piping
http://stackoverflow.com/questions/2091454/byte-to-inputstream-or-outputstream
http://im4java.sourceforge.net/api/

Para el registro de errores y tareas utilizamos bugzilla. Cuando me asignan una tarea mediante un oficio, adjunto el documento digitalizado. La mayoría de veces no tengo problemas, pero el día de ayer me arrojó un error debido al tamaño del archivo PDF.

Buscando una forma de reducir el tamaño del PDF (digitalizado mediante CamScanner con una iPad) me encontré este post. La forma que me pareció más sencilla y efectiva fue mediante ghostscript.

Primero asegurate de tener instalado ghostscript

sudo apt-get install ghostscript

Simplemente crea un archivo llamado shrinkpdf.sh en tu carpeta ~/bin o cualquiera que se encuentre en el path con el siguiente contenido.

    #!/bin/sh
    dpi=72
    if [ $# -lt 2 ]
    then
       echo "usage: $0 input output [dpi]"
       exit 1
    fi
    if [ $# -gt 2 ]
    then
       dpi=$3
    fi
    echo "Shrinking document..."
    gs  -q -dNOPAUSE -dBATCH -dSAFER \
        -sDEVICE=pdfwrite \
        -dCompatibilityLevel=1.3 \
        -dPDFSETTINGS=/screen \
        -dEmbedAllFonts=true \
        -dSubsetFonts=true \
        -dColorImageDownsampleType=/Bicubic \
        -dColorImageResolution=$dpi \
        -dGrayImageDownsampleType=/Bicubic \
        -dGrayImageResolution=$dpi \
        -dMonoImageDownsampleType=/Bicubic \
        -dMonoImageResolution=$dpi \
        -sOutputFile=$2 \
         $1

hazlo ejecutable con el comando

chmod a+x ~/bin/shrinkpdf.sh

finalmente utilizalo para comprimir cualquier archivo PDF de la siguiente forma

shrinkpdf.sh ~/input.pdf ~/output.pdf 150

El último parámetro le indica la resolución que va a utilizar. 150 dpi en el ejemplo, el cual produce una buena calidad de las imágenes. Puedes omitir este parámetro y por default utilizará una resolución de 72 dpi que produce archivos mucho más pequeños pero pierde calidad.

Necesitaba hacer un reporte con un tipo de letra que no viene instalado en Ubuntu por default, así que investigando un poco encontré que hay varias ubicaciones donde puedes copiar el archivo de la fuente. Estas ubicaciones están definidas en el archivo /etc/fonts/fonts.conf. Por default incluye /usr/share/fonts, /usr/local/share/fonts y /home//.fonts (dónde es tu nombre de usuario).

Lo más fácil es crear la carpeta .fonts, si no existe, en tu carpeta de usuario.

mkdir ~/.fonts

Luego copia ahí las fuentes que deseas instalar.

Finalmente ejecuta el comando

sudo fc-cache -f -v

para actualizar la lista de fuentes disponibles, luego cierra y abre los programas dónde deseas utilizar la fuente o reinicia tu máquina y listo!

Fuentes:
https://wiki.ubuntu.com/Fonts#Manually

jQuery – desde un CDN o desde el servidor

En el enlace de abajo se hace un análisis sobre si cargar jQuery desde un CDN (como el de Google)

<script src=”//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js”></script>

o desde el servidor

<script src=”/path/to/jquery/1.8.2/jquery.min.js”></script>

Algo que no se menciona es que estamos confiando en que el archivo del CDN no contiene otro código además del de jQuery, seguramente Google guarda información acerca de los sitios que cargan la librería desde sus servidores. En fin, creo que estoy siendo un poco paranoico, de cualquier forma Google sigue la filosofía de “Don’t be evil” 🙂

via Cargar jQuery desde un CDN o desde servidor | EtnasSoft.

JDeveloper 11g – Changing default JVM

Cuando instalas JDeveloper 11g, este incluye el JDK (necesario para ejecutar la aplicación). El problema es que incluye una versión de 32bits. Si tu sistema operativo es a 64 bits -Ubuntu 12.04 por ejemplo- probablemente te aparezca un error como el siguiente

libX11.so.6: cannot open shared object file: No such file or directory

Para resolverlo hay que instalar un JDK a 64 bits y configurarlo en el archivo jdeveloper/jdev/jdev.conf

SetJavaHome /usr/lib/jvm/java-6-openjdk-amd64/

Ya que en mi caso utilizo OpenJDK.

via OTN Discussion Forums : Changing default JVM in Jdeveloper 11 ….

Para configurar Apache CXF en una aplicación web, lo puedes hacer de muchas formas. Esto me confunde, ya que hay distintos ejemplos en internet.

Mi forma preferida es configurar un servlet en el archivo web.xml y configurar los servicios en un archivo beans.xml. Un ejemplo básico de estos archivos sería como el siguiente:

web.xml


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<display-name>CXF Servlet</display-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<init-param>
<param-name>config-location</param-name>
<param-value>/WEB-INF/beans.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
</web-app>

beans.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd">

<import resource="classpath:META-INF/cxf/cxf.xml" />

<jaxws:endpoint id="HelloSOAP" address="/ws/helloService"
implementor="com.acme.ws.soap.HelloServiceImpl" />

<jaxrs:server id="rest-api" address="/rest">
<jaxrs:serviceBeans>
<bean id="HelloREST" class="com.acme.ws.rest.HelloREST" />
</jaxrs:serviceBeans>
</jaxrs:server>

</beans>

Las dependencias necesarias en Maven son las siguientes:


<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.6</version>
</dependency>

La dependencia a la librería spring-web es necesaria desde la versión 2.6 de Apache CXF. Las dependencias de SLF4J son opcionales, pero muy recomendables para ver la información del Log. Si quieres saber como configurar SLF4J puedes verlo aquí.

Fuentes:
Apache CXF — Servlet Transport.
http://stackoverflow.com/questions/6349424/apache-cxf-rs-extensions-issue-in-2-4-0