miércoles, 29 de diciembre de 2010

Esto no da para mas

Estoy re podrido, al punto de estar pensando en ser un moroso, de no pagar más una sola cuenta, que en algún momento de mi vida pagaré convenio tras convenio.

Desde hace unos años pasé a ser profesional y cada año que pasa no paró de pagar una nueva cuenta, un nuevo impuesto o un recargo por un impuesto que debí pagar por tener un titulo intermedio hace 5 años por el cual nadie en ningún momento dio aviso, onda: "mirá que debiste pagar el año pasado del impuesto tal y tal, tenes tiempo hasta tal fecha para hacerlo sino luego tendrás multas y recargos".

De todos modos no es algo de los profesionales, lo vive cualquiera que labura. Obviamente los que no laburan, viven del aire o de la gracia divina de vaya a saber quien, no tiene estos problemas. Quizás deberían hacerse descuentos a esas gracias divinas por cada hora menos laburada.

Cada año que pasa, algo nuevo para engrosar la lista.

No solo alcanza con eso, si vivís en Montevideo tenes varios extras que te hacen la vida cada día mas fácil, que te hacen sentir orgulloso de vivir y pagar cada impuesto con una sonrisa en la cara:

- tenes que pagar la patente del auto 2, 3, 4, o 5 veces mas cara que otro departamento de este bendito Uruguay. A que se debe esto? entiendo que hay mas calles y cosas que hacer que alguna de las ciudades del resto del país, pero se da el caso que un mismo auto pague en Colonia 2000 pesos y en montevideo 18.000! parece joda.

- si necesitas asistencia médica, y salvo que pagues extra, seguramente conseguirás para que un especialista te atienda en el mes próximo.

- cada vez que queres hacer un trámite en cualquier oficina que dependa del estado o del municipio tenes que pagar un extra para que el mismo sea realizado en forma eficiente, o sea, mas rápido que el trámite ineficiente o llamado popularmente "común".

- los empleados de todos estos establecimientos (no todos pero la mayoría) vive en un constante mal humor, con el deseo de volver a su casa a tomar mate y mirar a tinelli lo mas rápido que pueda. Es un ejercicio sumamente divertido ver como estos seres apuran su ritmo cardíaco minutos antes de la hora de salida, apurando finalizar la tarea que están realizando, importando bastante poco si la están haciendo bien o mal.

- cada un determinado período de tiempo (parece cronometrado), algún sindicato (y no necesariamente privado) siente la necesidad de "luchar" por sus derechos olvidando por completo sus OBLIGACIONES. 

- si para colmo de males algunos de esos gremios o sindicatos o como se les llame, de casualidad son ADEOM o AEBU, tenemos que vivir entre la mugre o tenes que esperar a que a dos gordos barbudos tomando mate en el fresco del aire acondicionado decidan que se levante la medida de lucha pero que siguen en conflicto y se tomaran 6 meses para analizar la situación, para que por fin tu plata llegue a tu cuenta y puedas pagar todas las cuentas, muchas de las cuales sirven de pago para alimentar todo este circulo. Obviamente teniendo amnesia de lo sucedido en el caso que tengas que pagar multas y recargos.

- no alcanza con todo lo anterior, sino que si a esta gente se les exige (mala palabra en el diccionario de estos seres divinos) trabajar como mínimo 6 horas, se arma quilombo y chan otro pausa en las actividades.

No se ustedes pero yo estoy re podrido de vivir de esta forma.

No creo que la solución sea levantarte un día y dejar de pagar todo lo que deberías como propuse en el principio del mail, pero cada año que pasa estoy seguro que una o dos personas se levantan y lo piensan, lo cual es bastante malo.

Yo no veo mal que me saquen un poco, un poquito o mucho de lo que gane, pero si eso repercute en una mejor calidad de vida, sino me están robando la plata, y eso es lo que siento hoy en día.

miércoles, 8 de diciembre de 2010

Montevideo cruel

Desde hace un tiempo vivo un poco mas alejado a la zona donde siempre viví, de todos modos casi todas las tardes me hago un tiempo para ir por allí, mi familia y mis amigos viven en la zona, y no solo eso, me viene bien para hacer un poco de ejercicio las veces que voy corriendo.

Estos últimos años he estado mucho tiempo fuera del país y me he perdido de cosas que ahora estoy como “descubriendo”. De hecho son cosas que sucedieron estando yo acá, pero que no había percibido como consecuencia del ritmo de vida. Ahora no ha cambiado mucho el ritmo de vida pero algunas cosas son un poco más lentas.

En realidad los que me conocen saben que hay varios temas que me “mueven”, y hay uno de ellos que últimamente me ha movido bastante, y es la sustentabilidad. De hecho con algunos amigos creamos el blog: greenuy.blogspot.com en el cual, ahora un poco menos, hemos tratado de crear un poco de conciencia, tarea para nada simple.

En particular me he topado con que de un momento a otro, y no se que estuve haciendo en el medio o no se que paso que no me di cuenta lo que estaba pasando, la zona rural donde vivía poco a poco ha dejado de serlo, y cada día deja de serlo un poco mas.

El primer indicio de esto fueron las canchas de fútbol, o complejos con varias canchas, lo que antes eran granjas hoy son complejos con varias canchas de futbol. Lo otro asombrosamente extraño es la instalación de una industria en plena zona rural muy cerca de la casa de mis padres. Lo cual no deja de sorprenderme, dado que una zona rural que además es protegida, justamente para que no pasen cosas como esas sino que sentido tiene que sea una zona rural, se instale una industria.

Resulta sumamente extraño que se le haya dado un permiso a un emprendimiento con dichas características, me pregunto que pasara mañana cuando otro quiera hacer lo mismo. Otra cosa que me pregunto es si alguien controla una vez otorgado el permiso lo que esa industria esta haciendo en la zona.

Ya me han dicho: pero que importa, lo importante es que da trabajo a muchos. Ahora, que pasa si el dar trabajo a muchos significa tirar no se que desechos a la cañada por ejemplo, la cual va a parar al arroyo o río, será que será sustentable. La ecuación mucho no me cierra.

Por otro lado están proliferando los grandes galpones para logística, talleres, contenedores, etc.

Esta de más decir que no me cae para nada en gracia y para ninguno de los que allí habitaron toda la vida, esta clase de cosas. No es lindo.

Obviamente no domino el tema del urbanismo, la planificación de una ciudad o área dentro de una ciudad, pero suena bastante razonable pensar en que una zona es para determinada actividad, se me ocurre: vivienda, industria, rural, y comercio quizás. No suena muy prolijo que sea un mix de cosas. Pinta a desequilibrio.



jueves, 12 de agosto de 2010

Tweet Button

Siguiendo la linea de TweetThis y aprovechando el lanzamiento oficial del Tweet Button por parte de twitter, dejé en el gallery un nuevo user control para facilitar su uso en nuestras aplicaciones.

Las ventaja de este nuevo user control es que podemos ver la cantidad de veces que twitteamos determinado link o texto.

url: url que vamos a twittear
title: texto a incluir junto con la url
count: podemos especificar si queremos el contador de tweets y su align, valores posibles: [horizontal, vertical, none]
via: podemos indicar si lo twitteado lo leímos a través de un usuario particular, vía @cimasan
button_text: texto a incluir en el tweet button
lang: lenguage en el que aparecerá el texto del button



Download TweetButton

miércoles, 11 de agosto de 2010

User Control: Tweet

Hace un tiempo subí al gallery el user control Tweet, con la idea de poder tener los últimos tweets de un user en mi aplicación.

Para usar el UC simplemente arrastramos el control al form de nuestro objeto y configuramos en tiempo de diseño o pragmáticamente las siguientes propiedades:

username: el username del usuario de twitter
width: ancho que tendrá el contenedor donde se mostraran los tweets
avatarsize: es el tamaño a asignar a la foto de perfil del user, ej: 32 (32x32).
autojointextdefault: texto a colocar para tweets escritos por el user
autojointexted: texto a colocar para tweets pasados
autojointexting: texto a colocar para tweets en presente
autojointextreply: texto a colocar cuando el user responde a otro user
autojointexturl: text a colocar cuando se twittea un link
count: cantidad de tweets que queremos mostrar

En ejecución se ve mas o menos así:


update: version 1.1, ahora es posible hacer consultas para buscar determinados tweets, por ejemplo para buscar los tweets con el tag: #XXGX se programaría algo como:

Tweet1.Query = "%23XXGX"

siendo Tweet1, el nombre del user control.
Por más información sobre qué consultas se pueden realizar ver Twitter's Search API

lunes, 9 de agosto de 2010

TweetThis

Dejé en marketplace.genexus.com un nuevo UC para poder agregar un link en nuestra app que nos permita twittear un texto y una url. El UC utiliza http://bit.ly/ para el shorten de la url a tweetear.

 Debemos especificar:

- title, texto a incluir
- url, url que queramos compartir
- login, usuario de http://bit.ly/
- ApiKey, apikey proporcionado por http://bit.ly/ para el usuario especificado en login

Ejemplo:

Event Start

        TweetThis1.title = "tweetthis"
        TweetThis1.url = "http://cimasan.blogspot.com"
        TweetThis1.ApiKey = "mykey"
        TweetThis1.Login = "cimasan"

EndEvent

Download TweetThis

miércoles, 28 de julio de 2010

No siempre son palos

En estos días tuve que hacer varios trámites, tanto en el ámbito privado como público, y me he llevado algunas sorpresas, y la mayoría buenas sorpresas.

Tuve que justificar el no haber votado en las últimas elecciones por estar fuera del país, salvo por el hecho que la oficina donde debí hacer el trámite comenzaba a atender público a las 13 hs., el resto fue "un trámite", en pocos minutos estaba fuera con mi justificación. De este experiencia algunos comentarios: por qué no se atiende al público durante todo el día? por qué comienza a las 13 y no a las 9 o 10 como toda oficina? comienzan a trabajar a efectivamente a las 13 o van antes? si comienzan a trabajar a las 13 hs, solo trabajan 4 horas diarias? si van a las 9, qué hacen hasta las 13? Para terminar: señora que quiere justificar su no-voto y no lleva credencial ni cédula, por favor, no arme alboroto, pida disculpas y vuelva a su casa.

Tuve que hacerme socio de una mutualista, en este sentido es mas entendible que las cosas sean rápidas y se reciba un trato amable, pero créanme no siempre es así, de todos modos esta no fue una de esas veces y no tuve inconvenientes.

Solicitar servicio de ADSL en Antel, y  no solo adsl, sino linea telefónica y asociar mi teléfono celular al adsl movil asociado al servicio. Fuí pensando en que debería ir tres veces: una para solicitar teléfono, otra luego de tener el teléfono para solicitar adsl, y quizás otra para poder tener el servicio 3g en mi celular. Aún no puedo creer como salí de Antel, primero: feliz por el trato brindado, y segundo: feliz porque ya me iba con el servicio en mi celular y con fecha para instalación de linea telefónica para luego seguir con el adsl. Veamos como me va con las instalaciones, pero hasta ahora nada mal.

Para completar la semana, debía ir al Registro Civil, si, leen bien, fui al Registro Civil, me caso :-) pero no es la idea hablar de ese tema, lo que quiero comentar es el buen trato que recibimos, tanto allí como luego en el Diario Oficial, principalmente eso, el buen trato y el buen humor con el que fuimos atendidos.

Será casualidad?
Tuve un día de suerte?
Algo está cambiando?
Será por lo de Uruguay en el mundial?

martes, 18 de mayo de 2010

Irashaimase, Arigato gaozaimas, Sumimasen

Si, si antes me han leído van a notar que soy reiterativo en este tema, pero es que me sigue sorprendiendo y cada día no puedo evitar sorprenderme otra vez. De que les hablo? de la atención al cliente, cualquiera sea, en Japón.

Seguramente mi asombro es mayor por mi procedencia sudamericana, quizás en países de Europa o Oceanía el trato al cliente es mas cercano al japones y no se note tanto, pero no lo sé, nunca he estado allí por lo cual quiero contarles mi experiencia.

Casi todos los días oficio de cliente en por lo menos dos locales comerciales, un super o un restaurante. En ambos lugares y sin importar si estas vistiendo un traje, un pantalón destrozado por los efectos del trabajo duro de una obra, o si elijes el plato mas barato del menú, o simplemente compras una botella de agua, el trato es y será el mismo. Automáticamente al ser visto por algún integrante del staff te dirán: Irashaimase (bienvenido) y seguirá, dependiendo de la hora del día, un Konichiwa (buenas/hola) o Kombawa (buenas noches).

Imagino que trabajando unas ocho horas diarias esta gente pronuncia esas palabras unas 50 o mas veces al día. Como les decía antes, no para de sorprenderme cómo esta gente aguanta una rutina como esta. Pero es parte de su cultura, por lo cual no creo que se aburran de hacerlo algún un día (aunque me imagino existen casos de gente que dijo basta alguna vez).

Bueno, han crecido y han visto desde el nacimiento como todos lo hacen, con lo cual si voy a pedir trabajo a algún lugar de atención al cliente ya sé, de antemano, cuales son las reglas. De hecho cuando ellos son compradores esperan lo mismo del vendedor.

Está de más decir que durante la compra el trato sigue siendo el mismo, no disminuye dado que el inicio fue bueno, es decir, en el inicio, en el durante y en el final se recibe el mismo nivel de atención.

Lo mismo pasa cuando se va al correo a enviar una carta, al banco a cambiar plata, o a una oficina del gobierno un domingo, para resolver algún trámite que no pudiste hacer en la semana por motivos laborales, a las cuatro de la tarde, una hora antes de cerrar.

Esta bueno? si esta bueno, de hecho esta gente no entiende que no sea así, es decir no existe en su universo llegar a algún lugar y que nadie les de la bienvenida o que luego de la compra no se les diga gracias.

Está mal? y...no creo que este mal, quizás en otros países en un puesto de atención al cliente se le de la bienvenida a algunos, las gracias a otros, y otras veces no se diga nada, por lo cual para algunos puede llegar a ser un poco molesto en ocasiones.

Dos ejemplos de los que me sorprenden:

1. cuando vas a la peluquería, luego de pagar esperas un gracias y un hasta la próxima o algo así no? bueno acá van un poco mas allá, el peluquero que te atendió, junto con quién te cobró y quizás sumado a quién te hizo algún otro servicio te acompañan a la puerta, salen afuera contigo y te despiden en la calle hasta que vos, agradecido, emprendes viaje con el nuevo look.

2. similar al caso de la peluquería, cuando sos parte de una empresa y vas a visitar a otra, ya sea para presentar un producto, para una simple reunión o para ver un problema que puedan tener en un servicio o producto, luego de terminada la sesión pasará lo mismo que con el peluquero, incluso al punto de llamar al ascensor y esperar contigo la llegada del mismo para si finalmente despedirte.

Lo que hablaba antes del servicio al cliente en un restaurant o super se traslada al nivel empresarial obviamente. El cliente es lo máximo y siempre pero siempre se tratará de satisfacerlo y mimarlo. En este sentido sucede que cuando una empresa decide comprar un servicio o un producto a otra, deposita en ella toda su confianza y difícilmente el vinculo se rompa algún día.

Pero obviamente para ganar esa confianza hay que decir muchos: "Irashaimase", "Arigato gaozaimas" (gracias) y "Sumimasen" (disculpe).

martes, 27 de abril de 2010

User Control: FocusController

Cuando se carga una página GeneXus se encarga de colocar el foco en el primer campo editable que encuentra, pero que pasa si queremos poner el foco en determinado campo de la pantalla?

En muchos casos queremos que el foco vaya a un campo particular del form que no necesariamente es el primer campo de la pantalla. Es más, nos puede pasar que queramos que el usuario ingrese datos en un grid apenas se cargue la página,  para lo cual desearíamos poner el foco en el primer campo de la primera fila de un grid.

Para cumplir con ese deseo de controlar donde irá el foco luego de cargada la página, y en especial que vaya a un campo de un grid, surge la idea de desarrollar el user control, FocusController.

Como funciona?

Imaginen un ejemplo muy simple de un grid con un par de variables y el siguiente evento load para cargar los valores:

Event Grid1.Load
    for &I=1 to 5
        &Var1 = &i
        &Var2 = &i
        grid1.Load()
    endfor
EndEvent

Pero la idea es que al cargar el webpanel el foco vaya al campo asociado a &Var1 en la primera fila del grid, entonces lo que hacemos es colocar el user control FocusController en el form y cambiamos el evento load de la siguiente manera:

Event Grid1.Load
    for &I=1 to 5
        if &I=1
            FocusController1.OnLoadControlFocus = &Var1.InternalName
        endif
        &Var1 = &i
        &Var2 = &i
        grid1.Load()
    endfor
EndEvent

La propiedad OnLoadControlFocus del user control debe ser cargada con el InternalName (nombre interno que se le dará al campo en el html generado) de un campo que pueda recibir el foco, como por ejemplo: var/att editables, imagenes, o botones.

Nota: el user control fue desarrollado y testeado con la versión GeneXus Evolution 1, no se asegura su funcionamiento con versiones anteriores o posteriores de GeneXus.

lunes, 19 de abril de 2010

Problemas con Favicon.ico

Hace unos días me contaron que en el log del servidor aparecía el siguiente error:

[error] [client 192.168.51.251] File does not exist: /opt/jboss-ews-1.0_A/httpd/www/html/favicon.ico

El error aparecía en el Apache http server el cual se utiliza como "load balancer" entre los distintos application server, Jboss.

A primera vista es obvio pensar que se esta referenciando al archivo favicon.ico en la ruta mencionada en el error y dicho archivo no se encuentra, lo cual se confirmó luego de mi prueba, pero de todos quise armar un ambiente y efectivamente obtener el mismo error, la única diferencia sería hacerlo en un ambiente Windows y no Linux.

Lo primero que necesitaba era poder contar con varios jboss de forma de poder hacer el balanceo de carga, pero la idea era hacer todo en mi máquina, así que configuré dos IP's virtuales de forma de levantar una instancia de jboss en cada una de ellas.

Para hacer esto agregué un nuevo Network adapter (Add new hardware device - > (manual) Network Adapter - > Microsoft Loopback Adapter) y le configuré dos IP's (que no estuvieran en el rango de mi red). Para hacer eso se debe ir a las propiedades de la conexión recién creada y en las properties de la sección Internet Protocol (TCP/IP) configurar una IP, ej: 192.168.1.140, y luego en Advanced agregar una nueva IP, ej: 192.168.1.141.

Lo siguiente fue instalarme el Apache Http Server, y luego el modulo mod_jk de forma tal que mi Apache http server se pueda encargar del load balancing. El archivo a bajar tendrá un nombre de la forma mod_jk-x.x.xx-httpd-x.x.xx.so, dependiendo de la versión, en mi caso me baje la última disponible en ese momento, 1.2.30. Para instalarlo se debe copiar al directorio APACHE_HOME/modules y renombrarlo a mod_jk.so.

Ya tenía instalado Jboss por lo cual no fue necesario instalarlo.

 A partir de este momento tenía todo lo necesario, ahora solo restaba comenzar con las configuraciones..

Configuraciones a hacer en Apache:

1. Editar el httpd.config ubicado en apache-home\conf y agregar:

#mod_jk setup
Include conf/extra/mod_jk.conf


2. Crear el archivo mod_jk.conf en apache-home\conf\extra y agregar lo siguiente:

# Load mod_jk module
# Specify the filename of the mod_jk lib
LoadModule jk_module modules/mod_jk.so

# Where to find workers.properties
JkWorkersFile conf/workers.properties

# Where to put jk logs
JkLogFile logs/mod_jk.log

# Set the jk log level [debug/error/info]
JkLogLevel info

# Select the log format
JkLogStampFormat  "[%a %b %d %H:%M:%S %Y]"

# JkOptions indicates to send SSK KEY SIZE
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories

# JkRequestLogFormat
JkRequestLogFormat "%w %V %T"
             
# Mount your applications
JkMount /MYAPP_NAME/* loadbalancer

# You can use external file for mount points.
# It will be checked for updates each 60 seconds.
# The format of the file is: /url=worker
# /examples/*=loadbalancer
JkMountFile conf/uriworkermap.properties             

# Add shared memory.
# This directive is present with 1.2.10 and
# later versions of mod_jk, and is needed for
# for load balancing to work properly
JkShmFile logs/jk.shm
            
# Add jkstatus for managing runtime data

    JkMount status
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1


Aquí se debe reemplazar MYAPP_NAME por el nombre de la webapp en la que queremos hacer load balancing.

3. Crear el archivo workers.properties en apache-home\conf\ con el siguiente contenido:

# Define list of workers that will be used
# for mapping requests
worker.list=loadbalancer,status

# Define Node1
# modify the host as your host IP or DNS name.
worker.node1.port=8009
worker.node1.host=192.168.1.140
worker.node1.type=ajp13
worker.node1.lbfactor=1


# Define Node2
# modify the host as your host IP or DNS name.
worker.node2.port=8009
worker.node2.host=192.168.1.141
worker.node2.type=ajp13
worker.node2.lbfactor=1


# Load-balancing behaviour
worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=node1,node2
worker.loadbalancer.sticky_session=1
#worker.list=loadbalancer

# Status worker for managing load balancer
worker.status.type=status


Aquí estamos definiendo los nodos donde estarán nuestros jboss para hacer el load balancing entre ellos, en este caso el node1 estará en la IP 192.168.1.140 y el node2 en la IP 192.168.1.141, que son las IPs que configuré al principio, en caso de haber usado otras se deben colocar esos números de IP aqui.


4. Crear el archivo uriworkermap.properties en apache-home\conf\ con el siguiente contenido:

# Simple worker configuration file# Mount the Servlet context to the ajp13 worker
/MYAPP_NAME=loadbalancer
/MYAPP_NAME/*=loadbalancer


al igual que antes MYAPP_NAME es el nombre de la webapp que queremos "balancear".

Hasta acá todo lo necesario a configurar en el Apache HTTP Server.

Configuraciones a hacer en JBoss:

1. Como dije antes la idea es levantar dos instancias de JBoss en mi máquina, para hacer esto debemos hacer dos copias del dir jboss-home\server\default, llamar a una node1 y a la otra node2, estos nombres se corresponden con los que configuramos en el archivo workers.properties.

2. Editar el archivo jboss-home\server\node1\deploy\jboss-web.deployer\server.xml y  setear:

< Engine name="jboss.web" defaultHost="localhost" jvmRoute="node1" >


3. Editar el archivo jboss-home\server\node1\deploy\jboss-web.deployer\META-INF\jboss-service.xml y  setear:

< attribute name="UseJK" > true < /attribute >

4. Repetir el paso 2 y 3 para el node2

5. Debemos hacer el deploy de nuestra webapp, MYAPP_NAME, en ambas instancias del jboss, node1 y node2.

Por último solo nos resta levantar las dos instancias de JBoss, para hacer esto podemos hacer lo siguiente:

run.bat --host=192.168.1.140 --configuration=node1 -Djboss.messaging.ServerPeerID=1
run.bat --host=192.168.1.141 --configuration=node2 -Djboss.messaging.ServerPeerID=2

con esto tenemos las dos instancias de JBoss corriendo en nuestra máquina, una en la IP  192.168.1.140 y la otra en la IP 192.168.1.141.

Solo nos resta levantar Apache y comenzar a usar la app.

Cuando levantamos Apache podemos llegar a tener un error como este:

(OS 10048)Only one usage of each socket address (protocol/network address/por
is normally permitted.  : make_sock: could not bind to address localhost:
no listening sockets available, shutting down
Unable to open logs


Para solucionarlo podemos editar el archivo httpd.conf y setear la IP de nuestra máquina en lugar de localhost:

Listen 192.168.10.21:80

Lo mismo o un error similar puede pasar si tenemos corriendo el IIS en el mismo puerto (80).

Listo, cuando accedamos a http://localhost/MYAPP_NAME estaremos haciendo load balancing, podemos bajar un node y notar como seguirá funcionando nuestra app.

Volviendo al problema original, cuando accedemos a nuestra app el browser buscaba por el favicon.ico en apache-home\htdocs y el mismo no estaba allí, por lo cual copiando favicon.ico a dicho directorio el problema quedó resuelto.

viernes, 16 de abril de 2010

Cosas que no se ven habitualmente por mi barrio

Típica imagen de metro luego de las 10 de la noche.


Yorugua sacando ticket de tren con Pilsen en mano

Si vas a reusar las sábanas pone esto en la puerta para que no las cambien

Bar con todas botellas de wisky o sake

Tomate la cerveza y tira el vaso donde se debe

Máquina para elegir que vas a comer y pagar

Cerveza cusqueña

Voluntario que indica a los peatones cuando deben cruzar el seáforo

Típico escritorio de Uruguayo

Agarrate que se mueve todo

WTF

El padrino en el baño

Te leo las manos

 Todo bien con dejarla en la calle pero sacale las llaves

Se enojó

 Boy scouts

 Antes que te corte el pelo paga tú ticket

Haciendo té

Vista del cementerio desde la habitación

Nieve en primavera


jueves, 15 de abril de 2010

Cambiar dinero en Japón

....tarea por demás interesante.

Hace un tiempo hablé de la amabilidad con la que uno es atendido cuando va al banco, eso no ha cambiado y nada tengo para decir al respecto. Ahora, algo tan simple como cambiar plata en Japón, dolares a yenes en mi caso, puede llegar a ser una experiencia religiosa.

Hoy tenía que cambiar dinero porque ya no tenía yenes, por lo cual fui al primer banco que vi caminando por la calle, no voy a decir que banco dado que no aporta (pero era el Mizuho Bank), no tenía el pasaporte conmigo por lo cual no me fue posible cambiar.

Volver a casa a buscar el pasaporte o ir a otro banco e intentarlo? ir a otro banco.

Quiero cambiar dinero le dije a la señora amable que esta para atender a los clientes que entran al banco.
A la pregunta sobre que clase de cambio, le dije Dolares a Yenes.
Me entregó un formulario donde debía poner mi dirección y teléfono en Japón, mi nombre, y cuanto dinero debía cambiar.

Un embole, pero todo bien...

Espero (casi nada) y me llaman.
Me siento,  y entrego mi formulario a la funcionaria.
Olvidé poner el signo de dolares, shit!
Me pregunto: que raro? el formulario es especial para dolares a yenes, sino me hubieran dado otro de otro color y con un titulo que diría euros a yenes por ejemplo. Ok.

Siguiente pregunta: en esta dirección vive?

Siguiente respuesta: no, allí trabajo, me acabo de mudar y no se mi nueva dirección.
Cara de asombro por parte de funcionaria.
Espere un momento por favor, tengo un mapa con mi nueva dirección en mi bolsillo, le digo.
Entrego mapa con dirección.

Puedo sacar una copia, dice la funcionaria.

Si, por supuesto, respondo ya un tanto cansado.
Me pregunto nuevamente: por qué tanta vueltas por dios? enseguida recuerdo un cambio de Montevideo, o a una cholita en Bolivia cambiando dolares por bolivianos sentada en una silla en el medio de la frontera con Perú.

Luego de hacer la copia, ingresar algo en la computadora, otra vez se acerca la funcionaria al escritorio.

Debo admitir que en este momento estuve a punto de levantarme e irme, pero no tenía mis dolares conmigo, los tenía la funcionaria haciéndole algún super chequeo para corroborar que no fueran falsos.
Otra vez pienso: en realidad esta bien todo este chequeo de información, esto les permite tener un trace interesante de cada transacción y en caso de algún problema no habría dudas de donde ir a buscar al autor de la irregularidad, en este caso yo. Pero nuevamente me pregunto, solo quiero cambiar unos pocos dolares, por qué es tan complicado? Y otra vez se me viene a la mente la cholita boliviana.

Por fin! llegan los yenes en una bandejita junto con la funcionaria.

Pero...nueva pregunta: como se llama su empresa?

Mmm más preguntas, qué lindo!, eso pensé, pero no usando esas palabras.

No dije nada, solo le mostré mi tarjeta personal donde decía el nombre y a continuación leí el nombre de la empresa.

La dirección de la empresa que puso en el formulario se corresponde con el nombre de su empresa?

Respuesta: Si

Me entrega el dinero, lo cuento, todo esta ok, muchas gracias, chau hasta mañana.

Como decía mas arriba: una experiencia religiosa!

miércoles, 7 de abril de 2010

Where is Uruguay?

Fuí al correo porque tenía que enviar una carta a Uruguay.

Para cobrarme y poner los sellos debían saber donde estaba enviando la carta, en el sobre decía y obviamente yo les dije también: el país a enviar la carta es Uruguay.

Luego de pasar de una computadora a otra, parece que en el sistema de la primera no aparecía Uruguay, se dieron cuenta que el sistema es el mismo, independiente de la computadora y se percataron que ese país llamado Uruguay no aparecía en el sistema o al menos escrito de la forma "Uruguay".

En la oficina trabajaban unas 4 o 5 personas y ninguna sabía de la existencia de tan raro país, luego de preguntas tales como: Rusia? (está cercano a Rusia), Europe? (es un país de Europa?), había que recurrir a la clásica y ya trillada explicación:

1. South America
2. Movimiento de manos, explicando donde esta Asia, Europa, Amercia del Norte (USA) y América del Sur
3. Brazil
4. Argentina
5. Otra vez movimiento de manos, ubicando donde estaba Brasil y Argentina, para luego pasar si a...
6. Uruguay

Obviamente la amabilidad nunca la dejaron de lado y las disculpas por no saber donde estaba no tardaron en llegar. De todos modos me pregunto:

- es tan raro el país donde vivimos?
- Geografía, se enseña en los colegios?
- globos terráqueos existen por Asia?

Por otro lado también es cierto que si Japón y los japoneses son un punto muy pequeño en el mundo, explicado de forma muy clara acá, quizás es razonable pensar que no existamos, no?

Sigamos jugando, ahora Twitter

Hace un tiempo subí al GeneXus Server una KB que usaba una librería de las tantas que existen para interactuar con la API de Twitter, más específicamente la Yedda Twitter C# Library. La idea era jugar un poco con twitter desde GeneXus.

Para usar la librería utilizo un External Object, que encapsula toda la funcionalidad de la dll. En aquel momento solo probé traer mi lista de followers y mostrarla en un webpanel, algo que quedaba así de simple:

&userString = &twitter.GetFollowersAsJSON(&user,&password)

siendo &twitter mi external object y &userString el json con toda la lista de followers, y luego levantaba la info para poder utilizarla mediante un SDT haciendo:

&Users.FromJson(&userString), siendo &Users un sdt con toda la info que necesito asociada a los followers.

Pero ahora quería poder twittear. Cuando fui a utilizar dicho método, UpdateAsJSON, me encuentro con que al ejecutar se presenta un error (en la librería) que me lo impedía, quizás a causa de no estar actualizada la dll.

A diferencia de lo que buscaba cuando estaba jugando con facebook, ahora no quería utilizar una librería javascript y desarrollar un UC para resolver la integración, dado que no necesitaba nada de interfaz simplemente quería twittear, algo tan simple como pasar mi user y pass y actualizar mi status en twitter.

Así que opte por usar otra librería, ahora java, JTwitter. Como casi todas las librerías, esta tenía muchas mas funcionalidades de las que quería, y además tuve un error al importarla directamente en GeneXus, por lo cual opte por hacer un wrapper, solo disponibilizar aquello que necesitaba y crear un external object en base a ese wrapper:

getStatus(): devuelve el status del usuario
setStatus(text): twittea el texto text
getStatusesCount(): devuelve la cantidad de tweets del usuario
getProfileImageUrl(): devuelve la url de la picture del profile del usuario

Con esos cuatro métodos tengo todo lo que necesito para twittear y mostrar la info del usuario en mi webpanel:



Si quieren pueden bajarse la KB: Twitter desde Genexus Server, y seguir jugando.

Luego que tengan armado el ambiente deben copiar jtwitter.jar y twitter.jar (ambos archivos están en la KB) al directorio lib de su webapp, y ambos deben estar en su classpath. En los Files de la KB también esta el proyecto de NetBeans con el que hice el wrapper, twitter.zip, por si quieren seguir haciendo cosas.

domingo, 4 de abril de 2010

Jugando con Facebook

El dilema era: crear otro blog para escribir cosas mas técnicas y menos diarias o seguir usando este...como se puede ver abajo el dilema fue resuelto.

Desde hace un tiempo tenía ganas de poder integrar Facebook con GeneXus, de hecho en la charla que dimos con Javier Larrosa en la  XVIII GeneXus Meeting del 2008 algo habíamos mostrado. En esa oportunidad lo hicimos a través de los External Objects de GeneXus, utilizamos una librería desarrollada por Microsoft para interactuar con Facebook. La idea no estaba mal y de hecho pudimos comunicarnos muy fácilmente a través de dicha librería.

El problema con esto es que estábamos usando un producto de un tercero pudiéndolo hacerlo directamente a través de la API de Facebook. Esto tenía como inconveniente que siempre que ese tercero cambie nosotros debemos cambiar nuestro External Object para actualizar la lista de métodos/propiedades.

Eso fue justamente lo que nos paso luego del evento, Microsoft cambió varias interfaces de dicha librería debido a cambios en la propia API de Facebook, y lo que nosotros teníamos funcionando y que de hecho mostramos en la demo de la charla dejó de funcionar.

Lo interesante de utilizar un External Object era que teníamos la API de Facebook encapsulada en dicho objeto y era muy fácil su utilización.

Podíamos seguir en la línea de utilizar una librería de un tercero o podíamos nosotros mismos interactuar con la API de Facebook sin necesidad de un tercero, y esa es justamente la línea que elegimos, desarrollar una serie de User Controls que resuelvan la comunicación con Facebook desde nuestros objetos.

En cualquier caso, ya sea utilizando una librería de un tercero o accediendo a la API directamente, tenemos que crear una aplicación en Facebook, para lo cual primero que nada debemos agregar a nuestro perfil de Facebook la application: Developer. Y luego crear una nueva Application, esto nos permitirá obtener una ApiKey con la cual podremos acceder a la API. Acá pueden saber un poco mas al respecto.

La idea de los User Controls es utilizar la JavaScript Client Library, para acceder a la API a través de código javascript. No queremos hostear una app en Facebook, por lo cual cuando creemos nuestra app en Developer solo nos interesará:

Basic -  API Key, Key necesaria para poder interactuar con la API


Connect - Connect URL, url donde Facebook enviará una session válida para comunicarnos con ellos

Como pueden ver, también configuré un valor para Base Domain, en este caso localhost. Esto se debe a que tendremos una comunicación entre nuestra app y Facebook a través de js, por lo cual habrá una Cross Domain Communication, por lo cual debemos crear un Channel entre nuestra app y Facebook, para lo cual necesitamos crear un archivo xd_receiver.htm y almacenarlo en nuestro server. Pueden obtener mas detalles aquí, pero a los efectos de la utilización de los User Controles en GeneXus solo tenemos que tener en cuenta dos cosas:

1. cuando creamos la app en Facebook indicar un Base Domain, con lo cual indicamos el nombre del dominio en el cual estará el archivo xd_receiver.htm
2. cuando utilicemos el User Control: FacebookConnect, el cual nos permitirá conectarnos con Facebook, debemos indicar la ruta a dicho archivo a través de la property xdChannelUrl, cuyo valor por defecto es "/xd_receiver.htm".


Por lo cual si en el UC indicamos como xdChannelUrl el valor "/xd_receiver.htm",  entonces en el caso de .Net debemos almacenar el archivo en: C:\Inetpub\wwwroot, y en el caso de Java utilizando tomcat como webserver en: C:\Program Files\Apache Software Foundation\Tomcat 6.0\webapps\ROOT.

Los tres User Controls que tenemos al día de hoy son:

FacebookConnect: necesario para establecer la conexión entre nuestra app y Facebook.

Text: text del botón que se agregara a nuestro form y que nos permitirá establecer la comunicación con Facebook, valor por defecto: "Connect with Facebook".

ApiKey: como mencionamos antes es la Key asociada a la app que creamos en Facebook.

xdChannelUrl: url o ruta al archivo xd_receiver.htm que nos permitirá establecer una cross domain communication entre nuestra app y Facebook, valor por defecto: "/xd_receiver.htm"

Size: tamaño del boton, valores posibles: small, medium, large, or xlarge, valor por defecto: "medium".

FacebookLoggedUser: muestra la foto de perfil y el nombre del usuario logeado a Facebook.

Width: width de la foto, valor por defecto: 50

Height: height de la foto, valor por defecto: 50

FacebookLogo: true/false, indica si se quiere mostrar el logo de Facebook o no en la foto, valor por defecto: true.

Linked: true/false, indica si se quiere tener un link al perfil de Facebook en la foto de perfil, valor por defecto: true.

FacebookShare: permite compartir un link en el muro del usuario logeado

Link: link a compartir una vez que el user hace click en el boton asociado

Type: tipo de boton, valores posibles: box_count, button_count, button, icon, or icon_link, valor por defecto: button_count

Pueden obtener los controles en la gallery de GeneXus.

Si se fijan el código de estos User Controls es muy simple, por lo cual pueden chequear la docum de la JavaScript Client Library de Facebook y desarrollar el propio en base a sus necesidades.

update


Dado algunos cambios que sufrió la api de Facebook he realizado algunos cambios. Paso a hacer deprecated la JavaScript Client Library y con ello varios métodos y formas de realizar determinadas acciones.

Eliminé los user controls FacebookLoggedUser y FacebookShare dado que el Facebook Markup Language (FBML), lenguage utilizado en dichos controles, paso a ser deprecated (o en vías de serlo). De todos modos quedó todo armado hacer lo que hacían estos controles

Realicé cambios en la implementación del FacebookConnect los cuales son transparentes para quien utiliza el control, pero que eran necesarios para que funcione la autorización y autenticidad con Facebook.

Agregué un nuevo user control, FacebookFriends, que me pareció interesante pensando en el desarrollo de una aplicación que lo utilizara para explotar los datos obtenidos. Como su nombre lo indica el FacebookFriends obtiene la lista de los amigos del usuario logeado, deja cargada una colección con dichos datos.

Para que funcione el FacebookFriends es necesario tener un FacebookConnect de modo de resolver la autorizcion y autenticacion, una vez que el usario se logea a Facebook y permite acceso para que nuestra app
acceda a la lista de sus amigos obtendremos la collection de amigos a través de un sdt.

Cuando se arrastra el user control FacebookFriends se importa el xpz con el sdt que utilizara el uc para cargar la lista de amigos, la información de los amigos que se esta cargando hoy en día (podría agregarse mas data) son: id y nombre.

Para cargar la foto de todos mis amigos en un free style grid podría hacer algo como esto:


Event FacebookFriends1.AfterFriendsLoaded
for &friend in &friends
&imagesDataItem = new()
&imagesDataItem.Id = &friend.id
&imagesDataItem.Thumbnail = "http://graph.facebook.com/" + &friend.id + "/picture"
&imagesDataItem.Image = "http://graph.facebook.com/"+ &friend.id + "/picture?type=large"
&imagesDataItem.Caption = &friend.name
&imagesData.Add(&imagesDataItem)
endfor
&tic = Servernow()
 
EndEvent

en el evento AfterFriendsLoaded del user control FacebookFriends  cargo un sdt con la información de los amigos (id, name y foto).

Event grid1.Load
for &imagesDataItem in &imagesData
image1.FromURL(&imagesDataItem.Image)
grid1.Load()
endfor
EndEvent


y luego en el evento load de la grid cargo las fotos.


Notar que estoy usando otra sdt para cargar los datos de cada amigo cuando en realidad el UC podría ya devolver dicha información, esto es solo a los efectos de mostrar que dado el id de un user en Facebook puedo obtener información de dicho user consultando la Graph API.


Toda la documentación necesaria para interactuar con Facebook vía js esta en la JavaScript SDK.

Estos dos controles los pueden encontrar en el Marketplace de GeneXus.

jueves, 11 de febrero de 2010

Volviendo o yendo?

Hoy estoy regresando a Japón (esta vez con visa por lo cual espero pueda entrar :-))...para lo cual los amigos organizaron un asado "obrero" para hacerme entrega de la celeste y despedirme, unos grandes! Gracias: Maxi, Pali, Sollita, Javi, Dario, Schubert, Negro, Carlitos, Chato, Chango, Templi, Richard, Pirri, Pocho, Seba, Diego, Zanella, Mario, Barreto!!

Para completar los amigos de La Cachila, me hacen entrega de la taza con la foto del último campeonato ganado el año pasado!! Nooooo así es difícil irse!! Gracias: Pablo, Topo, Alex, Barreto, Willy, Carlin, Sollita, Colo, Victor, Manolo, Sergio y al resto de la gloriosa negra y roja!!

Gracias locos!!
Nos vemos pronto!!!