Impresiones de la DjangoCon Europe 2011

He tenido el placer de poder asistir a la DjangoCon Europe que tuvo lugar en Amsterdam. En contra de lo que se puede suponer a priori, el viaje a Amsterdam fue de todo menos un viaje de ocio. Con decir que tuve que quedar con un español que vive allí, el futuro compañero de Yaco Danny Navarro, para visitar Amsterdam (bueno sólo ir a ver algunos escaparates, sin comprar nada por supuesto que hay crisis ;)

En fin, que me lo pasé en grande con casi 200 geeks que asistían a la conferencia (cinco de ellos españoles :). Bueno, en realidad sólo me lo empecé a pasar bien a partir del lunes por la tarde, una vez había dado mi charlita de 10 minutos sobre Merengue (transparencias en HTML5 aquí), dentro de charla 3 CMSs in 45 minutes. Hasta entonces sólo había sido un cúmulo de nervios y de trabajo de preparación, debido a mi mal inglés. Menos mal que al parecer salió bien la cosa y a muchos le gustó Merengue.

Con respecto a la primea DjangoCon de 2008, a la que asistí con Marc García, ha habido muchas diferencias. El sitio no era GooglePlex, cierto es, pero también es cierto que... We conquered the Castle! En serio, la gran mayor diferencia que veo es que se nota estos tres años de alto crecimiento de Django y sobre todo tres años de recorrido de muchas empresas, organizaciones e individuos que han ido creciendo alrededor, y todos encantados de su experiencia.

No sabía que sitios como Prezi era Django, así como todas las webs que se están haciendo en Mozilla, como la de addons (código liberado en github), como la famosa que recogía las descargas en tiempo real del FF4. Por ejemplo la de addons recibe más 500 millones de peticiones a su API para la comprobación de nuevos addons y temas similares. También los chicos de bitbucket,org lo hacen todo con Django. Muchas webs e iniciativas exitosas son en Django: djangozoom, ep.io, disqus, etc. etc. En 2008 sólo teníamos un par de referencias como Pownce. Por cierto, allí de nuevo estaba la guapa Djanguera Leah Culver, co-desarrolladora de Pownce (ahora no existe).

Estos tres años han dado además para encontrar un sin fin de código liberado para Django que era el topic de las charlas o se usaban en los proyectos mencionados anteriores. Estos proyectos ni se intuían hace tres años y algunos tampoco los conocíamos antes de las conferencias (estaban en un github perdido). Cito algunos ejemplos:

  • Celery, para tareas asíncronas (usado en Yaco con éxito).
  • Fiber, un set de funcionalidades de CMS para añadir a tu proyecto Django, presentado por Dennis, una gran persona.
  • Django-qunit, para integración de django y qunit, que permiten hacer tests en Javascript. Se pueden ejecutar en varias máquinas usando jstestnet.
  • django-cache-machine, basado en el antiguo django-caching, que es una alternativa menos mágica a Johnny-cache.
  • django-waffle, para hacer test AB según ciertos flags activos o no.
  • django-bleach, para evitar ataques de inyección de Javascript.
  • django-queryset-transform, que permite evitar consultas SQL tomando el control del ORM, para cuando el select_related es insuficiente.
  • django-nani, para traducción de modelos usando la aproximación en dos tablas, como hacía django-multilingual pero mucho mejor que este último. En merengue se usa django-transmeta, que se basa en una tabla con columnas para cada idioma.
  • django-qmixin que permite una personalización elegante de tus managers y querysets.
  • django-rest-framework, que parece mejor pensado que django-piston. Es curioso como a la gente no le termina de convencer django-piston y están tomando otros productos, aunque dicen los de bitbucket que van a sacar una mejor versión pronto. El producto que al parecer está más de moda es django-tastypie, que tiene sin duda la mejor documentación de todos.
  • kong para testing funcional cuando Selenium se convierte en un cañon para matar moscas (depende de la naturaleza de la web que programes).
  • dagny, o como aprovechar el REST para mejorar la estructura y reutilización de tu código. Esta es otra gran alternativa a django-piston pero además te cambia el modelo de como programar. Un modelo elegantísimo.
  • etc.

Por otra parte, como ya le pareció a Loren en la PyCon, veo que estamos haciendo las cosas bien, tanto en desarrollo como en despliegue. Para integración continua usan Jenkins, como estamos empezando a usar nosotros. Otros usan bamboo. Para creación de máquinas y mantenimiento usan puppet y chef. Muchos usan la nube para ello.

Aunque todas estuvieron interesantes, voy a destacar algunas charlas especialmente:

  • La lightning talk de PyCharm. Es sin duda el mejor IDE Django que hay. Permite autocompletado de todo, incluyendo dentro de las plantillas Django (carga de librerías, expresiones, filtros, ¡todo!). Lo único malo es que tarda mucho en cargar por el análisis que hace al proyecto que carga. Como curiosidad el desarrollador principal es un geek superdotado que entró a la universidad con 15 años (y se arrepiente mucho de ello).
  • Muy interesante la charla de compass y less y del responsive web design.
  • La charla de django on rails que trata de como aprender del modelo restful de Rails y aplicarlo a Django. El resultado es dagny, mencionado antes.
  • La charla de reusable apps using "eicht spaces", me parecío como analizaba el problema del import circular en Django y permitía un diseño de vistas que dejaba mucha mayor reutilización. Permite por ejemplo que puedas extender el modelo de una aplicación en una segunda aplicación que sea el modelo que usa la primera aplicación, pero sin el problema del import circular que es el que saldría si intentaras hacerlo sin un artefacto ingenioso como "eicht spaces".

Otra cosa interesante fue ver a Reinout van Rees escribiendo los artículos de blog de las charlas que iba viendo en tiempo real como si de una taquígrafa se tratara. ¡Very cool!

Por último los Sprints. Fueron en el castillo de De Waag, y la verdad es que pasamos un rato agradable. Yo estuve con Samuel Fuentes, el único de los españoles que se quedó a los sprints. La verdad es que sólo trabajé sprintando en Django unas 5-6 horas, en las cuales metí mano a 3-4 tickets del trac de Django. El resto estuve también ayudando a gente, desarrollando con Merengue, preparando el sprint de la EuroPython, contestando correos, redactando documentación de Yaco, etc.

Al final llegó Danny Navarro y pasamos un buen rato de charla juntos hasta las 1 y pico de la mañana.

En fin, unas conferencias magníficas, la gente estupenda, una organización increíble, pendiente de los asistentes en cada momento, con buena comida (el queso genial), mejor cerveza belga. Eso sí, hay algo que fallo en la DjangoCon Europe... faltó Cal Henderson

Distributing a python application to MacOS X

Today I needed to create an app file for MacOS X with a simple Python script. This is what I learned:

  • Use py2app, it's your friend
  • After installing py2app with easy_install you need to fix it. Otherwise it may not work for your hardware architecture. See Section 2 of this blog post
  • Now, you can safely run python setup.py py2app and you will get a file with the .app extension in the dist directory
  • When you install that (copy into your Applications folder) and try to run it you will get this error (open the Console or do a tail -f /var/log/system.log) to see the error:

22/03/11 10:33:21    com.apple.launchd.peruser.502[580]    ([0x0-0x98098].org.pythonmac.unspecified.myscript1613]) Exited with exit code: 255
22/03/11 10:34:53    [0x0-0x9b09b].org.pythonmac.unspecified.myscript[1645]    Traceback (most recent call last):
22/03/11 10:34:53    [0x0-0x9b09b].org.pythonmac.unspecified.myscript[1645]      File "/Applications/xml2rfc.app/Contents/Resources/__boot__.py", line 103, in <module>
22/03/11 10:34:53    [0x0-0x9b09b].org.pythonmac.unspecified.myscript[1645]        _argv_emulation()
22/03/11 10:34:53    [0x0-0x9b09b].org.pythonmac.unspecified.myscript[1645]      File "/Applications/xml2rfc.app/Contents/Resources/__boot__.py", line 101, in _argv_emulation
22/03/11 10:34:53    [0x0-0x9b09b].org.pythonmac.unspecified.myscript[1645]        _get_argvemulator().mainloop()
22/03/11 10:34:53    [0x0-0x9b09b].org.pythonmac.unspecified.myscript[1645]      File "/Applications/xml2rfc.app/Contents/Resources/__boot__.py", line 40, in mainloop
22/03/11 10:34:53    [0x0-0x9b09b].org.pythonmac.unspecified.myscript[1645]        stoptime = Evt.TickCount() + timeout
22/03/11 10:34:53    [0x0-0x9b09b].org.pythonmac.unspecified.myscript[1645]    AttributeError: 'module' object has no attribute 'TickCount'

In order to avoid it you need to use a different Python from your system Python. In my case it only worked with a 32 bits Python like python-2.7.1-macosx10.3.dmg

Once you have the script installed you can run it from the shell in /Applications/myscript/MacOS/myscript.py

For the record, this is my setup.py file:

import sys
from setuptools import setup

mainscript = 'myscript.py'

if sys.platform == 'darwin':
    extra_options = dict(
        setup_requires=['py2app'],
        app=[mainscript],
        # Cross-platform applications generally expect sys.argv to
        # be used for opening files.
        options=dict(py2app=dict(argv_emulation=True)),
        )
elif sys.platform == 'win32':
    extra_options = dict(
        setup_requires=['py2exe'],
        app=[mainscript],
        )
else:
    extra_options = dict(
        # Normally unix-like platforms will use "setup.py install"
        # and install the main script as such
        scripts=[mainscript],
        )

setup(
    name='myscript',
    version='0.1.0',
    **extra_options
)

It's taken from a py2app example

Primeros pasos con Merengue en Django 1.3

La versión 0.8 de Merengue va a centrarse en mayor medida en tener un CMS production ready para grandes portales web, con una carga dinámica importante y un número de peticiones elevados.

Una de las acciones a tomar será compatibilizarlo con la versión 1.3 de Django, ya que, sobre todo a partir de la versión 1.2, se han realizado muchas mejoras en rendimiento, escalabilidad, robustez y seguridad. Así, compatibilizarlo con Django 1.3 (hasta ahora usaba Django 1.1) es una de las mejores formas de preparar Merengue para grandes webs.

Las mejoras que dispondríamos relativas a estas cuestiones serían:

  • ORM multidatabase. Con poco esfuerzo puedes tener varias bases de datos configuradas en cluster.
  • Caché de plantillas. La página inicial de Merengue, cuando entramos como un usuario autenticado, nada más instalar Merengue, renderiza ni más ni menos que 87 plantillas, pero tenemos casos de proyectos con vistas que renderizan hasta 206 plantillas. Estos números no son habituales en aplicaciones web ad-hoc, pero Merengue es un CMS pluggable de propósito general. El número es tan elevado porque:
    • Merengue renderiza las páginas a partir de elementos pequeños (bloques, acciones, viewlets, etc.) que pueden ser movidos configurados y desactivados por el gestor. Esta flexibilidad casi infinita tiene el inconveniente de renderizar los fragmentos de la página de forma separada, lo cual también es bueno para permitir que los desarrolladores integren sus plugins.
    • Merengue usa bastante la herencia de plantillas, por ejemplo para su sistema de temas (theming) y para los bloques. Por ejemplo cada bloque suele heredar de una plantilla padre que incluye herramientas para gestionarlos, moverlos, configurarlos, etc.
  • Protección contra ataques CSRF, para evitar que otras webs hackeadas puedan alterar datos de la nuestra.
  • Claves naturales en Fixtures, perfectas para mejorar el deployment. Por ejemplo para exportar automáticamente la configuración de un sitio Merengue (con el tema activo, los bloques, plugins activados, configuración, etc.) e importarlos en otro sitio distinto.
  • Uso de Model.objects.only(...), para seleccionar campos sueltos de las tablas, y no tener que cargar toda la tabla completa para cuando listas solo un par de campos en ella. Esto puede ser muy útil por ejemplo para las colecciones, ya que si el gestor define los campos que muestra, ¿para qué tener que obtener todos los demás si nunca van a salir?
  • Framework para Logging (1.3), que ya era hora de que se incluyera en este framework. Así evitamos el estar poniendo print y podemos configurarlo para enviar entrada a fichero, email, etc.
  • Ficheros estáticos (1.3). En Django 1.3 se distinguen los ficheros subidos por los usuarios de los servidos por el sistema. También hay herramientas de sincronización al directorio que sirve el servidor web usado. Merengue también tiene funcionalidades que equivalen a las de Django (y las superan en algunos casos), con los que habrá que pensar más tranquilamente como unir los caminos.

Pues bien, ya hemos empezado el trabajo de compatibilizarlo con Django 1.3, realizado en una rama aparte de código y las noticias son muy buenas... tan buenas... que puedo decir que tras unas 6 horas de trabajo la tarea está casi concluida. Falta probarlo bien y corregir los problemillas que surjan, pero tras múltiples refactorizaciones, fallitos corregidos, pruebas y pruebas, casi está listo (el trabajo se puede ver en el ticket #1568).

Benchmarkings preliminares

Lo primero que he realizado tras comprobar que funciona bien han sido pruebas de carga simples, comparando Merengue (rama trunk/) + Django 1.1 y Merengue (rama django1.3_compat) + Django 1.3, con y sin caché de plantillas habilitado (usando caché de memoria local).

Aquí los resultados:

  • Merengue con Django 1.1:
    • Vista con 87 plantillas: 2.85 [#/sec]
    • Vista con 209 plantillas: 1.20 [#/sec]
  • Merengue con Django 1.3:
    • Vista con 87 plantillas, sin cache: 2.88 [#/sec]
    • Vista con 87 plantillas, CON cache de plantillas: 6.35 [#/sec]
    • Vista con 209 plantillas, sin cache: 1.06 [#/sec]
    • Vista con 209 plantillas, CON cache de plantillas: 6.35 [#/sec]

 

 

Conclusiones del benchmark:

  • La caché de plantillas aumenta drásticamente el rendimiento de un sitio.
  • Cuanto más plantillas renderiza una vista, más se nota el aumento de rendimiento. De hecho en las pruebas se ve que se consiguen los mismos resultados con 87 plantillas y con 206, lo que denota que el tiempo de localizarlas en el sistema de ficheros y compilarlas es mucho más importante que el tiempo de renderizado de las mismas.

EasyTrac, un despliegue automatizado de Trac.

Como ya comenté en posts anteriores, en Yaco Sistemas trabajamos a diario con Trac, todas nuestras tareas están en Trac, incluyendo documentación de proyectos, etc; en Yaco Sistemas no eres nadie si no creas una wiki ;-)

Eso está muy bien, ¿pero qué es easyTrac?

EasyTrac es un instalador basado en zc.buildout que despliega un entorno de Trac de forma automatizada incluyendo dependencias necesarias.

Este instalador no solo puede ser utilizado para desarrollo sino que también podría utilizarse en un sistema de producción ya que los proyectos de Trac se despliegan bajo Nginx y uWSGI, con lo que tendremos un sistema bastante rápido, estable y liviano en nuestro sistema.

Si es cierto que para poder compilar Nginx y uWSGI, es necesario que se encuentren ciertas librerias de desarrollo en el sistema, por lo que deberemos tener instalados los siguientes paquetes en nuestro sistema:

  • libpcre3-dev
  • libssl-dev
  • libxml2-dev
  • libxslt-dev
  • libsqlite3-dev
  • libzzip-dev
  • libapr1-dev
  • libaprutil1-dev
  • python-dev

Me parece correcto... ¿pero de dónde me lo descargo?

Puedes descargarlo de forma comprimida tanto en formato zip como en formato tar.gz.

O si lo prefieres, puedes hacer un clone con Git de mi repositorio en Github ejecutando lo siguiente:

$ git clone git://github.com/mviera/easyTrac

Vale, ya lo tengo ¿y ahora cómo lo instalo?

EasyTrac se puede instalar tanto como root como con cualquier usuario sin privilegios, ya que la instalación no interferirá para nada en nuestro sistema. Personalmente, prefiero instalar con un usuario sin privilegios.

El instalador de easyTrac funciona sin tener que hacer ninguna modificación en la configuración, pero si quieres personalizar la configuración, puedes editar el fichero buildout.cfg y modificar alguno de los siguientes parámetros:

  • nginx-http-port: puerto utilizado por Nginx para escuchar las peticiones vía http.
  • nginx-https-port: puerto a través del cual Nginx escuchará las peticiones vía https (en caso de que quieras usar https).
  • supervisor-http-port: puerto utilizado por Supervisor.
  • host: IP del host o FQDN (Fully Qualified Domain Name)
  • socket-directory: directorio donde se almacenarán los sockets.
  • pid-directory: directorio donde se alojarán los ficheros pid.
  • log-directory: directorio de logs.
  • trac-projects-directory: directorio donde se crearán los proyectos de Trac. Por defecto este directorio es <installdir>/opt/trac/.
  • svn-repository-directory: directorio donde se crearán los repositorios de código SVN. Por defecto, este directorio es <installdir>/opt/svn/.

Una vez instaladas las anteriores dependencias, y configurados los parámetros de configuración, en caso de que quisieras personalizarlos, podemos seguir con la instalación, así que ejecutaremos lo siguiente:

$ python bootstrap.py

Con esto prepararemos el entorno y una vez hecho, podremos lanzar la instalación ejecutando lo siguiente:

$ ./bin/buildout

Comenzará el proceso de compilado de Nginx y uWSGI; y la instalación de los módulos de Python necesarios. Además, easyTrac compila Subversion e instala los bindings necesarios para que Trac pueda enlazarse con repositorios de código SVN.

He ido a por un café y al volver ya estaba instalado ¿ahora qué hago?

EasyTrac incluye la instalación de Supervisor. Pero ¿qué es Supervisor? Es un sistema de control de procesos que nos va a permitir arrancar, parar y reiniciar cada uno de nuestros servicios. En easyTrac tendremos dos servicios: Nginx yuWSGI.

La sintaxis de uso de Supervisor es la siguiente:

$ ./bin/supervisorctl

Por lo tanto si quisiéramos iniciar el servicio Nginx, ejecutaríamos lo siguiente:

$ ./bin/supervisorctl start nginx

En caso de querer pararlo, ejecutaremos:

$ ./bin/supervisorctl stop nginx

Y si quisiéramos reiniciarlo:

$ ./bin/supervisorctl restart nginx

Supervisor incluye una palabra especial llamada all que hace referencia a todos los servicios configurados en supervisor. Con ella podremos controlar todos los servicios al mismo tiempo. Por ejemplo, si quisiéramos reiniciar todos los servicios, ejecutaríamos lo siguiente:

$ ./bin/supervisorct restart all

Pero esto no es todo, es que además Supervisor, por si fuera poco, incluye una interfaz web desde la que podemos controlar nuestros servicios. Podremos acceder a ella accediendo a

http://localhost:9000

Por defecto, el usuario es admin y la contraseña es admin. (nótese el punto al final de admin). Es posible cambiar estos datos editando la parte [supervisor] en el fichero buildout.cfg y volveremos a ejecutar la instrucción./bin/buildout

Ya tenemos nuestro entorno listo y accederemos a él a través de

http://localhost:8080

¡Qué bien! ¿y ahora cómo creo un Trac?

Tranquilos, la creación de un proyecto Trac es muy sencilla. Utilizaremos el binario trac-admin creado por el instalador, y que se encuentra en el directorio bin/.

Crearemos un proyecto llamado demo, por lo que ejecutaremos lo siguiente:

$ ./bin/trac-admin opt/trac/demo initenv demo sqlite:db/trac.db

Y ya que estamos, vamos a crear un repositorio SVN con el mismo nombre. Para ello utilizaremos el binario llamadosvnadmin que podremos encontrar también en el directorio bin/.

$ ./bin/svnadmin create opt/svn/demo

Fiuf! ahora solo falta que pudiera hacer backups de mis Tracs

Aunque no es una solución feténica, easyTrac cuenta con un comando backup con el que podremos comprimir nuestros proyectos y guardarlos en otra localización. Para ello, simplemente ejecutaremos la siguiente instrucción:

$ ./bin/backup

y todos los proyectos Trac serán comprimidos y guardados en un directorio llamado backups/.

Vale, tengo backups, quiero restaurarlos ¿cómo lo hago?

Tan simple como ejecutar lo siguiente:

$ ./bin/restore backups/backup-file.tar.gz

y todos los tracs serán restaurados automáticamente en el directorio, por defecto, opt/trac/.

No me convence. Quiero desinstalarlo.

Solamente es necesario parar todos los servicios:

$ ./bin/supervisorctl shutdown

y borrar el directorio de instalación:

$ rm -rf easyTrac

And that's all folks!!! ;-)

Un saludo!

via blog.manuelviera.es

 

Crontab

Hoy trabajando en Yaco Sistemas he aprendido algo nuevo sobre cron. Seguramente muchos de los que os moveis entre GNU/Linux y similares, conoceréis el demonio cron.

Cron es un planificador de tareas que nos permite ejecutar una tarea en un momento determinado en el tiempo. La sintaxis para configurar una tarea cron es la siguiente:

.---------------- minuto (0 - 59)
|  .------------- hora (0 - 23)
|  |  .---------- día del mes (1 - 31)
|  |  |  .------- mes (1 - 12)
|  |  |  |  .---- día de la semana (0 - 6) (Domingo=0)
|  |  |  |  |
*  *  *  *  *  comando para ser ejecutado


De esta forma, imaginad que queremos apagar nuestro ordenador los sábados a las 21:30h, configuraríamos una tarea cron de la siguiente forma:

30 21 * * 6 /sbin/shutdown -h now


Podemos planificar tareas para un usuario utilizando el comando crontab:
crontab -l Lista las tareas cron para el usuario actual.
crontab -e Permite configurar una tarea cron para el usuario actual. Se abrirá el editor de texto configurado por defecto en el sistema.
crontab -r Elimina las tareas cron configuradas en el usuario actual.
crontab -v Muestra la última vez que se editó crontab del usuario actual.

La verdad es que no parece una sintaxis muy complicada pero a mi, personalmente, siempre se me olvida.

Como os decía al principio, hoy he descubierto los horarios predefinidos en crontab gracias a ant30. Estos horarios predefinidos son unos valores que se pueden usar para sustituir la sintaxis de las expresiones anteriores. Estos valores predefinidos son:

@yearly Se ejecuta una vez al año. Equivalente a 0 0 1 1 *
@annually (igual que @yearly). Equivalente a 0 0 1 1 *
@monthly Se ejecuta una vez al mes. Equivalente a 0 0 1 * *
@weekly Se ejecuta una vez a la semana. Equivalente a 0 0 * * 0
@daily Se ejecuta una vez al día. Equivalente a 0 0 * * *
@midnight (igual que @daily). Equivalente a 0 0 * * *
@hourly Se ejecuta una vez cada hora. Equivalente a 0 * * * *
@reboot Se ejecuta en el arranque y al reiniciar.

El que yo he utilizado hoy ha sido @reboot que me permite ejecutar un comando cuando arranca el sistema. En mi caso quería que cada vez que se arranque el sistema, se iniciara un servicio desplegado con el usuario en cuestión. Gracias a @reboot no tengo que crear un script en /etc/init.d/ y activarlo en el arranque ;-)

Un saludo!

Publicado Merengue 0.6.0

Tras más de 300 tickets cerrados y dos meses de trabajo, se ha publicado la versión 0.6.0-final de Merengue, disponible en Pypi.

Esta versión final supone la corrección de muchos errores, y sin ningun cambio funcional desde la versión 0.6.0-alpha, y pensamos está lista para su uso en webs de producción. Para el que no conozca el proyecto, recomiendo echar un ojo al overview de Merengue y entrar en la web de demostración

Algunos enlaces de interés:

Gracias a todo el equipo de Merengue, gracias a ellos el proyecto Merengue se ha hecho realidad.

Aplicaciones Django interesantes

He hecho un recorrido por el estado de algunas aplicaciones que conocía y ver otras muchas nuevas, para ver la posibilidad de integración en Merengueo en otros proyectos Django.

Para que no se quede sólo en mi cabeza os listo las que he visto más interesantes:

  • django-attachments: para crear adjuntos a cualquier modelo de forma no intrusiva (usando generic FK). Tiene:
    • un InlineModelAdmin para poder poner adjuntos en cualquier ModelAdmin que tengamos.
    • una serie de templatetags para poner enlaces a los attachments.
  • django-mediasync: para poder desarrollar con los media local, pero sincronizar con CDNs como S3 o Rackspace estando en producción, y permitiendo en la sincronización hacer cosas como comprimir CSS y JS, versionar imágenes para permitir un cacheo mucho más agresivo, etc. Creo que debemos integrarlo en Merengue.
  • django-announcements: para anunciar algo a todos los que entren en la web, o sólo a los miembros de la misma. Son anuncios como "nueva version de la web" o "mañana a las 12 habrá un corte en la web por motivos de mantenimiento". Creo que va a ser necesario para la UMA por lo que será incluido en Merengue.
  • django-uni-form, para normalizar presentación de formularios como <div> ya bien maquetados. Poniendo un simple {{ my_form|as_uni_form }} y incluyendo unos ficheros css ya preparados, tenemos unos formularios perfectos. Esto es útil para usarlo en todo proyecto que hagamos. Además permite una personalización del layout, que viene en la documentación.
  • django-frontendadmin, aplicación que permite editar el contenido en la misma página que lo ves, como nuestra inlineeditforms, pero que te muestra el formulario de edición al completo en lugar de ir editando haciendo click en el campo concreto que quieres cambiar. Puede ser útil en algunos proyectos concretos, pero creo que Merengue irá mejor si la edición es en el admin (o en el caso de la UMA Victoriano quiere los inlineeditforms).
  • django-sorting, aplicación para que el usuario pueda ordenar listados pinchando en las cabeceras de las tablas. Está hecho como django-pagination, con lo que un simple middleware y poco más se necesita para echarlo a andar, cosa que se agradece.  Se integrará con las colecciones de Merengue (en versión 0.8).
  • django-email-confirmation, para cuando necesitas verificar el correo de un cliente, para cualquier parte de la lógica de tu sistema.

 

Contribución a Trac

En Yaco Sistemas utilizamos Trac en cada uno de nuestros proyectos de desarrollo y para los que no son de desarrollo también. Trac se ha convertido una herramienta fundamental para nosotros, tanto, que sin ella nos sería mucho más complicado trabajar.

Ayer nos surgió una nueva necesidad en el Trac de uno de nuestros proyectos. Os pongo un poco en situación.

En Trac cuando se crea un ticket, normalmente lo crea una persona y es posible asignarlo a otra. En este caso, y si estuviese configurado, es posible notificar vía email tanto al creador del ticket (reporter) como a la persona a la que se le ha asignado el ticket (owner) de la creación del ticket y de las posteriores modificaciones en éste.

En la documentación de Trac referente a las notificaciones podemos ver que existen tres opciones:


  • always_notify_owner: si se establece como true, cualquier modificación en el ticket se envía al owner del ticke
  • always_notify_reporter: si se marca como true, cualquier modificación es enviada al reporter del ticket.
  • always_notify_updater: si se configura a true, se envía una notificación a la persona que ha modificado el ticket y a cualquier persona que haya modificado anteriormente el ticket.

Nuestra nueva necesidad consistía en que se notificase por correo al reporter de un ticket solamente cuando el ticket fuera cerrado, y no con cada una de las modificaciones del ticket. Con la opción always_notify_reporter no es posible, ya que se envían todas las modificaciones del ticket o ninguna, dependiendo si está o no activada esta opción en la configuración de nuestro Trac.

Busqué en la documentación de Trac a ver si había posibilidad de hacer esto. También busqué alguna otra posible solución en internet, pero no encontre nada.

En ese momento decidí ver si era posible crear yo mismo dicha funcionalidad. Así que he desarrollado una nueva opción llamada always_notify_close_reporter la cual, si establecemos a true, solamente notificaremos al reporter cuando el ticket se cierre, evitando que le lleguen correos con cada una de las modificaciones del ticket.

Creé el parche y decidimos abrir un ticket en Trac [1] para compartirlo con la comunidad. A ver si hay suerte y lo incluyen en el código de Trac :-)

[1] http://trac.edgewall.org/ticket/9977

Esto es lo bonito del software libre :-)

Un saludo.

Migración de una base de datos postgresql a una nueva versión postgis

Mi problema en concreto, era que no podía cargar una base de datos postgresql de un sistema con postgis1.3 a un sistema con postgis1.5. Uno de los muchos errores, era que no encontraba la liblwgeom.so.

La solución es usar el script new_postgis_restore.pl. El mismo comando al ejecutarlo sin parámetros, indica los pasos a seguir:

Usage: /usr/share/postgresql-8.4-postgis/utils/new_postgis_restore.pl <dumpfile>
 Restore a custom dump (pg_dump -Fc) of a PostGIS-enabled database.
First dump the old database: pg_dump -Fc <olddb> > <olddb.dmp>
Then create a new database: createdb <newdb>
Then install PostGIS in the new database: psql -f <path>/postgis.sql
Finally, run this script on the old dump: /usr/share/postgresql-8.4-postgis/utils/new_postgis_restore.pl <olddb.dmp> | psql <newdb>

 

 

 

Laboratorio Andaluz de Android

La semana pasada, el día 28 de Octubre tuvo lugar el primer laboratorio andaluz de android.

Las distintas ponencias estuvieron muy muy interesantes, ya que no fueron sólo técnicas, sino que tocaron varias áreas como la usabilidad y la rentabilidad de las aplicaciones android. 

Hoy he encontrado un hueco para rescribir las notas que tomé, he apuntado lo más interesante desde mi punto de vista, seguramente me deje muchas cosas en el tintero.

Previa presentación de Dª. Laura Martín (Directora del Centro de Formación en Comunicaciones y Tecnologías de la Información), la jornada empezó con la ponencia de Antonio Carabantes CEO de androisis.com. Lo primero que comentó fueron las desventajas que actualmente sufre android:
  • Las distintas versiones de las sdk provocan incompatibilidades hacia atrás, hacen que las apps no estén disponibles para todos los dispositivos. Cada uno puede tener versiones de android distintas, y además algunas operadoras modifican las interfaces haciéndolas más incompatibles.
  • El buscador del market deja mucho que desear, tienes que poner exactamente el nombre de la aplicación para encontrarla.
  • La instalación de las aplicaciones se realizan en la memoria interna en lugar de la sd card que es menos limitada. Sin embargo parece que esto está solucionado en la versión 2.2
  • No hay un buen feedback de reporte de errores de las aplicaciones a sus desarrolladores, por lo que la aplicación puede estar fallando y su creador no se entera.
  • La única forma de pagar las aplicaciones es mediante google checkout. Parece que se está resolviendo y en breve se podrá pagar mediante paypal. 
También habló de las ventajas (algunas por comparación con otras plataformas):
  •  Los desarrolladores pagan 25 dólares una sola vez para poder subir sus aplicaciones al market.
  •  El lenguaje de programación es java, la curva de aprendizaje para un programador con conocimientos medios en este lenguaje es baja.
  •  El usuario que compra una aplicación tiene 24 horas para devolverla con su correspondiente reembolso. Esto, sin embargo, no es una ventaja para el desarrollador.
  •  El 70% de los beneficios son para el desarrollador.
  •  Acceso a las herramientas de desarrollo nativas ndk.
  •  El flujo para subir una aplicación al market es más rápido y menos restrictivo.
  •  Aunque no llega a ser abierto del todo, es uno de los menos restrictivos.
  •  Es un sistema que permite integrarse en muchos tipos de dispositivos: televisiones, lavadoras, microndas, etc.
Antonio citó varios modelos de negocio para rentabilizar las aplicaciones:
  • Aplicaciones gratuitas con publicidad.
  • Aplicaciones de pago.
  • Aplicaciones gratuitas para versiones reducidas y de pago con funcionalidades adicionales.

El modelo menos interesante es el de pago, ya que sólo se pueden vender en 32 países, mientras que con la app store de apple se puede vender en 90. Por ello Rovio, la empresa creadora del exitoso juego "angry birds" ha decidido usar en el market de android el modelo de aplicación gratuita con publicidad. 

Llegó el turno de Juan Carlos Viota CEO de Inizziativa Networks:
  • Hizo un repaso del crecimiento emergente de android, mostrando finalmente una estadística predictiva de un crecimiento del 325% para el 2014 convirtiéndose en la plataforma número 1.
  • Destacó que gran parte de la culpa del crecimiento en general de los dispositivos móviles, la tenían las redes sociales.
  • Las aplicaciones no sólo muestran información sino que ahora pueden jugar con el entorno para crear realidad aumentada. Puso como ejemplos la aplicación de ikea que coloca cualquier elemento de su catálogo en el salón de tu casa y navigator de google.
  • Cita también los modelos de negocio, añadiendo a los ya comentados por Antonio, el desarrollo de aplicaciones corporativas personalizadas que no pasan por el market.
  • Recalcó la dependencia que antes sufría el desarrollador, que tenía que realizar n desarrollos para n dispositivos y ahora sólo realiza un desarrollo que puede desplegar en distintos dispositivos. 
  • Antes el desarrollador necesitaba estar en una gran empresa para poder distribuir el software en paquetes en las grandes superficies. Ahora, el solo puede crear una aplicación en su casa y por medio de las apps stores puede venderla en multitud de países, sin moverse del sitio.
Siguió con una serie de consejos a la hora de desarrollar:
  • El desarrollo en dispositivos móviles no es un desarrollo en una resolución menor, hay que buscar las posibilidades que ofrece el dispositivo al interactuar con el entorno.
  • Hablando de respetar el entorno, no tiene sentido hacer una aplicación para registrar ejercicio físico en el ipad.
  • Regla del pulgar: no colocar el menú arriba, mejor abajo, cuesta trabajo llegar cuando se coge el móvil con una sola mano. En el caso del ipad aprovechar los laterales para introducir botones y menús, ya que la forma de cogerlo hace más fácil acceder a ellos.
  • En la aplicación GolfPlay hicieron los botones grandes para que la gente cuando esté jugando al golf pueda usar la app con guantes.
  • Usar los servicios de la nube. Los usuarios tienen muchos dispositivos y no quieren estar continuamente replicando la información.
  • Hacer un buen uso de la caché. En el caso de una aplicación de golf, el móvil no tiene espacio para guardar todos los campos, cachea solo 3 o 4 y los vas sustituyendo.
  • Dar prioridad al feedback del usuario. El 40% de las novedades de SweetDreams vinieron de las sugerencias de los usuarios.
  • Promoción. La aplicación por muy buena que sea no sirve para nada si no la das a conocer.
Termina la charla con dos puntos muy interesantes:
  • Es muy difícil pronosticar si realmente android o cualquier otro sistema será el sistema para dispositivos móviles del futuro. Gartner siempre se equivoca en sus estimaciones.
  • El futuro está en html5, es la piedra rosetta que será capaz de hablar con todo.

La siguiente ponencia fue de Jose Emilio Villena, CEO de Alea Technology. Fue más técnica, explicó la estructura básica que debe tener un proyecto android y los componentes a partir de los cuales se construye una aplicación. Muy resumidamente (perdonadme si cometo algún error) algunos de los componentes más importantes son:
  • Activities: cada pantalla que se muestra en una app es una activity, sólo puede mostrarse una a la vez. Al llamarlas pasan al primer plano, y van apilándose de forma que puedas volver hacia atrás.
  • Intents: son los encargados de encadenar las activities y realizar el paso de información entre ellas.
  • ContentProviders: como su nombre indica son proveedores de contenidos a los que puede acceder la aplicación, un ejemplo puede ser la lista de contactos.
  • Services: son procesos que se ejecutan en background.
Después habló de algunas herramientas para desarrollar como Eclipse + ADTDroidDraw para generar las interfaces xml, AppInventor para crear aplicaciones sin necesidad de programar o SQLite Database Browser para gestionar las bases de datos que usan las aplicaciones.

Finalmente Juan Carlos volvió para cerrar la jornada explicando en detalle el código de dos aplicaciones.

El nivel de las preguntas de los asistentes fue muy bueno, algunos ejemplos:
  • ¿Cómo se controlan las aplicaciones maliciosas que quieren hacer un mal uso de los datos de los móviles? El market al ser un sistema menos restrictivo es más fácil que ocurran estás cosas, la mejor forma de detectar estas aplicaciones maliciosas es por el feedback de los usuarios.
  • ¿Cúal es la mejor modelo de negocio? No hay uno mejor ni peor, todo depende de la aplicación y de la empresa. Inizziativa a hecho uso de I+D para crear SweetDreams y subirlo al market gratis y sin publicidad, el beneficio le ha venido por ganar un premio que ha publicitado la propia empresa.