Draft Idea

Proyectos, ideas y demás :D

En este cuarto artículo tiene como objetivo comentar el script en Python que hará la función de servidor de escaneado en la Raspberry Pi. La segunda parte habla sobre como convertir este script en un servicio de Linux.

En 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 no podemos utilizar todo el potencial de la impresora multifunción ya que aún no podemos utilizar la función de escaneado. Para solucionar este problema, el siguiente script crea un sencillo servidor web, muy parecido al que se utilizó en el artículo anterior para el servidor de impresión, con el que realizar un escaneado del documento que se encuentre en la bandeja de escaneado. Una vez que el escaneado llega a su fin, el servidor web envía al cliente un archivo de imágen en formato TIFF con el documento escaneado.

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 escaneado.

Captura de la web de escaneado.

 

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

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

 

La funcionalidad del script anterior es muy similar a la que se explico en el artículo anterior. El script inicia el servidor de escaneado en el puerto 1479, que se queda esperando a recibir una petición. Si se desea realizar un escaneado, 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:1479 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 se enviará de vuelta al usuario la imagen escaneada, si ha habido algún problema, la imágen devuelta será de 0 bytes. 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 envía una petición POST) cuando realiza la petición de escaneado. En esta función se procesa la petición (con todas las opciones seleccionadas) y se crea el comando con el que se escaneará el documento.
  • 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/pyscan/scanserver.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.

En esta ocasión, para dar compatibilidad a vuestro escáner primero debe ser reconocido y estar configurado (si fuese necesario) en el sistema en el que se implemente el servidor de impresión (en este caso en la Raspberry Pi). A continuación se puede averiguar si vuestra impresora es reconocida por el sistema con el siguiente comando (en modo superusuario):

 

Nota: Dispositivos webcam y algunos otros también son reconocidos como dispositivos válidos. Esto obliga a obtener el nombre del dispositivo a mano en caso de que tengais más de un dispositivo compatible (en la Raspberry Pi, no existia ningún otro, por lo que este detalle no se tiene en cuenta)

Para obtener todas las opciones con las que el sistema permite trabajar al escanear documentos con un dispositivo determinado se puede utilizar el siguiente comando:

 

Sustituyendo DEVICE por el dispositivo que se quiera utilizar como impresora obtenemos la ayuda y las opciones para ese dispositivo.

Una vez que se conocen estos datos, es necesario editar do_GET para que se muestren las opciones correspondientes al escáner que se desea configurar en la interfaz web y luego es necesario modificar do_POST para que se lean las opciones y se genere el comando de escaneado de forma correcta.

En la función do_POST se reciben todas las opciónes de configuración del escaneado (blanco y negro o color, resolución…). Es importante generar bien el comando de escaneado y guardar el fichero generado al escanear para poder enviarlo de vuelta.

En el script el archivo escaneado 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 escanear desde consola se puede utilizar algo como lo siguiente:

 

El parámetro -d nos permite seleccionar el dispositivo con el que se va a escanear. El parámetro mode nos permite decidir si deseamos escanear en color (Color) o en blanco y negro (Gray), el parámetro resolution nos permite seleccionar la resolución (en DPI) con la que escanear, el parámetro format nos permite seleccionar el formato de salida. Un ejemplo concreto podría ser algo como lo siguiente:

 

Establecer el script como un servicio en GNU/Linux.

.El siguiente script debe guardarse en /etc/init.d/scanweb.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 escaneado como servicio, lo que implica que el script en Python del servidor de impresión se lance al iniciar 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:

 

Ficheros del servidor: Archivos del servidor de escaneado v2

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

Este es el último artículo de este proyecto. Los anteriores puedes encontrarlos aquí:

 

Bibliografía:
http://www.linuxtopia.org/online_books/programming_books/python_programming/python_ch36s02.html
http://www.stuffaboutcode.com/2012/06/raspberry-pi-run-program-at-start-up.html

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ónAdd 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 enAdd printers and classes (añadir impresoras y clases), poner nuestra contraseña de superusuario y en la siguiente pantalla seleccionarFind 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 red (“Share 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:

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