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

En esta nueva entrada, empezaremos explicando como configurar el servidor de impresión CUPS en la Raspberry Pi y a continuación como añadir la impresora en red en Windows y Linux.

Para comenzar, es necesario instalar CUPS, para ellos en una terminal con privilegios de root ejecutamos lo siguiente:

apt-get install cups

Una vez que la instalación finalice es necesario acceder al menú de configuración de CUPS para añadir la impresora que queremos compartir:

En primer lugar debemos asegurarnos de que la impresora está  encendida y conectada a la Raspberry Pi por uno de los puertos USB.

Ahora debemos comenzar a configurar CUPS, para ello tenemos varias opciones para acceder a la web de gestión: podemos acceder desde la propia Raspberry Pi desde entorno gráfico (usando un navegador cualquiera), desde consola (usando el navegador elinks) o sino desde otro ordenador conectado a la misma red. En mi caso he elegido la tercera opción por ser la más rápida y sencilla.

Para acceder a la web de gestión de CUPS es necesario saber que dirección IP tiene asignada la Raspberry Pi (se podría averiguar desde la propia Raspberry Pi con el comando ifconfig o desde la web de gestión del router). En mi caso la Raspberry tiene asignada una IP estática para evitar problemas.

Una vez que tenemos la IP debemos abrir un navegador en un ordenador de la misma red y escribir en la barra de direcciones la dirección IP de la Raspberry Pi, a continuación escribir unos dos puntos («:») y a continuación el número de puerto en la que está escuchando la web de gestión de CUPS (631) quedando algo similar a lo siguiente:

123.456.789:631

Siendo 123.456.789 la dirección IP de la Rasbperry Pi

 Debería cargarse en el navegador una página similar a la siguiente

CUPS home

Panel principal de CUPS

 

Para añadir la impresora debemos pulsar en el enlace que pone «Adding printer and classes« (Añadir impresoras y clases) como se ve en la imagen anterior.

A continuación debemos seleccionar la opción «Add printer« (Añadir impresora) e introducir las credenciales de superusuario para poder añadir y configurar la nueva impresora.

Añadir impresora

Añadiendo nueva impresora

A continuación nos aparece un asistente muy sencillo en el que seleccionar la impresora que queremos configurar, ponerle un nombre y establecerla como compartida, seleccionar el controlador adecuado y establecer la configuración por defecto.

Selección de impresora

Seleccionar impresora a añadir

Añadir nombre

Añadir nombre para la impresora

Selección de controlador

Selección de controlador

Configuración por defecto

Selección de la configuración por defecto

 

Una vez realizados estos pasos, nos aparecerá la pantalla de gestión de la impresora y su cola de impresión. La dirección de este panel es a donde deberemos enviar los documentos que deseemos imprimir (Esta es la razón por la que resulta útil tener una IP estática, de este modo nunca cambia esta dirección).

Panel de gestión y cola de trabajos

Panel de gestión de la impresora. Cola de trabajos

 

Con estos pasos ya tenemos a nuestra impresora en red, esperando a que los documentos lleguen para ser impresos. Pero nos falta añadir esta impresora al resto de ordenadores de la red. Empezaremos añadiendo la impresora a en un sistema GNU/Linux.

 

Añadiendo la impresora en red en GNU/Linux

 

En GNU/Linux es casi automático, debemos entrar en la web de gestión de CUPS en el ordenador en el que queremos añadir nuestra impresora en red usando la siguiente dirección:

localhost:631

A continuación debemos pulsar en «Add printers and classes« (añadir impresoras y clases), poner nuestra contraseña de superusuario y en la siguiente pantalla seleccionar «Find new printers« (Buscar nuevas impresoras).

Buscar impresora en red

Buscar impresora en red

 

Ahora saldrá un listado en el que debería aparecer la impresora configurada en la Raspberry Pi. Debemos seleccionar esa impresora y configurarla siguiendo los mismos pasos que cuando se configuró en la Raspberry con un único cambio: no debemos compartirla por redShare this printer» debe estar desmarcado).

Seleccionar impresora de red

Seleccionar la impresora de red a añadir

Nombre imrpesora y comparticion deshabilitada

Escribir un nombre para la impresora y compartición en red DESHABILITADA.

 

Una vez realizados todos los pasos la impresora debería estar lista para imprimir. Para probar que funciona puedes imprimir un documento de prueba desde el ordenador y debería aparecer la nueva impresora en el menú de selección de impresora

Impresora en red

Seleccionar impresora en red al imprimir

 

NOTA: Hemos añadido la impresora como impresora local enlazada a la impresora en red de modo que el trabajo duro se realiza en nuestro ordenador. También se podría enlazar directamente la impresora en red, pero la Raspberry tiene poca potencia para procesar algunos documentos y se puede volver muy lento (basado en mi experiencia)

 

Añadiendo la impresora en Windows

 

Para añadir la impresora en Windows debemos instalar en primer lugar los drivers de nuestra impresora. Para instalarlos se puede utilizar el disco de instalación de la impresora o buscar los drivers en la web del fabricante.

Una vez instalados los controladores, debemos abrir la ventana «Impresoras y faxes». Para abrirlo pulsamos en Inicio y seleccionamos la opción «Impresoras y faxes«.

impresoras y faxes

Abrir Impresoras y faxes

 

En la ventana de «Impresoras y faxes«, pulsamos en la opción «Agregar una impresora«, la cual abrirá un asistente.

Nueva impresora

Añadir impresora

 

Seguimos las instrucciones del asistente y debemos seleccionar la opción «Una impresora de red o una impresora conectada a otro equipo«.

Añadir impresora. Asistente

Asistente para añadir una nueva impresora

Añadir impresora de red

Seleccionar añadir una impresora de red

 

En la siguiente pantalla debemos seleccionar la opción «Conectarse a una impresora en internet o en su red doméstico u organización« y debemos escribir la dirección de la impresora (es la dirección que se indicó al inicio de este artículo).

Añadir impresora

Escribir la dirección de la impresora

 

A continuación se debe seleccionar el modelo de la impresora, los cuales solo aparecerán si la impresora es compatible con su sistema operativo o han sido instalados de antemano.

En la siguiente pantalla, se pregunta si se desea establecer la impresora que acabamos de añadir como predeterminada.

Hacer impresora predeterminada

Establecer impresora como predeterminada

 

La nueva impresora aparecerá en la ventana «Impresoras y faxes»

Impresora en Impresoras y faxes

La impresora aparecerá en la ventana de Impresoras y faxes

 

Por último se podría hacer una prueba de impresión desde cualquier programa.

Impresión de prueba

Impresión de prueba

 

En el próximo artículo se explicará un script en Python para imprimir archivos PDF de forma remota, muy útil para imprimir desde una tablet, un móvil o cualquier dispositivo que tenga un navegador web.

Ante cualquier duda, error, mejora o queja vuestros comentarios son bienvenidos.

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

Una impresora multifunción (impresora y escáner) es un aparato muy útil tanto para casa como para oficina. Si queremos utilizar la multifunción para imprimir o escanear desde muchos dispositivos distintos puede ser una tarea poco práctica o imposible. Para sortear este inconveniente he desarrollado esta solución que, aunque es muy mejorable, ofrece la funcionalidad básica.

En mi caso, contamos en casa con una impresora multifunción y varios ordenadores desde los que sería interesante poder imprimir y escanear. Hasta hace poco para imprimir o escanear era necesario ir al ordenador en el que la impresora estuviera conectada y realizar la operación deseada, siempre que el ordenador no estuviera ocupado en ese momento. Otra cosa que también resulta molesta es no poder imprimir desde una tablet o un móvil.

Para solucionar este problema una posible solución es aprovechar la red interna de casa o de la oficina para conectar la impresora multifunción en red. Para ello es necesario utilizar un ordenador como servidor de impresion y escaneado para poder ofrecer estos servicios a todos los dispositivos conectados a la red.

En concreto, para este proyecto se ha utilizado una multifunción de la marca Epson y se ha elegido como servidor un mini ordenador llamado Raspberry Pi que ofrece un rendimiento razonable con un bajo precio y un bajo consumo. En particular, se ha usado una Raspberry Pi modelo B con 256 megabytes de RAM con el sistema operativo Debian y la impresora es una Epson DX4800.

El software utilizado en este proyecto ha sido el servidor de impresión CUPS y dos sencillos scripts en Python que ofrecen la funcionalidad de servidor de impresión de PDF y de servidor de escaneado.

Ejemplo de configuración de red.

Esquema de ejemplo de configuración de red.

 

En el esquema anterior se muestra un ejemplo de la configuración de red que se puede utilizar en este proyecto y es la que se ha tenido en cuenta al realizar esta serie de artículos.

 

Esquema Raspberry Pi

Esquema de conexiones en la Raspberry Pi

 

En la imagen anterior se ilustra las conexiones de la Raspberry Pi que se han utilizado en este proyecto. Como se puede observar se ha utilizado uno de los puertos USB para conectar la impresora y el puerto Ethernet para conectar el Raspberry Pi al router (al que se conectan el resto de dispositivos).

También es posible conectar el Raspberry Pi por red inalámbrica al router utilizando un adaptador inalámbrico en el segundo USB, pero para ello es necesario realizar un poco de configuración extra.

En los siguientes artículos se explica todo lo refente a la implementación de esta solución:

Se agradecen los comentarios ante cualquier duda, sugerencia o corrección.

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