Archivo

Archivo para marzo, 2008

Mejoras al RSS de Globovision

Sábado, 29 de marzo de 2008
Comentarios desactivados

Bueno, he estado MUY ocupado debido a lo movido que ha estado el mercado de opciones estas últimas 3 semanas (incluyendo la caida estrepitosa de Bearn Sterns). Sin embargo hoy corregí un par de errores en el archivo de Ant y al fin monté la primera versión en Java del convertido de HTML a RSS de Globovisión (en un articulo anterior les mostraba el código y porqué me decidí a escribirlo).

La versión de Perl quedará en la historia :)

Buscar en otros sitios:

Blogalaxia:, , ,
Technorati:, , ,
To2blogs:, , ,
Del.icio.us:, , ,

java , , ,

Trucos UNIX: ¿Como matar todos los procesos de un usuario?

Sábado, 15 de marzo de 2008

Bueno, si usted tiene un montón de servidores a los cuales se puede conectar con SSH y lo quiere es matar todos los procesos de un usuario en particular, entonces puede usar algo como esto:

1 #!/bin/bash
2 for machine in `cat myhostfile`; do
3 ssh -x -q -f $machine "/usr/bin/pkill -9 -U myuser"
4 done

Funciona bajo Solaris 7 o superior y Linux. OS X por supuesto no lo tiene :(

Buscar en otros sitios:

Blogalaxia:, , ,
Technorati:, , ,
To2blogs:, , ,
Del.icio.us:, , ,

Sin categoría , , ,

¡Java es el nuevo Perl!

Miércoles, 12 de marzo de 2008

¿Java es el nuevo Perl?. ¿Será porque está muerto? No, todo lo contrario, gracias a scripting languajes lenguajes interpretados Java sigue creciendo en direcciones muy diversas.

Quiero empezar este pequeño análisis diciendo que yo adoro Perl; Yo lo aprendí por mi cuenta (si, para ese entonces no habían cursos de Perl y quizas el único manual autorizado era el libro del camello de O’Reilly). La versatilidad del lenguaje, la cantidad de librerías en CPAN y la enorme cantidad de código y ejemplos de como resolver problemas en la Internet lo hicieron el favorito.

Pero vamos a estar claros: Perl lleva años en el abandono. El modelo de “threads” es un fastidio, la orientación a objetos en Perl si bien no es difícil tiene varias diferencias comparada con otros lenguajes (y por ende es más difícil de aprender en mi opinión, al menos que a usted no le cause picazón el “bless”) pero sobre todo, Parrot (el nuevo interprete de Perl 6) no termina de salir a la luz publica.

Y entonces viene Java con su soporte a lenguajes interpretados como Python (Jython), Ruby (JRuby) y sus lenguajes con merito propio como BeanShell y Groovy. Sin embargo nadie ha escrito un JPerl.

Mi tiempo es muy limitado estos días (trabajo, un niño pequeño) como para ponerme a inventar a aprender un lenguaje exótico el cual nunca voy a utilizar o sacar algún provecho; Sin embargo (y gracias a Java) he podido jugar con Jython en mi trabajo aprovechando código que ya tenemos escrito en Java mientras hago las mismas cosas que hubiera hecho en Perl. Por otro lado, tenemos ya código escrito en BeanShell lo cual significa que yo no seré el único en mi grupo que puede mantener el código.

Es muy interesante la experiencia, ya que por ejemplo aún sin saber la sintaxis completa de Python puedo resolver problemas ya que puedo importar clases de Java y utilizar sus funcionalidades. Si, es una muleta pero a la vez mantiene la productividad y me permite aprender el lenguaje al mismo tiempo. El mismo argumento va para JRuby.

¿Jython vs. JRuby en mi oficina? Bueno, Python se ve interesante, pero como dijo un PHD de mi grupo, “a quien se le ocurre utilizar un lenguaje que utiliza identación para definir alcance”. También tuve problemas cuando traté de importar el modulo de expresiones regulares (import re).

¿Porque no un JPerl (no como el paquete JPerl, escrito en C++)? Quizas es la sintaxis, aunque no soy el primero que se hace la misma pregunta.

En fin, parece ser que la decisión de que usar como scripting languages en Java se reduce en mi caso a:

  • Beanshell: No tiene curva de aprendizaje comparado con Jython, JRuby, además de que va a ser parte del JDK en un futuro no muy lejano (estandar de Java)
  • JRuby: Más popular que Python (gracias a Rails). Y no usa identación como loco :)

Lo siento Perl. Pero Parrot te mató y le mundo se sigue moviendo. Por ahora, tu futuro está en la misma liga que el Kernel de GNU Hurd (el cual existe y a nadie le vale un bledo :)).

Buscar en otros sitios:

Blogalaxia:, , , ,
Technorati:, , , ,
To2blogs:, , , ,
Del.icio.us:, , , ,

java , , , ,

RSS de Globovision está roto II: Java al rescate

Domingo, 9 de marzo de 2008
Comentarios desactivados

Bueno, varias horas después y sin respuesta de Lunar Pages, me decidí a reescribir el programa usando Java. Lo primero que intenté fue tratar de procesar la página de noticias de Globovision.com, pero quienes hicieron el código del sitio Web simplemente no saben de programación HTML, y el daño es demasiado para el ya sensible JTidy:


line 15 column 1 - Warning: unexpected </head> in <link>
line 20 column 165 - Warning: unexpected </a> in <img>
line 20 column 169 - Warning: unexpected </td> in <img>
line 23 column 97 - Warning: unexpected </td> in <img>
line 24 column 5 - Warning: unexpected </tr> in <img>
line 26 column 93 - Warning: unexpected </a> in <img>
line 26 column 97 - Warning: unexpected </td> in <img>
This document has errors that must be fixed before
using HTML Tidy to generate a tidied up version.

Asi que, ¿como procesar un documento que está así de roto en Java?

Bueno, el sitio de Java tiene mucha documentación y una de las cosas interesantes que muestran es como usar el parser que tiene Swing pero afuera de sus componentes gráficos. Esto resolvió perfectamente como obtener e iterar un documento roto, ahora sólo quedaba resolver el problema de escribir el RSS lo más fácil posible.

Después de buscar un poco me decidí a usar la librería Rome. No es pesada, lo único fastidioso es que requiere JDOM. Bueno, antes tuve que pedir que instalarn Expat para Perl, asi que mejor no me quejo :)

El código como siempre está en Source Forge, en el sitio de KodeGeek. Se los pongo aquí por comodidad:

  1 package com.kodegeek.blog.rss;
2
3 import java.io.BufferedReader;
4 import java.io.FileWriter;
5 import java.io.InputStreamReader;
6 import java.io.Reader;
7 import java.io.Writer;
8 import java.net.URL;
9 import java.util.ArrayList;
10 import java.util.Date;
11 import java.util.List;
12 import java.util.logging.Level;
13 import java.util.logging.Logger;
14
15 import javax.swing.text.AttributeSet;
16 import javax.swing.text.MutableAttributeSet;
17 import javax.swing.text.html.HTML;
18 import javax.swing.text.html.HTML.Tag;
19 import javax.swing.text.html.HTMLEditorKit.ParserCallback;
20 import javax.swing.text.html.parser.ParserDelegator;
21
22 import com.sun.syndication.feed.synd.SyndEntry;
23 import com.sun.syndication.feed.synd.SyndEntryImpl;
24 import com.sun.syndication.feed.synd.SyndFeed;
25 import com.sun.syndication.feed.synd.SyndFeedImpl;
26 import com.sun.syndication.io.SyndFeedOutput;
27
28
29 /**
30 * Program that converts the main summary news from Globovision.com
to RSS format.
31 * @author josevnz at kodeeek.com
32 *

License: GPL


33 * I use a combination of Yahoo Pipes and Google Reader to keep me
updated about news of any kind. However, some websites like
34 * Globovision.com still don't have a proper RSS feed,
so one day I
decided to create my own mashup :).
35 * It worked for a while until my Blog hosting provider
decided to
remove the XML::RSS Perl module I asked to install for me.
Because of that,
36 * this Java version was born.
37 */

38 public final class GlobovisionHtml2Rss {
39
40 public static final String
GLOBOVISION_URL = "http://globovision.com";
41 public static final String NEWS_URL =
GLOBOVISION_URL + "/history.php?cha=1&pag=1";
42
43 private static Logger log;
44 private static final long DEFAULT_WAIT = 1000L*60L*5L;
45
46 // Do not alow instances of this class to be created
47 private GlobovisionHtml2Rss() {
48 // Empty
49 }
50
51 static {
52
53 log = Logger.getLogger(GlobovisionHtml2Rss.class.getName());
54 }
55
56 /**
57 * @param args
58 */

59 public static void main(String[] args) throws Exception {
60
61 try {
62 fetch(NEWS_URL, args[0]);
63 } catch (Exception exp) {
64 log.log(Level.SEVERE, "Cannot recover from this
exception"
, exp);
65 }
66 }
67
68 /**
69 * Try to fetch the URL and convert it to a Document
70 * @param url
71 * @param outfile
72 * @return
73 * @throws Exception
74 */

75 private static void fetch(String url, String outfile)
throws
Exception {
76 Reader reader = null;
77 Writer writer = null;
78 SyndFeed feed;
79 List <SyndEntry>news = new ArrayList<SyndEntry>();
80 try {
81 feed = new SyndFeedImpl();
82 feed.setAuthor("Jose Nunez, josevnz at kodegeek.com");
83 feed.setDescription("Globovision.com news - Brough to
you by http://KodeGeek.com"
);
84 feed.setFeedType("rss_1.0");
85 feed.setLink("http://www.kodegeek.com/rss/globovision.rss");
86 feed.setTitle("Globovision.com Venezuelan News");
87 URL globovisionURL = new URL(url);
88 reader = new BufferedReader(
new
InputStreamReader(globovisionURL.openStream()));
89 ParserDelegator parser = new ParserDelegator();
90 parser.parse(reader, new GlobovisionHtml2Rss().
new GlobovisionParser(news), false);
91 if (news.size() > 0) {
92 feed.setEntries(news);
93 writer = new FileWriter(outfile);
94 SyndFeedOutput feedOut = new SyndFeedOutput();
95 feedOut.output(feed, writer);
96 }
97 } catch (Exception exp) {
98 throw new Exception("Unexpected problem", exp);
99 } finally {
100
101 if (reader != null) {
102 reader.close();
103 }
104
105 if (writer != null) {
106 writer.close();
107 }
108 news.clear();
109 }
110 }
111
112 /**
113 * Helper class used to parse Globovision news website
114 * @author josevnz
115 */

116 class GlobovisionParser extends ParserCallback {
117
118 private boolean getHeadline = false;
119 private AttributeSet attribute;
120 private List <SyndEntry>entries;
121
122 public GlobovisionParser(List <SyndEntry>entries) {
123 this.entries = entries;
124 }
125
126 /**
127 * Globovision HTML is so broken than we will ignore the errors
silently.
128 * Increase the logger verbosity to see the errors
129 */

130 public void handleError(String errorMsg, int pos) {
131 log.log(Level.FINE, String.format("%s, %d", errorMsg, pos));
132 }
133
134 /**
135 * Looking for: tag = "a" and attr{href} =~ /news.php?nid=\d+/
136 * @param t Tag
137 * @param a Attribute set
138 * @param pos position
139 */

140 public void handleStartTag(Tag t, MutableAttributeSet a, int pos) {
141 if (
142 (t == Tag.A) &&
143 (a.getAttribute(HTML.Attribute.HREF) != null)
&&
144 (a.getAttribute(HTML.Attribute.HREF).
toString
().matches("news\\.php\\?nid=\\d+"))
145 ) {
146 attribute = a.copyAttributes();
147 log.log(Level.FINE,
String.format("Tag: %s, attributes: %s", t, a));
148 getHeadline = true;
149 }
150
151 }
152
153 /**
154 * Get the headline and also write the RSS entry
155 * @param data Text next to the headline
156 * @param pos position
157 */

158 public void handleText(char[] data, int pos) {
159 if (getHeadline) {
160 SyndEntry entry = new SyndEntryImpl();
161 entry.setLink(String.format("%s/%s",
GLOBOVISION_URL, attribute.getAttribute(HTML.Attribute.HREF).toString()));
162 entry.setPublishedDate(new Date());
163 entry.setTitle(new String(data));
164 entries.add(entry);
165 getHeadline = false;
166 attribute = null;
167 }
168 }
169
170
171
172 }
173
174 }

Debo admitir que el proceso para volver a crear el RSS de Globovision desde Java fué más complejo y requirió más código que el de Perl (aunque terminé mi nueva versión antes que Lunar Pages reemplazara el modulo perdido, unas cuantas horas después) . Pero por otro lado, aprendí más trucos con este y al menos ya no tengo que preocuparme por pedirles que instalen módulos no estandares.

Nota a los subscriptores del la fuente de Globovision en RSS: La versión vieja ya funciona de nuevo. Pienso montar la nueva dentro de poco con nuevas mejoras. Una de ellas es que este tipo de error no afectará el programa (aunque no doy ningún tipo de garantias por soporte gratis :)).

To Lunar Pages: Response to this issue was kind of slow, thanks for fixing the issue on my account anyways.

Buscar en otros sitios:

Blogalaxia:, , , ,
Technorati:, , , ,
To2blogs:, , , ,
Del.icio.us:, , , ,

java , , , ,

RSS de Globovision está roto I

Domingo, 9 de marzo de 2008

Creo que mi proveedor de hospedaje decidió remover el modulo de Perl XML::RSS que utilizo para crear el RSS de Globovisión el día de hoy:


Can't locate XML/RSS.pm in @INC (@INC contains:
/usr/lib/perl5/5.8.5/i386-linux-thread-multi
/usr/lib/perl5/5.8.5 /usr/lib/perl5/site_perl/5.8.5/
i386-linux-thread-multi
/usr/lib/perl5/site_perl/5.8.4/i386-linux-thread-multi
/usr/lib/perl5/site_perl/5.8.3/i386-linux-thread-multi
/usr/lib/perl5/site_perl/5.8.2/i386-linux-thread-multi
/usr/lib/perl5/site_perl/5.8.1/i386-linux-thread-multi
/usr/lib/perl5/site_perl/5.8.0/i386-linux-thread-multi
/usr/lib/perl5/site_perl/5.8.5 /usr/lib/perl5/site_perl/5.8.4
/usr/lib/perl5/site_perl/5.8.3 /usr/lib/perl5/site_perl/5.8.2
/usr/lib/perl5/site_perl/5.8.1 /usr/lib/perl5/site_perl/5.8.0
/usr/lib/perl5/site_perl /usr/lib/perl5/vendor_perl/5.8.5/
i386-linux-thread-multi
/usr/lib/perl5/vendor_perl/5.8.4/i386-linux-thread-multi
/usr/lib/perl5/vendor_perl/5.8.3/i386-linux-thread-multi
/usr/lib/perl5/vendor_perl/5.8.2/i386-linux-thread-multi
/usr/lib/perl5/vendor_perl/5.8.1/i386-linux-thread-multi
/usr/lib/perl5/vendor_perl/5.8.0/i386-linux-thread-multi
/usr/lib/perl5/vendor_perl/5.8.5 /usr/lib/perl5/vendor_perl/5.8.4
/usr/lib/perl5/vendor_perl/5.8.3 /usr/lib/perl5/vendor_perl/5.8.2
/usr/lib/perl5/vendor_perl/5.8.1 /usr/lib/perl5/vendor_perl/5.8.0
/usr/lib/perl5/vendor_perl .) at
/home/kodeg2/scripts/GlobovisionHtml2Rss.pl line 6.
BEGIN failed--compilation aborted at
/home/XXXX/scripts/GlobovisionHtml2Rss.pl line 6.

Esta es una de las pocas cosas que odio de Perl; Montar módulos en ubicaciones alternativas ES UN FASTIDIO (si no tienes ROOT). En mi caso no tengo accesso a shell para hacerlo yo, así que dependo de la bondad de los administradores de Lunar Pages para que ellos lo hagan.

¿Que hacer? Bueno, o pedirles que lo monten en mi directorio (y yo agrego la ruta de busqueda usando “use lib”) o lo hago en otro lenguaje como Java (en cuyo caso copio mis Jar en donde me de la gana).

Voy a pensarlo un poco, vamos a ver que tanto tiempo toma escribir el mismo código en otro lenguaje.

Blogalaxia:, ,
Technorati:, ,
To2blogs:, ,
Del.icio.us:, ,

Buscar en otros sitios:

java , , ,

A %d blogueros les gusta esto: