Extendiendo manage.py para sincornizar con Flex
Estamos haciendo un sistema que tendrá como interfaces algunas pantallas en Flex por lo que ha surgido la necesidad de publicar algunos servicios remotos utilizando PyAMF. En Flex utilizamos Cairngorm como MVC, este requiere la definición de un archivo de servicios Services.xml que estoy intendando generar utilizando Python y que mejor que hacerlo utilizando el mismo estilo que utiliza DJango para la sincronización de la base de datos. Por ello estoy intenando generar una opción nueva el comando manage.py de la aplicación DJango:
manage.py syncflex
Gracias a la flexibilidad de DJango esto es bastante fácil nada más debes crear una clase que debes llamar Command que extienda a la clase BaseCommand y ubicarla en paquete managment/commands bajo alguna de tus aplicaciones en mi caso yo estoy haciendo un pequeño ERP así que la ubique en la ruta flex/managment/commands:

En mi caso dado que mi comando no tiene argumentos extendere la clase NoArgsCommand :
class Command(NoArgsCommand): help = "Sync Flex Commands" requires_model_validation = False def handle_noargs(self, **options): # Your code here
El método handle_noargs es el que nos permite ejecutar las acciones realizadas por nuestro comando cuando es invocado, en mi caso la implementación es la siguiente (algo básica por ahora):
def handle_noargs(self, **options): from pyamf.remoting.gateway.django import DjangoGateway import sys project = settings.ROOT_URLCONF.split('.')[0] #import types for app in models.get_apps(): if project == app.__name__.split('.')[0]: app_name = app.__name__.split('.')[-2] package = project + '.' + app_name + '.gateway' try: mod = __import__(package, globals(), locals(), ['gateway'], -1) for d in dir(mod): attr = getattr(mod, d) try: if isinstance(attr, DjangoGateway): self.processClass(d, attr) except TypeError: pass except ImportError: pass
Como se puede ver su funcionamiento se basa en introspección, para ello busco un módulo llamado gateway dentro de mis aplicaciones DJango una vez que encuentro el módulo busco en él las clases que extiendan a DjangoGateway para generar el archivo Services.xml. Un ejemplo de mi archivo gateway.py es:
from pyamf.remoting.gateway.django import DjangoGateway from django.contrib.auth.models import User from sampleapp.contabilidad.models import Comprobante from sampleapp.gateway.amf import AMFGateway class ComprobanteGateway(AMFGateway): def obtenerComprobantes(self, request, data): # Implemetnar pass class CuentaGateway(AMFGateway): def obtenerCuentas(self, request, data): # Implemetnar pass contabilidadGateway = DjangoGateway({'gwComprobante' : ComprobanteGateway, 'gwCuenta' : CuentaGateway,})
Si vemos la implementación del método processClass tenemos lo siguiente:
def processClass(self, name, gateway): import inspect print ("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" "<cairngorm:ServiceLocator xmlns:mx=\"http://www.adobe.com/2006/mxml\"" "xmlns:cairngorm=\"com.adobe.cairngorm.business.*\">\n") for g in gateway.services: print ("<mx:RemoteObject id=\"" + g + "\" " "\n\t\tdestination=\"" + g + "\" " "\n\t\tendpoint=\"" + settings.REMOTING_URL + "/" + name + "\" " "\n\t\tshowBusyCursor=\"true\" " "\n\t\tresult=\"event.token.resultHandler( event );\" " "\n\t\tfault=\"event.token.faultHandler( event );\">") service = gateway.services[g] for m in service.getMethods(): print "\t<mx:method name=\"" + m + "\" />" print "</mx:RemoteObject>\n" print "</cairngorm:ServiceLocator>"
Con eso ya estamos casí listos sólo nos falta agregar nuestra aplicación para que DJango la conozca y definir la variable REMOTING_URL para ello sólo editamos nuestro archivo settings.py:
INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.admin', 'sampleapp.contabilidad', 'sampleapp.compra', 'sampleapp.agricola', 'sampleapp.rrhh', 'sampleapp.maquinaria', 'sampleapp.comun', 'sampleapp.actividad', 'sampleapp.flex', ) # -------------------------------------------------- # My customs settings # -------------------------------------------------- REMOTING_URL = "http://localhost:8080/remoting"
Con eso ya estamos listo ahora sólo ejecutamos manage.py syncflex en la consola:
manage.py syncflex
Aquí una muestra del resultado:
<?xml version="1.0" encoding="utf-8"?> <cairngorm:ServiceLocator xmlns:mx="http://www.adobe.com/2006/mxml"xmlns:cairngorm="com.adobe.cairngorm.business.*"> <mx:RemoteObject id="gwCuenta" destination="gwCuenta" endpoint="http://localhost:8080/remoting/contabilidadGateway" showBusyCursor="true" result="event.token.resultHandler( event );" fault="event.token.faultHandler( event );"> <mx:method name="obtenerCuentas" /> </mx:RemoteObject> <mx:RemoteObject id="gwComprobante" destination="gwComprobante" endpoint="http://localhost:8080/remoting/contabilidadGateway" showBusyCursor="true" result="event.token.resultHandler( event );" fault="event.token.faultHandler( event );"> <mx:method name="obtenerComprobantes" /> </mx:RemoteObject> </cairngorm:ServiceLocator>
Complementos de búsqueda con OpenSearch
Hace poco escribí algunas extensiones utilizando OpenSearch. OpenSearch es un conjunto de estándares que permiten la publicación de los resultados de los sistemas de búsqueda permitiendo de este modo la sindicación y la agregación de contenidos entre diferentes motores y sistema de búsqueda. OpenSearch se compone de 3 partes, un formato para la descripción de motores de búsqueda, un formato para la descripción de los resultados de búsqueda llamado OpenSearch Response y finalmente los agregadores o sitios capaces de mostrar resultados en formato OpenSearch.
Navegadores como IE7 y Firefox soportan ya OpenSearch, es decir, permiten la incorporación de complementos de búsqueda mediante este estándar, al mismo tiempo cada uno de estos navegadores extiende las capacidades estándares de OpenSearch agregándole sus propios sabores.
La utilización de OpenSearch permite incorporar algo de usabilidad a tus sitios Web, si es que, los mismos presentan buscadores a los usuarios. Yo en mi caso particular utilizo un diccionario en inglés de la empresa WordMagic, este diccionario presenta un buscador en su portada mediante el cuál puedes acceder a las palabras del diccionario. Dado que a mí me resultaba bastante molesto ingresar al sitio para realizar la búsqueda es que me decidí a hacer este complemento, además es muy sencillo hacerlo y lo puedes incorporar también en tus sitios. A continuación veremos este ejemplo:
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/" xmlns:moz="http://www.mozilla.org/2006/browser/search/"> <ShortName>WordMagic</ShortName> <Description>Word Magic Software, Inc. es una compañia dedicada al desarrollo de software con sede en Houston, Texas.</Description> <InputEncoding>UTF-8</InputEncoding> <Image width="16" height="16" type="image/x-icon">http://wordmagicsoft.com/favicon.ico</Image> <Url type="text/html" method="POST" template="http://wordmagicsoft.com/diccionario/search.php"> <Param name="word_to_search" value="{searchTerms}"/> <Param name="search_option" value="es-en"/> </Url> </OpenSearchDescription>
Los parámetros especificados son los siguientes:
- OpenSearchDescription: Este es el nodo principal de un documento OpenSearch.
- ShortName: Un pequeño titulo que identifique al buscador.
- Description: Una descripción más larga acerca del buscador.
- InputEncoding: El encoding que soporta nuestro el buscador.
- Image: La url de algún icono representativo de nuestro buscador.
- URL: Describe la interfaz para nuestro buscador, o sea aquella que responderá a las búsquedas. El atributo template permite especificar la url y el atributo method permite indicar si se hará un GET o un POST a la url.
Eso es todo! Guardamos el contenido en un archivo xml, en mi caso le puse wordmagic.xml y ya esta! ahora solo nos queda agregarlo a nuestro navegador, para ello utilizaremos un pequeño javascript, para ello puedes construirte una página con lo siguiente:
<SCRIPT LANGUAGE="JavaScript"> <!-- function addWordMagicSearch() { window.sidebar.addSearchEngine("http://developer.cl/opensearch/wordmagic.xml", "http://wordmagicsoft.com/favicon.ico", "WordMagic", ""); } //--> </SCRIPT>
Luego solo tienes que agregar la llamada en el HTML:
<a href="#" onclick="addWordMagicSearch();">Agregar búsqueda en WordMagic</a>
Mira aquí esta el mio.
Documentación que entorpece la calidad
¿Hasta cuando será suficiente documentar el código? Uno de nuestros clientes revisa detenidamente el código fuente en las entregas, o por los menos a primera vista eso parece, sin embargo, me he dado cuenta que el foco principal de la revisión es la documentación del código, esto prosupuesto no tiene nada de extraño ni de malo, pero en mi opinión se ha perdido un aspecto importante de la revisión: la calidad del código entregado.
Cada día me encuentro con código duplicado, extensas funciones y métodos o nulo control de errores, es evidente que las revisiones ponen mas énfasis en la forma que en el fondo, dejando atrás los muchos otros aspectos que hablan acerca de la calidad del software. Bajo este planteamiento los mejores códigos serán aquellos que están más documentados, sin considerar aspectos como el tamaño, la complejidad de los algoritmos, el uso eficiente de recursos, entre muchas otras cosas.
Hoy en día el escenario global resalta otras metodologías y prácticas, una de ellas es el refactoring, definido de forma simple como la mejora del diseño del código existente, el cuál debido al acoplamiento existente entre la documentación y su código, se ve entorpecido; en cierto sentido la documentación desincentiva la iniciativa de refactorizar poniendo barreras a la mejora.
Es indudable que la documentación del código nos ahorrara varios dolores de cabeza y frustración pero cuando nos nubla la vista y adormece nuestros sentidos es hora de preocuparse.
Firefox, simplemente es mejor
Nos soy de esos que históricamente han manifestado su repudio al gigante Microsoft, no utilizo Internet Explorer porque no vaya de acuerdo a mis ideas en cuanto a código abierto, simplemente utilizo Firefox por que es mejor. No he analizado en detalle la experiencia de usuario en uno u otro navegador, no he comparado su rendimiento, su seguridad, etc., tal vez en otras áreas Firefox no sea el que la lleva, el hecho es que en mi área Firefox es por mucho el gran ganador. Es tan grande este sentimiento que he incorporado la pregunta “¿que navegador utilizas?” en la entrevista a desarrolladores. ¿Y por qué tal diferencia y adhesión?, la razón es simple y esta dada por una serie de plugins que me hacen ser mas eficiente, construir aplicaciones de calidad en un menor tiempo, en fin ser más productivo.
He aquí un pequeño listado de mis plugins favoritos:
Aardvark, me permite limpiar páginas antes de la impresión quitando así esos molestos banners publicitarios.
Firebug, herramienta indispensable para todo desarrollador, permite inspeccionar y editar HTML, inspeccionar el modelo de objetos DOM, ver los errores, depurar javascript y mucho más.
Web Developer, agrega una barra a Firefox con un montón de utilidades como resaltado de tablas, manejo de formularios, validación de CSS y HTML , información de la página, etc.
Selenium IDE, graba y reproduce nuestra navegación en una página, está herramienta ha sido creada con el propósito de realizar pruebas a nuestras páginas y lo logra de una manera muy sencilla.
Fireshoot, es una extensión que nos permite crear ScreenShoot de páginas Web y realizar anotaciones sobre estos.
TamperData, permite seguir y modificar las solicitudes HTTP, ideal para comprobaciones de seguridad (modificando los datos) y para hacer seguimiento a los request.
Google Notebook, nos permite realizar anotaciones rápidas a medida que vamos navegando.
Javascript Shell, esta es una pequeña pero potente shell para javascript sin duda una de mis favoritas.
¿Porque debería mantenerme al día?
He estado pensando acerca de si los desarrolladores deberían tener o no ese "no se que" que los lleva a ser curisos, a investigar, a querer aprender nuevas cosas, o sea ¿es obligatorio que un desarrollador lo posea?, al fin llegue a la conclusión de que si lo es, de que si elegimos esta profesión no cabe otra opción o acaso ¿como te sentirias tú al tratarte con un doctor que ocupe tecnicas del siglo pasado?, bueno en este mundo las cosas son un poco más rápidas, todos los días aparecen nuevas herramientas y lenguajes que nos sirven para codificar con mayor rapidez, con menos erroes y de una forma más mantenible, en fin, a ser más productivos, además ¿no sería aburrido no hacerlo...? para mi ahi esta lo entretenido de esta pega, en descubrir todos los días una nueva y mejor forma de hacer las cosas.
¿PHP, Ruby o Python?
Se ha establecido la discución internamente en mi empresa acerca de cual debería ser el lenguaje seleccionado para nuestros desarrollos, por lo menos para aquellos desarrollos donde al cliente no le interesa cual será la tecnología. Con la aparición de frameworks como Rails o DJango nace la necesidad de migrar del viejo y querido PHP hacia lenguajes mas ágiles, donde los cambios rápidos son más fáciles de implementar, son más fáciles de mantener y quien sabe que otra ventajas.
Por mi parte aunque reconozco la gran oportunidad que estos lenguajes ofrecen me tomo con calama la selección, ya que a mi juicio el factor lenguaje no es un argumento tan ponente como si lo es la perfecta coordinación del equipo de desarrollo, la generación de conocimiento al interior de las empresas y la utilización de las metodologías actuales como TDD, BDD, XP, etc. Este es mi juicio es el mayor valor que una empresa de software tiene o debierá tener. Así para mi siempre será mejor tener 10 tipos aromicamente coordinados trabajando en PHP que 10 expertos pero incomuicados programadores en Python.
En todo caso las cosas que he visto de Python ya me han abierto el apetito, mmhhhh... ya tengo mi elección.






