Draft Idea

Proyectos, ideas y demás :D

En este tercer artículo se tratará la realización de un script sencillo en Python que hará la función de servidor de impresión de archivos PDF en la Raspberry Pi. La segunda parte habla sobre como convertir este script en un servicio de Linux.

Una vez que contamos con nuestro CUPS instalado y funcionando en la Raspberry Pi, ya podemos imprimir desde los ordenadores de nuestra red. El problema reside es que actualmente contamos en nuestra vida cotidiana con muchos dispositivos en los que no podemos configurar CUPS para imprimir como por ejemplo móviles y tablets. Para dar capacidades de impresión a estos dispositivos se ha realizado el script que se comenta a continuación, aunque actualmente cuenta con la restricción de que solo se permite la impresión de archivos PDF.

A continuación se muestra el script del servidor de impresión web (Al final del artículo está el archivo PDF con todos los archivos y la estructura de directorios). Debe tenerse en cuenta que el script está escrito de forma que tenga compatibilidad únicamente con la impresora multifunción DX4800 (en la descripción aparece como DX6000). Para que el script funcione con otros modelos de impresora más adelante se tratará que cosas deberían cambiarse y como obtener la información de las opciones disponibles.

NOTA: La parte en HTML ha sido modificada por problemas con el CMS. Recomiendo descargar el ZIP (al final del artículo)  y consultar la versión correcta. Este problema ha sido solucionado.

Nota: Se ha corregido un problema importante que permitía la ejecución de código aleatorio a través de una petición POST especial.

Interfaz web de impresión

Captura de la interfaz web de impresión

 

En el script anterior se utilizan los siguientes módulos de Python:

  • BaseHTTPServer: Se utiliza para obtener la funcionalidad de servidor web.
  • pyPdf: Se utiliza para comprobar si el archivo recibido es un archivo PDF.
  • cgi: Se utiliza para trabajar con formularios en la web.
  • time: Se utiliza para crear un archivo temporal único.
  • os: Se utiliza para interactuar con el sistema.

 

El script anterior lo que hace básicamente es iniciar el servidor de impresión en el puerto 1478, que se queda esperando a recibir una petición. Si se desea imprimir un documento PDF el usuario debe abrir un navegador y escribir en la barra de direcciones web la dirección IP de la Raspberry Pi y el puerto en el que está alojado el servidor (debería ser algo así 100.101.102.103:1478 siendo 100.101.102.103 la dirección IP de la Raspberry Pi) realizando una petición . Una vez que se recibe la petición desde el cliente, se lanza la función do_GET que responde al cliente con lo que tengamos en esa función. A continuación el usuario puede, o no, contestar a lo que acabamos de enviarle usando una petición tipo POST. En caso de que ocurra, esta petición se procesará en la función do_POST y se realizaran las operaciones necesarias y enviando de vuelta al usuario información indicando si ha habido algún problema o no. A continuación se explica esto un poco más pormenorizado.

En el script anterior el main() inicializa el servidor web y la clase StoreHandler contiene las tres funciones (do_POST, do_GET y respond) que implementan la funcionalidad del servidor web.

  • do_GET: Cada vez que se recibe una petición web, este sencillo servidor responde al cliente que ha hecho una petición con lo que este determinado en ella a través de la función respond (Se debe tener en cuenta que a cualquier tipo de petición siempre se responde esto, da igual que el cliente pida una imagen, una página web o cualquier otra cosa).
  • do_POST: Esta función es la responsable de procesar la información que se recibe desde el usuario (que envia una petición POST) cuando envía el fichero a imprimir. En esta función se procesa el fichero y se crea el comando con el que mandaremos el fichero a imprimir.
  • respond: Es la responsable de enviar datos al cliente (se usa en do_GET y en do_POST)

 

El script anterior lo he situado en /opt/pyprint/printserver.py (solo se puede acceder a este directorio como superusuario). Os recomiendo utilizar el mismo directorio que yo si queréis utilizar el script para convertirlo en servicio de GNU/Linux sin modificar nada.

Básicamente para dar compatibilidad a vuestra impresora se debe averiguar que opciones os da el comando lp para imprimir. Esto se puede averiguar escribiendo en la terminal del ordenador donde la impresora lo siguiente:

lpoptions -d $(lpstat -a|sed -n 1p|cut -d ‘ ‘ -f 1)

 

Con el comando lpoptions -d IMPRESORA se listan todas las opciones que permite utilizar el driver que este cargado para esa impresora. Con el comando lpstat -a se listan todas las impresoras conectadas al equipo. Con sed -n 1p se imprime la primera linea de la salida estándar. Con cut -d ‘ ‘ -f 1 se parte la cadena que recibe utilizando como separador un espacio en blanco y el parámetro -f 1 indica que nos interesa escribir en la salida el primer elemento en los que se dividió la cadena de entrada. La línea vertical | se conoce como pipe y lo que hace es concatenar las operacioes (se ejecuta la primera, lo que escribe la primera se le pasa a la segunda)

Una vez que se conocen estos datos, es necesario editar do_GET para que se muestren las opciones correspondientes a la impresora que se quiere configurar y luego es necesario modificar do_POST para que se lean las opciones de forma correcta y se genere el comando de impresión de forma correcta.

En la función do_POST se recibe el fichero que se quiere imprimir y todos las opciónes de configuración de la impresora. Es importante generar bien el comando de impresión y guardar el fichero recibido para imprimirlo luego.

En el script el archivo PDF se guarda en un archivo en el que el nombre es generado a partir de la fecha y hora actual (para evitar problemas) y se escribe en el directorio /tmp.

 

Para imprimir desde consola se puede utilizar en linux el comando lp. Este comando es el que he utilizado para imprimir en la Raspberry Pi.

 

El parámetro -d permite seleccionar la impresora, se debe escribir el nombre. El parámetro -o permite establecer las opciones, que deben ir entre comillas (las que aparecen en el listado de lpoptions). El último parámetro (obligatorio) es el fichero a imprimir. Un ejemplo sería el siguiente:

 

Establecer el script como un servicio en GNU/Linux.

El siguiente script debe guardarse en /etc/init.d/printweb.sh para que funcione (Al final del artículo está el archivo ZIP con todos los archivos y la estructura de directorios).

 

Para dar de alta el servidor de impresión como servicio, lo que implica que el script en Python del servidor de impresión se lance al iniciar el sistema en la Raspberry Pi, se debe ejecutar en ese directorio el siguiente comando:

 

Automáticamente creará enlaces simbólicos a los niveles de ejecución (runlevels) correspondientes.

Si en algún momento deseas dar de baja el servicio y que por lo tanto NO se ejecute al inicio deberías usar el siguiente comando:

En el siguiente artículo se tratara el script para el servidor de escaneado.

Ficheros del servidor: Archivos del servidor de impresión de PDF v2

Ante cualquier duda, sugerencia, mejora o queja podéis dejarla en los comentarios.

A continuación puedes encontrar los artículos de este proyecto:

 

Bibliografía:
http://www.linuxtopia.org/online_books/programming_books/python_programming/python_ch36s02.html
http://stackoverflow.com/questions/13146064/simple-python-webserver-to-save-file
http://www.stuffaboutcode.com/2012/06/raspberry-pi-run-program-at-start-up.html

2 Comentarios to "Impresora multifunción en red usando una Raspberry Pi, CUPS y Python. Parte III"

  1. […] los artículos anteriores se configuró CUPS y se programó el script del servidor de impresión de PDF. Ahora ya contamos con opciones para imprimir desde ordenadores y dispositivos móviles, pero aún […]

  2. […] Explicación del script del servidor de impresion de PDF y como establecerlo como servicio en Debian… […]

¡Comenta la entrada!

XHTML: Puedes usar los siguientes tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Copyright © 2009 Draft Idea. Theme by THAT Agency powered by WordPress.

div class=The short URL is: