Archivo

Archivo para la categoría ‘opensource’

Aprendiendo JavaFX: GUI basics II

Domingo, 10 de enero de 2010

Aqui les dejó el código de la tarea de esta sección del curso de JavaFX en JavaPassion . El resultado se ve como esto:

En este ejercicio el circulo se mueve en sentido contrario al cuadrado proporcionalmente (sólo en el eje X).

Que lo disfruten, pienso seguir agregando respuestas del curso (admito que estoy muy retrasado con respecto a la entrega final, pero no pienso rendirme :) )

java, javafx, kodegeek, opensource, programación , ,

¿Oracle destruyendo MysQL? No me veo firmando una petición para salvarlo…

Sábado, 9 de enero de 2010

¡Salven a MySQL de las garras de Oracle! Ese es el nuevo grito en Internet estos días, y viene del fundador de MySQL.

Si leen la petición cuidadosamente, el argumenta que el uso de GPL no es suficiente. La intención es que Oracle le deje el desarrollo a una tercera compañía la cual va a seguir creciendo MySQL bajo GPL.

No entiendo el llanto, después que vendió MySQL a SUN, luego dejó a SUN para trabajar en MariaDB (Fork).

¿A quien le importa si MySQL deja de existir? Hay otras alternativas, muy buenas como PostgreSQL. Lo otro es que no creo que Oracle este interesado en destruirlo (aunque no creo que lo aumente o mejoren).

El software gratuito tiene este y otros dilemas. Un caso muy interesante es el de OpenNMS el cual pasó varios años peleando contra una compañía que tomó el producto, hizo dinero con él y no liberó los cambios para el beneficio de todos.

Yo creo que un fork de MySQL puede sobrevivir y prosperar. La licencia GPL protege el producto y hay muchas compañías interesadas en que MySQL viva.

Los dejo con la siguiente nota de LWN, a la final es la comunidad quien decide el éxito de una aplicación:

Still, it is telling that so much of the work done by the forks centers around the InnoDB storage engine: the patches written by Percona and OurDelta, Percona’s replacement engine XtraDB, and MariaDB’s replacement engine Maria. InnoDB is GPLv2-licensed, but the copyright is owned by … Oracle. Oracle acquired InnoDB’s creator Innobase in 2005. That acquisition sparked a flurry of concern that the database giant would kill the product, take it proprietary, or somehow use it against MySQL — many of the same nightmare scenarios now speculated about the Sun purchase. It is worth noting that in the intervening years two things have occurred: Oracle has not killed or maimed InnoDB, and the open source community has preemptively created its own innovative solutions, thereby insulating open source users and customers from disaster should Oracle take a step in the wrong direction.

The real question is not which fork is the MySQL, but whether the multiple patch sets and forks indicate sickness or health for MySQL as a whole. Excluding Drizzle, all of the projects were started because someone who cared a great deal about the future of MySQL saw something wrong with MySQL’s development process (and for its part, Drizzle was spawned by even deeper dissatisfaction with the technical direction of MySQL). Surely that much concern on the part of the community signifies health. There is no telling which forks will prosper and which will fizzle out, but that depends to a large degree on Oracle, and how it governs the project in the future.

¿Usted piensa firmar esta petición en línea?

opensource, oracle

Migrando KodeGeek de CVS a Subversion en SF.net

Viernes, 25 de diciembre de 2009

Bueno, creo que ya era hora de hacerlo. Así que lo hice en varios pasos, siguiendo las recomendaciones de SF.net:

  • Hacer un respaldo del código existente en CVS:

    rsync -av rsync://elangelnegro.cvs.sourceforge.net/cvsroot/elangelnegro/* .

    Hasta ahora bien.
  • Crear un vaciado para SVN usando cvs2svn:
    Hmm, no tan rápido:

    auyan:sf josevnz$ ~/Downloads/cvs2svn-2.3.0/cvs2svn --dumpfile=svndump .
    ERROR: cvs2svn uses the anydbm package, which depends on lower level dbm
    libraries. Your system has dbm, with which cvs2svn is known to have
    problems. To use cvs2svn, you must install a Python dbm library other than
    dumbdbm or dbm. See http://python.org/doc/current/lib/module-anydbm.html
    for more information.
    auyan:sf josevnz$

    OK, vamos a ver que tan difícil es de hacer en OSX. Lo primero que hice fué actualizar Python (2.5 -> 3.1.1) usando un paquete pre-compilado:

    auyan:sf josevnz$ /Library/Frameworks/Python.framework/Versions/3.1/bin/python3
    Python 3.1.1 (r311:74543, Aug 24 2009, 18:44:04)
    [GCC 4.0.1 (Apple Inc. build 5493)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.

    El script cvs2svn fué escrito en Python 2.5, no 3. Así que lo convertimos con un poco de ayuda:

    auyan:sf josevnz$ /Library/Frameworks/Python.framework/Versions/3.1/bin/2to3 -w ~/Desktop/cvs2svn-2.3.0/cvs2svn
    RefactoringTool: Skipping implicit fixer: buffer
    RefactoringTool: Skipping implicit fixer: idioms
    RefactoringTool: Skipping implicit fixer: set_literal
    RefactoringTool: Skipping implicit fixer: ws_comma
    RefactoringTool: Refactored /Users/josevnz/Desktop/cvs2svn-2.3.0/cvs2svn
    --- /Users/josevnz/Desktop/cvs2svn-2.3.0/cvs2svn (original)
    +++ /Users/josevnz/Desktop/cvs2svn-2.3.0/cvs2svn (refactored)
    @@ -69,7 +69,7 @@

    try:
    svn_main(os.path.basename(sys.argv[0]), sys.argv[1:])
    -except FatalException, e:
    +except FatalException as e:
    sys.stderr.write(str(e) + '\n')
    sys.exit(1)

    RefactoringTool: Files that were modified:
    RefactoringTool: /Users/josevnz/Desktop/cvs2svn-2.3.0/cvs2svn

    Más las librerías de cvs2svn:

    auyan:sf josevnz$ for file in `ls ~/Desktop/cvs2svn-2.3.0/cvs2svn_lib/*.py`; do /Library/Frameworks/Python.framework/Versions/3.1/bin/2to3 -w $file; done
    # Montón de paja omitida por brevedad :)

    Además de unos pequeños cambios en el código (las líneas que requieren edición tienen número por delante):


    1 #!/Library/Frameworks/Python.framework/Versions/3.1/bin/python3
    2 ##!/usr/bin/env python
    3 # (Be in -*- python -*- mode.)
    55 #if not ((2,4) < = version < (3,0)):
    56 # sys.stderr.write(
    57 # version_error + ' version %d.%d.%d.\n'
    58 # % (version[0], version[1], version[2],)
    59 # )
    60 # sys.stderr.write(version_advice)
    61 # sys.exit(1)

    Sin embargo el Python 3 es anal acerca de la mezcla de espacios y tabulación:

    ...
    TabError: inconsistent use of tabs and spaces in indentation

    Traté de arreglarlo rápidamente, pero lo que hice fué empeorar la situación:

    auyan:sf josevnz$ perl -p -i -e 's#\t# #g' /Users/josevnz/Desktop/cvs2svn-2.3.0/cvs2svn_lib/*.py
    auyan:sf josevnz$ ~/Desktop/cvs2svn-2.3.0/cvs2svn --dumpfile=svndump .
    Traceback (most recent call last):
    File "/Users/josevnz/Desktop/cvs2svn-2.3.0/cvs2svn", line 68, in <module>
    from cvs2svn_lib.main import svn_main
    File "/Users/josevnz/Desktop/cvs2svn-2.3.0/cvs2svn_lib/main.py", line 30, in <module>
    from cvs2svn_lib.svn_run_options import SVNRunOptions
    File "/Users/josevnz/Desktop/cvs2svn-2.3.0/cvs2svn_lib/svn_run_options.py", line 40, in <module>
    from cvs2svn_lib.svn_output_option import DumpfileOutputOption
    File "/Users/josevnz/Desktop/cvs2svn-2.3.0/cvs2svn_lib/svn_output_option.py", line 83
    cvsauthor = to_utf8(cvsauthor)
    ^
    IndentationError: unindent does not match any outer indentation level

    No me jodan. Demasiado tratar de que este script funcione con Python 3, ¿será más fácil instalar las librerías faltantes y que Python 2.5 las reconozca?

    Me decidí entonces de usar las librerías compatibles con DBM. Nos las bajamos de Oracle y compilamos:


    auyan:db-4.8.26 josevnz$ pwd
    /Users/josevnz/Desktop/db-4.8.26
    auyan:db-4.8.26 josevnz$ ./dist/configure && make
    auyan:db-4.8.26 josevnz$ cd build_unix/
    auyan:build_unix josevnz$ ../dist/configure && make && make install && export DYLD_LIBRARY_PATH=/usr/local/BerkeleyDB.4.8/lib:$DYLD_LIBRARY_PATH

    Instalé entonces capa de Python que enlaza con DBM, bsddb3 4.8.1:

    auyan:bsddb3-4.8.1 josevnz$ pwd
    /Users/josevnz/Downloads/bsddb3-4.8.1
    auyan:bsddb3-4.8.1 josevnz$ python setup.py build

    Y como todo salió bien:

    sudo python setup.py install

    Pero ¿funcionará ahora?:


    auyan:sf josevnz$ ~/Downloads/cvs2svn-2.3.0/cvs2svn --dumpfile=svndump .
    # Omitiendo salida del comando....
    cvs2svn Statistics:
    ------------------
    Total CVS Files: 362
    Total CVS Revisions: 603
    Total CVS Branches: 0
    Total CVS Tags: 0
    Total Unique Tags: 0
    Total Unique Branches: 0
    CVS Repos Size in KB: 7377
    Total SVN Commits: 228
    First Revision Date: Thu Jan 13 16:10:27 2005
    Last Revision Date: Sat Jul 18 23:49:03 2009
    ------------------
    Timings (seconds):
    ------------------
    2.132 pass1 CollectRevsPass
    0.063 pass2 CleanMetadataPass
    0.009 pass3 CollateSymbolsPass
    0.163 pass4 FilterSymbolsPass
    0.017 pass5 SortRevisionSummaryPass
    0.031 pass6 SortSymbolSummaryPass
    0.089 pass7 InitializeChangesetsPass
    0.095 pass8 BreakRevisionChangesetCyclesPass
    0.092 pass9 RevisionTopologicalSortPass
    0.031 pass10 BreakSymbolChangesetCyclesPass
    0.080 pass11 BreakAllChangesetCyclesPass
    0.062 pass12 TopologicalSortPass
    0.169 pass13 CreateRevsPass
    0.016 pass14 SortSymbolsPass
    0.009 pass15 IndexSymbolsPass
    1.075 pass16 OutputPass
    4.134 total

    ¡Exito! :D

  • Importar el código de nuevo en SVN:

    Ahora no queda otra más que tratar de importar el archivo que fué creado en el paso anterior:

    auyan:sf josevnz$ ls -l svndump
    -rw-r--r-- 1 josevnz josevnz 8600150 Dec 25 20:53 svndump
    gzip svndump

    SF.net tiene una consola especial para estos casos. En este caso cree mi nueva sesión y me dispuse a trabajar:

    auyan:~ josevnz$ ssh -t josevnz,elangelnegro@shell.sourceforge.net create
    The authenticity of host 'shell.sourceforge.net (216.34.181.119)' can't be established.
    RSA key fingerprint is b4:c5:6c:36:f7:ad:2c:23:52:e1:84:3e:77:61:5d:59.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added 'shell.sourceforge.net,216.34.181.119' (RSA) to the list of known hosts.
    josevnz,elangelnegro@shell.sourceforge.net's password:

    Requesting a new shell for "josevnz" and waiting for it to start.
    queued... creating... starting...
    This is an interactive shell created for user josevnz,elangelnegro.
    Use the "timeleft" command to see how much time remains before shutdown.
    Use the "shutdown" command to destroy the shell before the time limit.
    For path information and login help, type "sf-help".

    [josevnz@shell-23008 ~]$
    [josevnz@shell-23008 ~]$ timeleft
    Time remaining before shutdown: 239 minutes.

    Subiendo el código:

    auyan:sf josevnz$ rsync -aiv svndump.gz josevnz,elangelnegro@web.sourceforge.net:htdocs
    josevnz,elangelnegro@web.sourceforge.net's password:
    building file list ... done

    sent 6067785 bytes received 42 bytes 49132.20 bytes/sec
    total size is 6066914 speedup is 1.00

    Y finalmente el proceso de importación en varios pasos:

    [josevnz@shell-23008 ~]$ adminrepo --checkout svn
    Lock and checkout the svn repository for elangelnegro? [ny] y
    Repository locked -- starting checkout copy.
    ...

    [josevnz@shell-23008 ~]$ ls -l /home/groups/e/el/elangelnegro/htdocs/svndump.gz
    -rw-rw-r-- 1 josevnz elangelnegro 6066914 Dec 26 01:53 /home/groups/e/el/elangelnegro/htdocs/svndump.gz
    [josevnz@shell-23008 ~]$ gunzip /home/groups/e/el/elangelnegro/htdocs/svndump.gz
    [josevnz@shell-23008 ~]$ svnadmin load /svnroot/elangelnegro < /home/groups/e/el/elangelnegro/htdocs/svndump
    ....
    ------- Committed revision 227 >>>

    < << Started new transaction, based on original revision 228
    * editing path : trunk/src/java/main/com/kodegeek/blog/twitter/TwitterPing.java ... done.
    [josevnz@shell-23008 ~]$ adminrepo --save svn

  • Desactivar el soporte de CVS para el proyecto

    Primero verifiqué que podía acceder el nuevo repositorio:

    svn co https://elangelnegro.svn.sourceforge.net/svnroot/elangelnegro elangelnegro

    Y después de eso desactive el acceso a CVS.

Así que de ahora en adelante el código está disponible usando SVN en la siguiente ubicación:

  • svn co https://elangelnegro.svn.sourceforge.net/svnroot/elangelnegro elangelnegro

¡Que lo disfruten!

java, kodegeek, opensource, programación

Stupid Zombie 1.1 ya fué liberado, quizas la última versión

Miércoles, 28 de octubre de 2009

Hoy me tomé el día libre y decidí trabajar en el proyecto. Después de una demora de varios meses (en los cuales puse mis energías en otros proyectos personales) decidí liberar el código de la versión 1.1.

Debo decir que me costó mucho mantener el foco y quizas esta sea la última versión de StupidZombie por un buen tiempo; Es un proyecto que requiere tiempo y la herramienta se encuentra en un punto en donde hace lo que quiere y su principal cliente (yo) está contento como se comporta.

¿Habrán mejoras? ¿Nuevas versiones? No lo sé. He visto muchas descargas pero nadie ha escrito pidiendo cosas nuevas (hay interés sin embargo, incluso existe un proyecto derivado en Kenai.com el cual tiene un instalador nativo para Windows).

El proyecto es formal, tiene artefactos como documentación, sitio web. Sin embargo mantener esos artefactos no es divertido y toma tiempo el cual quiero usar para echar código, lo cual fué la idea inicial del proyecto. Así que sin ayuda adicional simplemente he decidido enfocarme en aprender nuevas cosas, de manera más informal (por ejemplo, no he tenido tiempo para jugar con mi teléfono con Android).

Asi que espero que disfruten esta versión. Pienso mantenerla en linea de manera indefinida, pero mi centro de atención definitivamente está en otro lado ;)

José.

java, kodegeek, opensource, programación

Book review: Even Faster Web Sites, by Steve Souders (and others)

Martes, 4 de agosto de 2009

Even Faster Websites

Even Faster Websites


Thanks to the O’Reilly Facebook group I got the chance to review the book ‘Even Faster Web Sites‘, by Steve Souders. Please read below to get an idea on what to expect about this new title from O’Reilly ($34.99).

Synopsis:

This book is a collection of practical tips and advice on how to optimize web pages, focusing in client side optimizations. It explains how to reduce downloading times through coding techniques, CSS and image optimization, speed up page rendering and code instrumentation so it will definitely will appeal developers and designers that work with Ajax or regular JavaScript sites.

The book is written by several authors (the main one is Steve Souders), and it was specially nice to read Tony Gentilcore (the author of the popular plugin ‘Fasterfox‘) writting about some gotchas of the use of Gzip to serve web pages, among other things.

How is it organized:

The book is organized in 14 chapters, each one of them can be read independently (more or less) from each other. They are packed with good examples that are brief but illustrate each technique, which makes this book a good reference guide. Also the appendix (which is so big it should be called the chapter 15) is loaded with really useful tools that can be used to detect and diagnose problems on a website (the majority of them are free).

Missing things:

Not everything is perfect. The book focus almost on Javascript optimizations and loading techniques but doesn’t mention what can be done with other important technologies like Flash, SilverLight or even Java Webstart (JavaFx is gaining traction these days).

Forgets to mention server side techniques like connection and thread pools, page caching (server side not client side), among others, or common tricks used in well known frameworks like Ruby & Rails, Java Servlets (PHP is mentioned briefly though).

Also missing is the coverage of server side tools like vmstat, mpstat, top, free, tcpdump or ethereal (Linux, Solaris, BSD or UNIX tools) which could be really useful to diagnose performance issues on the web application.

To be fair this is a book focused on client side techniques and talking about server side optimizations will make it pretty big, so maybe the tittle of the book should be changed to ‘Even Faster Web Sites, client optimizations’ (I am pretty sure the authors have tons of server side techniques to share as well, so maybe this could be a second book on the subject? :) )

Conclusion:

It is another solid title from O’Reilly that delivers concrete techniques that can be used to speed up websites that rely on Javascript, images and CSS to present the content to the end users. The lack of the mention of the existence of server side techniques is a minor glitch but still there is great value on each one of the chapters of this reference book (I am going through them to make this blog to load faster ;) )

Kodegeek stars: 4 of 5.

opensource, programación , , , , , ,

Localización en Java (III): El caso de StupidZombie y JFileChooser

Lunes, 20 de julio de 2009

Bueno, resulta que otro desarollador de Argentina se topó con mi problema (del cual hablé en un articulo) de hace más de un mes en el foro de Sun y logró buscar el resto de las etiquetas para hacer que JFileChooser funcione en otro idioma (ya saben, el problema de localización):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
Jose V Nunez Z,
 
You are watching the thread "Localization problems for JFileChooser in OSX", which was updated on Jul 19, 2009 9:34:41 PM by arg_slo:
 
<http ://forums.sun.com/thread.jspa?threadID=5393267>
 
For your convenience, the new message is included below:
--------------------------------------------------------------
Hello! Here the code I promised. In the JFileChooser.properties file I put this values:
 
FileChooser.fileNameLabelText=Nombre del archivo
FileChooser.homeFolderToolTipText=Directorio hogar
FileChooser.newFolderToolTipText=Nueva carpeta
FileChooser.listViewButtonToolTipTextlist=Ver lista
FileChooser.detailsViewButtonToolTipText=Detalles
FileChooser.newFolderButtonText=Nueva carpeta
FileChooser.lookInLabelText=Buscar en
FileChooser.filesOfTypeLabelText=Archivos de tipo
FileChooser.upFolderToolTipText=Subir un nivel
FileChooser.saveInLabelText=Guardar en
 
FileChooser.saveButtonText:Guardar
FileChooser.newFolderErrorSeparator::
FileChooser.other.newFolder:Carpeta nueva
FileChooser.acceptAllFileFilterText:Todos los archivos
FileChooser.directoryOpenButtonMnemonic:82
FileChooser.updateButtonToolTipText:Actualizar lista de directorios
FileChooser.cancelButtonText:Cancelar
FileChooser.directoryDescriptionText:Directorio
FileChooser.updateButtonMnemonic:84
FileChooser.cancelButtonMnemonic:67
FileChooser.newFolderErrorText:Error al crear una nueva carpeta
FileChooser.saveButtonMnemonic:71
FileChooser.cancelButtonToolTipText:Cuadro de diálogo para cancelar elector de archivo
FileChooser.directoryOpenButtonToolTipText:Abrir directorio seleccionado
FileChooser.helpButtonText:Ayuda
FileChooser.updateButtonText:Actualizar
FileChooser.helpButtonToolTipText:Ayuda elector de archivos
FileChooser.saveDialogTitleText:Guardar
FileChooser.openButtonToolTipText:Abrir archivo seleccionado
FileChooser.openButtonText:Abrir
FileChooser.fileSizeMegaBytes:{0} MB
FileChooser.fileSizeGigaBytes:{0} GB
FileChooser.win32.newFolder:Carpeta nueva
FileChooser.openButtonMnemonic:65
FileChooser.helpButtonMnemonic:89
FileChooser.fileSizeKiloBytes:{0} KB
FileChooser.openDialogTitleText:Abrir
FileChooser.fileDescriptionText:Archivo genérico
FileChooser.directoryOpenButtonText:Abrir
FileChooser.saveButtonToolTipText:Guardar archivo seleccionado
FileChooser.other.newFolder.subsequent:Carpeta nueva.{0}
FileChooser.win32.newFolder.subsequent:Carpeta nueva ({0})
 
 
and it works perfectly, all in spanish!
 
José from Bs As, Argentina
--------------------------------------------------------------
 
To respond to this post, please click the following link:
</http><http ://forums.sun.com/thread.jspa?messageID=10769968>
</http>

¡Genial!. Aún no he probado lo que el me envió pero parece razonable. Muchas gracias a José (tocayo tenia que ser) o como dicen por allá, gracias ¡Che!

java, opensource, programación , , , , , ,

Enviando Tweets desde Java usando Twitter4J: ¿Como proteger consumerKey and consumerSecret?

Sábado, 18 de julio de 2009

Bueno, mientras buscaba como agregar soporte para Facebook en StupidZombie, me conseguí con un problema interesante. Twitter4J requiere que definamos consumerKey y consumerSecret en el objeto Twitter en cada llamada.

Lo cual trae problemas, ya que si distribuimos esas claves entonces cualquiera puede hacerse pasar por nuestra aplicación (No es un problema en una aplicación web pero si en una de escritorio). El problema es peor si la aplicación es OpenSource porque entonces un Script-Kiddie puede hacer de las suyas sin mucho esfuerzo.

1
2
//twitter.setOAuthConsumer(consumerKey, consumerSecret);
accessToken = twitter.getOAuthAccessToken(token, tokenSecret, pin);

Lo que mas me preocupa es que autenticación de escritorio no funciona si no lo definimos. Por ejemplo, en el código que escribí la vez pasada esto es lo que ocurre si no incluimos la linea que esta comentada en el párrafo anterior:

1
2
3
Jul 18, 2009 10:18:49 PM com.kodegeek.blog.twitter.TwitterPing getAccessToken
INFO: Token=Ujq2pzpG7PwZVAJmGHjWrDiVzFz6wfmxzx9r85y7s TokenSecret=hBHVuOWdJPBe5r3iVXklSJuwawssjqoBslLHXhzlE Pin=4129706
Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Neither user ID/password combination nor OAuth consumer key/secret combination supplied

Por ahora ando preguntándole al autor como resolver este asunto. La gente de Java API de FaceBook tiene una solución a este problema, lo hacen creando algo llamado ‘temporary secret

Actualización: El siguiente “hack” parece funcionar, pues el código de HttpClient revizar por NULL o cadenas de caracteres vacias:

1
2
3
		Twitter twitter = new Twitter();
		twitter.setOAuthConsumer(" ", " ");
		twitter.setOAuthAccessToken(accessToken);

internet, java, kodegeek, opensource, programación , , ,

Mientras Brasil le da un abrazo a Java, en Venezuela lo satanizan

Lunes, 13 de julio de 2009

Bueno, para nadie es un secreto que Brasil le lleva años luz a Venezuela en materia de desarrollo de software. Ya hace años atrás ellos participan en Internet 2 y hoy leyendo entre mis bitácoras favoritos me conseguí esta perla.

Bueno, no sólo de política se puede aprender de nuestros vecinos, ¿no es así?

java, opensource, programación, venezuela , , ,

El Blogaton de Eclipse

Miércoles, 8 de julio de 2009

Bueno, después de participar en el Blogaton de Eclipse (y de ser el único escritor en Español) me gané mi camisa con el logo de Eclipse :)

¡Muchas gracias a los panas de Eclipse!

java, opensource, programación , ,

Como enviar Tweets desde Java usando Twitter4J

Domingo, 5 de julio de 2009

Una de las cosas que quiero hacer para la versión 1.1 de StupidZombie es agregarle soporte para actualizar el estado de Twitter cada vez que hacemos un ping. Como siempre es el asunto de construir algo desde cero o utilizar una herramienta existente y en el caso de StupidZombie lo que quiero es implementar la funcionalidad lo más rápido posible (por ejemplo, no tengo tiempo para seguir los cambios en el API de Twitter).

Después de buscar en la red me conseguí que Twitter4J es quizas la versión más madura para Java (recuerden, StupidZombie está escrito en ese lenguaje). Ni corto ni perezoso me puse a echar código y al final me decidí escribir una pequeña aplicación en Swing la cual hace lo siguiente:

  1. Autoriza la aplicación contra su cuenta de Twitter
  2. Obtiene un PIN y claves especiales de autorización (lo cual no es lo mismo que su usuario clave, a eso se le conoce como OAuth).
  3. Envia un mensaje (tweet) a su cuenta en Twitter desde la aplicación en Java

Nota, si usted es el desarrollador de la aplicación entonces lo primero que hay que hacer es registrar una aplicación nueva en Twitter (sus usuarios pueden saltarse este paso). Una vez terminado se ve como lo siguiente:

Registered applications
Aplicaciones registradas en Twitter

Una vez registrada debemos pasar “Consumer key” y “Consumer Secret” a nuestro código de Twitter4j, yo lo hago en el constructor:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
	private TwitterPing(String consumerKey, String consumerSecret) throws TwitterException {
		super("KodeGeek simple Twitter pinger");
		if (consumerKey == null) {
			throw new IllegalArgumentException("Consumer key is missing");
		}
		if (consumerSecret == null) {
			throw new IllegalArgumentException("Consumer secret is missing");
		}
		twitter = new Twitter();
		twitter.setOAuthConsumer(consumerKey, consumerSecret);
		requestToken = twitter.getOAuthRequestToken();
 
		setPreferredSize(new Dimension(600, 400));
 
	}

Desde la aplicación en Swing hacemos clic en el botón que dice “Authorize KodeGeek on Tweeter”. Si el soporte de Java para escritorio está activado entonces el navegador por omisión se arrancará e iremos a Twitter:

Allowing KodeGeek
Hora de autorizar a KodeGeek :)

El código que hace esto es super sencillo :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
	/**
	 * Send the user to the authorization webpage
	 * @throws Exception 
	 */
	private void sendUserToAuthUrl() throws Exception {
		final TwitterPing instance = this;
		log.log(Level.INFO, String.format("Got authorization URL: %s", requestToken.getAuthorizationURL()));
		if (Desktop.isDesktopSupported()) {
			Desktop.getDesktop().browse(new URI(requestToken.getAuthorizationURL()));
			log.info("Redirection was successfull.");
		} else {
			EventQueue.invokeLater(new Runnable() {
 
				@Override
				public void run() {
					JOptionPane.showMessageDialog(
							instance, 
							String.format("Cannot call default browser, please go to this URL instead: %s", requestToken.getAuthorizationURL()), 
							"Problems trying to send the user to default page", 
							JOptionPane.ERROR_MESSAGE);
				}
			});
		}
	}

Si la autorización es aceptada (como se ve a continuación):

KodeGeek twitter application
La autorización trabajó

Entonces podemos pedir el token de acceso usando el PIN obtenido en el paso anterior:

1
2
3
4
5
6
7
8
9
10
	/**
	 * Call this method only after the user has authorized the application
	 * @throws TwitterException 
	 */
	private void getAccessToken(final String pin) throws TwitterException {
		log.info(String.format("Got token: %s, Got secret: %s", requestToken.getToken(), requestToken.getTokenSecret()));
		accessToken = twitter.getOAuthAccessToken(requestToken, pin);
		if (accessToken != null)
			log.info(String.format("Got access token for user %s", accessToken.getScreenName()));
	}

Lo cual se ve así:

Ping number, required for desktop appsNúmero PIN para darle acceso a nuestro cliente a la cuenta de Twitter

Si todo va bien entonces podemos mostrar los 3 pedazos de la autorización necesarios para poder enviar un Tweet:

After geting the auth tokens
La aplicación tiene todo lo que necesita. Hora de enviar un tweet

Ya hacer el tweet es trivial con el siguiente pedazo de código:

1
2
3
4
5
6
7
8
9
10
	/**
	 * Send a tween using an existing AccessToken
	 * @param tweet The update to set
	 * @throws TwitterException If there is a problem updating the status
	 * @return The status of the tweet
	 */
	private Status sendTweet(final String tweet) throws TwitterException {
		twitter.setOAuthAccessToken(accessToken);
		return twitter.updateStatus(tweet);
	}

Al final, ¡exito!:

Success, tweet update
Como se ve nuestro mensaje en Twitter, enviado desde Java

El protocolo de Twitter soporta muchísimas cosas más. En particular le recomiendo que se lean la documentación relacionada para entender más como trabajan las cosas, en especial la autenticación usando OAth. Ahhh, y por supuesto aquí les dejo el código fuente completo para que se diviertan echando código.

Hasta la siguiente entrega, dentro de unas horas me sale ir a una parrillada :)

Veneblogs: , , , ,

Blogalaxia: , , , ,

To2Blogs: , , , ,

Technorati: , , , ,

Del.icio.us: , , , ,

java, kodegeek, opensource, programación , , , , , ,