sábado, agosto 22, 2009

twitter desde línea de comandos

Twitter, ese gran amigo de muchos y mal endémico de la web 2.0 al que yo aún no había sucumbido. El enjuto hermano bastardo del "blogger". La forma de que la web 2.0 convierta tu vida en Tu Vida 2.0, aquí en Mundo Real™.

¿Y qué es lo que le preocupa a un usuario de GNU/Linux cuando conoce Twitter? ¿me quedaré enganchado a ésto por el resto de mis días? ¿seré hallado con 80 años muerto relatando mi propia agonía en 140 caracteres? ...

... pues no ...

... la verdadera pregunta es ... ¿se podrá hacer ésto desde línea de comandos? Y obviamente hay como otras 8000 personas a las que eso ya se les ocurrió antes, así que la respuesta a vuestras plegarias sale con un googleo simple.

Esta es una entrada chorra (tengo algunas más interesantes en mente y proyecto), así que sólo pondré las 2 formas que me han resultado más divertidas.


Fórmula 1 -- postear en twitter usando curl

Gracias al API de twitter, se puede usar curl para hacer un sencillo micro-post con un comando tan chorra como...

curl -u usuario:contraseña -d status="Tu mensaje" http://twitter.com/statuses/update.xml



Fórmula 2 -- Twitter Tools

Esta aplicación escrita en python es la que más me ha gustado para esta tarea (sólo he inspeccionado 4 o 5, tampoco es que tenga mucho criterio). Es sencillita y te permite ver tu twitter con sólo hacer...

twitter

¿Fácil no? Veamos 2 formas de instalarla.

La primera es la más sencilla, y consiste en instalar el paquete apropiado desde línea de comandos. Algo tan fácil como...

sudo aptitude install python-twitter

La otra forma consiste en irse a la página web (http://mike.verdone.ca/twitter/) y descargarse el código fuente (en tar.gz). Luego lo descomprimimos con...

tar -xvzf twitter-.tar.gz

ahora nos intalamos el paquete python-setuptools con...

sudo aptitude install python-setuptools

accedemos a la carpeta twitter dentro de la carpeta descomprimida y desde dentro hacemos...

sudo easy_install twitter

La ventaja de usar la versión descargada es que como es lógico, te descargas la última versión disponible que siempre va a estar por encima de la disponible en los repositorios. La desventaja, que no tienes la actualización automática que te dan los repositorios. Para algo con tan poco calado e importancia, yo personalmente recomiendo usar la instalación desde los repositorios.


La configuración

Para ahorrarnos el tener que poner el usuario y contraseña cada vez que vamos a consultar o escribir en nuestro twitter, podemos crear un fichero en ~/.twitter que tenga un contenido como el siguiente...

[twitter]
email: mi_usuario
password: mi_clave
format: ansi
prompt: '[cyan]twitter[R]'

...que hará que no tengáis que introducir usuario y clave, y además pondrá de colorines el resultado de las lecturas de forma que será más entretenido de leer :).


El resultado

Y ahora el resultado. Un ejemplo...

twitter set "Python Twitter Tools mola, lo recomiendo realmente a todos/as"
produciría un resultado que podríamos ver desde línea de comandos con el comando "twitter" como os pongo a continuación...



Y visto desde la web de twitter...


Y bueno, para quienes finalmente decidáis usar este sistema de microblogging ya iréis descubriendo que desde la Ptt (Python twitter tools) se pueden hacer muchas más cosas. Pero eso ya os lo dejo a vosotros/as.

Un abrazo a todos/as.

lunes, agosto 10, 2009

Códigos del motor de informes dinámicos en PDF

Debido a la demanda de los códigos, he realizado un pequeño proyecto sobre la entrada "Motor de informes dinámicos con iTextSharp(I)" . Os recomiendo leer primero el post para poder entender los códigos correctamente y sacarles el máximo partido.

Podéis descargar el proyecto desde aquí. Espero que os sea de utilidad.

sábado, junio 27, 2009

Sistema de plugins en C# usando Reflexión

En este post os voy a describir un pequeño sistema de plugins que implementé para un proyecto y que me resultó de mucha utilidad y sobre todo, me permitió aumentar el sistema sin tener que cambiar nada de lo ya establecido (códigos, recompilaciones, etc.).

La idea es disponer de un sistema de plugins para un CMS (gestor de contenidos) de forma que cada plugin sea autogestionado y no haya que tocar nada del sistema a la hora de introducir un nuevo plugin, salvo lógicamente introducir su definición en base de datos. En el proyecto que implementé, los plugins eran elementos visuales que permitían realizar la maquetación de las páginas mostrando el contenido de base de datos de diferentes formas (contenido tabulado, histórico, contenido con scroll, publicidad, etc.).



No voy a entrar en cómo implementar toda la estructura del sistema de elementos visuales (será para un artículo posterior), lo importante es cómo podemos, acceder a clases de c# sin utilizar elementos tipados. Es decir, lo normal para instanciar un objeto es utilizar la siguiente nomenclatura:

TipoObjeto miObjeto = new TipoObjeto(parametros);

En el caso de un sistema dinámico de plugins, no podemos utilizar esa nomenclatura porque no sabemos a priori la clase del objeto a utilizar. En esta situación, la reflexión se nos ofrece como técnica perfecta.

Implementación del sistema de plugins

Los plugins se dan de alta en base de datos, cada proyecto puede utilizar su propia definición de tablas. En mi caso, creé dos tablas, una para guardar la definición del elemento y otra para almacenar las propiedades modificables del elemento. Por ejemplo, uno de los plugins era para introducir un bloque de código HTML directamente en la página. La definición de este elemento es:


y la definición de sus propiedades es:


Lo importante de los datos almacenados para cada elemento es el campo "clase" en el que se guarda la clase de código que implementa la funcionalidad de este elemento. En este caso, la clase es plugins.elementoHtml. Este campo se utiliza luego para la reflexión.

Interfaz de los plugins
Este paso no es necesario pero es bueno que todas las clases que se encarguen de plugin implementen una interfaz obligando a que el método público de acceso sea siempre igual y no haya fallos de parámetros. En mi caso, la interfaz definía los siguientes métodos:

La interfaz define dos métodos, uno para obtener el código html del plugin cuando se debe insertar en el centro de la página y otro para cuando se debe insertar en el lateral de la página. Los parámetros que se pasan son el id particular para cada elemento y un object extras con parámetros extras que hicieran falta en cada caso.

El quid de la cuestión

En cada proyecto, obtendremos referencias a nuestros plugins de la manera que queramos. El quid de la cuestión se encuentra en las líneas que utilizan la reflexión para acceder a los métodos de la clase de cada plugin:




Lo que hacemos es:
  1. Obtener el campo "clase" de la base de datos y llamar al método Type.GetType para obtener el tipo del elemento.
  2. A través de reflexión podemos obtener acceso al constructor e invocarlo pasándole los argumentos necesarios, en este caso null porque no hay argumentos.
  3. Obtener la información del método "Renderizar" que es el que utilizamos de cada clase y que define la interfaz.
  4. Invocamos el método pasándole el objeto inicializado mediante el constructor y le pasamos un vector de objects con los parámetros que el método está esperando.
  5. El resultado del método (en este caso un string), se obtiene haciendo un cast a string.
Conclusión
La reflexión es una herramienta muy potente dentro del lenguaje .net que permite llamar a métodos y objetos sin conocer previamente el tipo. Esto permite generar sistemas como el descrito de una forma eficiente. El problema estriba en que, inicialmente no es un tipo de programación sencilla y requiere un tiempo para acostumbrarse a cómo funciona.

Espero que os haya gustado este artículo y que os sirva esta idea para vuestros desarrollos. En mi caso, me ha sido de mucha utilidad.




domingo, junio 14, 2009

Problema de expiración de la sesión en ASP.net

Los códigos de este post los podéis descargar desde aquí

Finalmente, por fin he encontrado un rato para escribir un post en el blog. Tenía en mente varios temas pero al fin me he decidido por éste que me parece bastante interesante y útil para aquellos que desarollamos aplicaciones en asp.net. Pongámonos en situación, cuando escribimos aplicaciones, una de las herramientas más utilizadas para mantener la persistencia de los datos es la sesión, almacenamos en sesión tablas con las que trabaja el usuario por pantalla, ids de filas, usuarios, variables, etc. todo ello para que cuando el usuario pulse algún botón y se realice un postback, podamos realizar las acciones correspondientes. Es decir, la sesión nos mantiene conectado con el usuario en un entorno desconectado. El problema viene cuando el tiempo de sesión expira, si el usuario no ha realizado ninguna acción pasados x minutos (5 por defecto), el servidor (IIS) elimina su sesión. En el momento en que el usuario pulse un botón y se vaya al servidor, nos encontraremos con que aquellos datos que habíamos guardado en la sesión ya no existen y (dependiendo de cómo controlemos esta situación) saltará una excepción en algún punto de nuestro código, echándonos fuera de la aplicación, o saltando una fantástica pantalla amarilla o algo parecido.

En aplicaciones en las que las operaciones se realicen en el servidor no vamos a tener problemas con la sesión porque cada vez que el usuario realice un postback, la cuenta de expiración de la sesión se reinicirá. En el caso que hagamos aplicaciones que hagan uso de la lógica del cliente, tipo blogs, editores wysiwyg, o que el usuario realice operaciones largas en el explorador sin tener que ir al servidor, el tiempo de expiración de la sesión se convierte en un gran problema para el programador y en una gran molestia para el cliente. Imaginaos escribiendo un post en un blog y que cuando lleváis 30 minutos escribiendo, habéis acabado el post le dais a guardar y salta una excepción, perdiendo todo el trabajo...

Posibles soluciones a este problema
Existen varias soluciones a este problema, que dependiendo de dónde esté alojada nuestra aplicación nos serán factibles o no.

Solución 1: Web.config

La solución más fácil es incorporar en nuestro web.config la etiqueta "sessionState" con el atributo "timeout" indicándole el número de minutos que deseamos que se mantenga la sesión (dentro de la sección system.web):



En este caso, hemos aumentado el tiempo de sesión a 60 minutos, antes de que el servidor la elimine. Sin embargo, me he encontrado alojamientos en los que, aunque en mi web.config tenga incluido este tag, el tiempo de sesión viene marcado por el servidor sin posibilidad de cambiarlo desde aquí.

Solución 2: Pool de aplicaciones
La segunda solución con la que contamos es la de crear un pool de aplicaciones en el IIS para nuestra aplicación. En dicho pool podemos especificarle el tiempo de sesión que queremos. Además, al crear un pool propio, se lanza un proceso en el sistema para nosotros solos. Esto es bueno en el caso de alojamientos compartidos en los que en el mismo proceso puede haber muchas aplicaciones ejecutándose. Siempre es aconsejable tener nuestro propio pool de aplicaciones, el cual se crea de la siguiente manera:

1. Desde el administrador de IIS, pulsamos con el botón derecho sobre "Grupos de aplicaciones" y seleccionamos un nuevo grupo:


2. Le damos un nombre al nuevo grupo de aplicaciones:


3. Lo siguiente es configurar las opciones de rendimiento para este grupo de aplicaciones, como la cantidad de memoria a asignar, el tiempo de reciclado del proceso o el tiempo de sesión para este grupo, entre otras opciones:


4. Por último, a un sitio o directorio web, le asignaremos este grupo de aplicaciones desde sus propiedades:


Solución 3: Servicio web de Echo
Para implementar las dos soluciones anteriores necesitamos tener control sobre el servidor (cosa que no siempre es así). En el caso que tengamos alojamientos compartidos, podemos utilizar esta opción (es la que utilizo ahora). Normalmente, un portal web dispone de dos partes, la pública (en la que normalmente se puede funcionar con cookies) y la privada en la que trabajaremos con sesiones. Es en la parte privada donde utilizaremos esta opción. La idea es implementar un servicio web que simplemente realice un eco, reciba un parámetro y lo devuelva. Habilitamos la sesión para el servicio web con lo que cada vez que se llame a este servicio, la cuenta de expiración de la sesión se reinicirá. Desde las página de gestión se llama, vía AJAX, periódicamente (yo lo tengo cada 50 segundos) a dicho servicio web para que no reinicie la cuenta. De forma esquemática, la solución es la siguiente:


El código del servicio web es el siguiente:

Tenemos que introducir el using System.Web.Script.Services para poder utilizar este servicio web vía AJAX. Además, la definición del servicio web incluye la sentencia [WebMethod(true)] indicando que se utilizará la sesión en ese método del servicio web. Para llamar a dicho método desde la página maestra (lo normal) o desde cualquier página de nuestra aplicación utilizaremos el siguiente código:

a. Incluir una referencia web al servicio web creado.
b. Dar de alta el servicio web mediante el ScriptManager de la página
En la propiedad Path pondremos la ubicación del fichero .asmx (servicio web). Si, al crear el servicio web, separados el código del fichero, se creará un fichero .asmx con la definición del servicio web donde le hayamos dicho y un fichero .cs con los códigos dentro de la carpeta App_Code.


c. Crear la función Javascript que llama al servicio web


d. Crear el temporizador para que se repita la llamada cada x segundos

Ponemos la función en el onload de la página para que se ejecute al iniciar la página. En este caso esta puesto que se repita la llamada cada 50 segundos (50.000 milisegundos)


Conclusión
Esta última es una solución sencilla que nos puede servir en cualquier entorno en el que trabajemos con aplicaciones asp.net. Utilizando el servicio de echo, nos aseguramos que la sesión del usuario no va a expirar independientemente del tiempo que esté sin hacer ningún postback. En el caso que el usuario cierre la ventana del explorador, se deja de llamar al servicio con lo que la sesión expirará en los 5 minutos correspondientes. Por supuesto, siempre podemos colocar el botón de cerrar que matará la sesión. Como siempre, espero que os sea de utilidad este post y gracias por leer este blog (ya sois un montón).

martes, abril 07, 2009

Traductor de Artilugios en ASP.NET

La página de demostración la podéis encontrar aquí.
El comprimido con los códigos del proyecto os lo podéis descargar de aquí.


Hacía tiempo que no escribía un post pero, finalmente, he conseguido un poco de tiempo. En este post lo que os voy a contar es un pequeño pero muy útil, por lo menos para mí, proyecto que hice en su día y que voy mejorando y modificando a medida que lo necesito. El proyecto se llama "Traductor de Artilugios" (un nombre raro, pero es que no tenía y se lo acabo de poner) y es un generador de objetos complejos para gestores de contenido.

Un generador de qué?
La idea la cogí de Wordpress, el cual permite introducir ciertos sinónimos en el editor de post que posteriormente son traducidos a un html más complejo (video y música). Es una forma muy sencilla de poder introducir componentes flash que precisan de etiquetas object o embed o código html elaborado.

Con esta idea me hice una pequeña clase TraductorObjetos.cs que generaba ese código en las páginas de forma dinámica. Inicialmente lo hice para video flash (flv en el servidor) y videos de youtube, luego le metí un reproductor mp3, galeria javascript, ventanas modales, galeria flash. A medida que voy necesitando algo lo voy metiendo.

Sí, muy bien, pero ¿cómo funciona?
El funcionamiento es el siguiente:

a. Desde un editor WYSIWYG (yo utilizo FCKEditor) se introduce el texto de la entrada y se incluye el sinónimo del artilugio. En este caso, voy a meter un video flash por lo que utilizo el sinónimo video. La cadena que utilizo es @video [urlVideo]=[Yeguada1.flv]@ indicando que la url donde se encuentra el video es yeguada1.flv.









b. Ese código se guarda en base de datos. A la hora de renderizar el código en pantalla, se llama a la función Traducir de la clase TraductorObjetos.cs para que rastree el código HTML guardado en base de datos en busca de artilugios. La definición de los artilugios se guarda en una tabla de base de datos con dos campo (nombre y código).



c. Una vez localizado el sinónimo en la cadena de HTML, se sustituye dicha cadena por el valor de base de datos, poniendo los parámetros en su lugar correspondiente. Los parámetros en base de datos se identifican por el símbolo @ (p.e. @urlVideo es un parámetro que será sustituido en tiempo de ejecución).

d. Finalmente, se devuelve el código traducido para que sea renderizado en pantalla.















Extensibilidad

Es muy fácil incluir más elementos en el proyecto, basta con insertar el código a traducir en la tabla con los parámetros correspondientes y listo. Tened en cuenta que todos los ficheros extras utilizados (javascript, flash, hojas de estilo,...) por lo artilugios se localizan en la carpeta "extras" y se deben cargar en la página para que funcionen correctamente.


Conclusión

Espero que este proyecto os sirva tanto como me sirve a mi en mis desarrollos. Con una simple línea, el usuario es capaz de generar códigos muy complejos que de otra forma no podría hacerlo. Os he dejado los códigos del proyecto así como una página de demo donde podéis probar con las diferentes cadenas de sinónimos que tengo puestas.


lunes, marzo 02, 2009

Artículo en la revista "Solo Programadores"


Este mes he publicado un artículo en la revista "Solo Programadores". El artículo se titulo "Aplicaciones multiidioma en ASP.NET" e invito a todo el mundo a que lo lea. Es la primera vez que publico en una revista tecnológica de tirada nacional.






El sumario de la revista es el siguiente:


lunes, febrero 23, 2009

Encriptación de imágenes/ficheros en servidor con asp.net

Las clases Crypto.cs y CryptoProvider.cs las podéis descargar desde aquí.

En este artículo vamos a explorar un aspecto que siempre me ha tenido preocupado a la hora de trabajar con imágenes o ficheros subidos por los usuarios en aplicaciones en internet con asp.net. El problema es la encriptación de esos archivos para evitar que alguna persona pueda linkarlos y acceder a ellos. 

La raiz del problema
Cuando programamos una aplicación ASP.NET para que se puedan subir archivos a una carpeta, debemos darle permiso al usuario con el que se ejecuta el proceso ASP.NET para que escriba en esa carpeta y para leer la información (para su poste
rior visionado). Una alternativa es realizar un impersonate sobre el proceso (algo que nunca me ha gustado). Otras alternativas que propone la gente es darles nombres extraños, ubicaciones extrañas, etc. pero no dejan de ser soluciones de ocultación que no solventan el problema. La alternativa que vamos a ver en este post es la de realizar una encriptación del fichero subido con el algoritmo AES-Rijndael de forma que aunque un potencial usuario malintencionado gane acceso al fichero subido, no sea capaz de averiguar su contenido.

Las dos partes del problema
La encriptación de ficheros en servidor tiene dos partes bien diferenciadas que tenemos que solventar:
  1. Encriptación al subir el fichero
  2. Desencriptación al vuelo al visionar/descargar el fichero sin dejar ninguna copia desencriptada en el servidor.
El flujo de información del proyecto es el siguiente:
















Vamos al lío, subiendo archivos al servidor...
La primera parte es subir archivos al servidor. Cada uno utilizará el método que quiera, yo he utilizado el componente FileUpload que viene con los controles de servidor. Cuando se pulsa el botón de subir el archivo, se ejecuta el siguiente código, en el que se realizan las siguientes acciones:
  • Se comprueba que la extensión sea pdf
  • Se comprueba que el tamaño no exceda los 10MB (estoy hay que configurarlo en el web.config para que el servidor lo admita)
  • Se sube el fichero con un nuevo nombre único
  • Se encripta el fichero

















La línea clave es objencriptador.EncriptarFichero(), ¿qué es lo que hace esta función? Esta función es la encargada de encriptar el fichero pasado en el primer parámetro, guardarlo con el nombre del segundo parámetro y eliminar el original.





















Este método se encuentra en una clase llamada Crypto.cs que utiliza otra llamada CryptoProvider.cs que se encarga de inicializar el proveedor de encriptación. Hay que tener en cuenta que el algoritmo Rijndael se basa en dos cadenas: la clave y el vector de inicialización. Ambos valores se guardan en el app.config de la clase de negocio o se codifican en la clase. Al inicializar el proveedor Rijndael, ambos valores son pasados a su constructor para que pueda encriptar y desencriptar.

En este método, lo que se hace es abrir dos streams, uno para la entrada y otro para la salida. Seguidamente se inicializa el proveedor de servicios de encriptación con la clave (Key) y el vector de inicialización (IV), en modo encriptación. Una vez inicializado, el siguiente paso es crear un stream encriptado para ir pasando del fichero de origen al destino. Pasamos la información de un fichero a otro a través del CryptoStream, cerramos todos los flujos y eliminamos el fichero original.

Ya está encriptado, ¿cómo lo ve el usuario?
Ya tenemos el fichero encriptado en el servidor, por lo que el siguiente paso será desencriptarlo cuando haya que hacerlo sin dejar copia en el servidor. Para ello nos vamos a crear una página aspx que devuelva un flujo desencriptado al explorador del usuario.










En el momento que queramos descargar/visualizar el fichero desencriptado, la página en la que nos encontremos invocará a la página ObtenerPDF.aspx que solicitará el fichero desencriptado a la clase Crypto.cs. Esta clase, devolverá un MemoryStream desencriptado que será devuelto al explorador del cliente (junto con las cabeceras necesarias) para que sea renderizado en pantalla.















En mi caso, miro el fichero a desencriptar de la sesión del usuario. Habría que comprobar la seguridad para evitar accesos indebidos. Una vez obtenido el fichero, invocamos al método DesencriptarFichero() de la clase Crypto, que devuelve un objeto del tipo MemoryStream. Ese objeto es devuelto en el Response de la página para que el cliente lo muestre en pantalla.

El método DesencriptarFichero realiza las operaciones inversas que se realizaron en el método de encriptación.





















Con esto tenemos ya listo nuestro sistema de encriptación/desencriptación de ficheros en servidor. Tened en cuenta que esta solución es para entornos de hosting remoto en los que no tenemos capacidad de tocar el sistema de archivos. Si el servidor es nuestro, existen otras alternativas como la reubicación en carpetas fuera del directorio web, u otras.

Conclusión
Como siempre, espero que os haya interesado este post. En este caso, el código que he puesto es solamente el de las clases Crypto y CryptoProvider. Cada caso es particular así que cada uno adaptará la solución a su entorno. En este artículo he intentado dar unas guías para que podáis de una forma "fácil" incluir la encriptación en vuestros desarrollos asp.net.