lunes, febrero 25, 2008

urllib vs urllib2

Haciendo unas pruebecillas con la página de la wikipedia de mi signo chino, me pasaba una cosa curiosa que era que en la maquina en la que estaba ejecutando mi código me daba un error:


>>> import urllib2
>>> urllib2.urlopen("http://es.wikipedia.org/wiki/Rata")
Traceback (most recent call last):
File "", line 1, in ?
File "/usr/lib/python2.4/urllib2.py", line 130, in urlopen
return _opener.open(url, data)
File "/usr/lib/python2.4/urllib2.py", line 364, in open
response = meth(req, response)
File "/usr/lib/python2.4/urllib2.py", line 471, in http_response
response = self.parent.error(
File "/usr/lib/python2.4/urllib2.py", line 402, in error
return self._call_chain(*args)
File "/usr/lib/python2.4/urllib2.py", line 337, in _call_chain
result = func(*args)
File "/usr/lib/python2.4/urllib2.py", line 480, in http_error_default
raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 403: Forbidden



Pero sin embargo, haciendo un wget, si que la obtenía...
Se me ocurre probar con urllib en lugar de con urllib2 y si que la obtengo. ¿Mande?

Solución ñapa temporal :pppp:


try:
h = urllib2.urlopen(theUrl)
except:
h = urllib.urlopen(theUrl)


¡Dios! ¡soy un lumbreras!
Bueno seamos serios.... tras probar mis cosillas gracias a la ñapa, procedamos a mirar que es lo que realmente está pasando...
Pues lo que está pasando es que urllib2 está enviando unos headers al servidor web que no le molan...
La solución es cambiar el user agent.
Para ello lo que tenemos que hacer es proceder del siguiente modo (por ejemplo):


userAgent = 'Mozilla' # Por ejemplo
headers = { 'User-Agent' : userAgent }
req = urllib2.Request(theUrl, None, headers)
response = urllib2.urlopen(req)
thePage = response.read()


Referencias:

lunes, febrero 04, 2008

HTML5 or XHTML 2.0

He leido un artículo interesante que compara HTML5 contra XHTML 2.0 [vía].

martes, enero 29, 2008

Brad Fitzpatrick

De una cosa que se oye hablar últimamente: opensocial.
Y tambien de openid.

Detrás de ambos proyecto hay un nombre común: Brad Fitzpatrick.

jueves, enero 24, 2008

¿Escalan bien los lenguajes dinámicos?

A través de este post de barrapunto, llego a éste articulo de The Server Side.
Es de interesante lectura, no solo por el artículo, sino ademas por todas las referencias que contiene.

Parece que todo viene a colacion del proyecto chandler.

TinyURL

Hoy me he encontrado una pequeña herramienta web, que puede ser muy util, TinyURL. No sólo proque nos puede ayudar a hacer mas manejables ciertas urls, sino porque nos puede permitir no favorecer el algoritmo de google, por el tema del enlazado. Se sepa... ;). O bien por lo que sea porque queramos enmascarar una url hasta el momento de pincharla.

miércoles, enero 16, 2008

Lista de año

En el 2007 mi lista favorita sin dudarlo ha sido python-es.

martes, enero 15, 2008

Blog favorito 2007

Sin dudarlo, Ismael El-Qudsi.

lunes, enero 14, 2008

Ha surgido un thread muy interesante en python-es a raiz de que python ha sido declarado por TIOBE lenguaje del año 2007.

viernes, enero 11, 2008

TIOBE Declares Python the Programming Language of 2007.

Impresionante el avance de Lua.

sábado, enero 05, 2008

¿que nos deparará el 2008 en cuanto a buscadores?

Un post interesante de dirson al respecto.

jueves, noviembre 15, 2007

Python en Linux-magazine

El número 32 de Linux Maganize va dedicado a python [vía la lista python-es].

miércoles, noviembre 14, 2007

Parseando CSS en python revisited

Una tercera entrada sobre el tema. Las anteriores:
Debido a la lentitud de cssutils (usé la versión 0.9.1b3) pobré libcroco y las diferencias de tiempo eran brutales (en un ejemplo real, pues ('real time') de procesar en 0,1 seg. a 0,4 seg.

Para la funcionalidad que necesito, me valen ambas, con lo cual en mi caso la elección está clara, ya que el tiempo de procesamiento me importa. Mi uso de la librería es muy rudimentario. Lo que realmente me interesa es el parseo en si, que me lo den, luego yo ya manejaré los datos a mi antojo...

Ahora bien, si el tiempo no te importan pues lo suyo es usar csstuils, porque libcroco te obliga a implementar bindings, ya que es C.

Con respecto a cssutils, comentar que ultimamente veo que el proyecto ha estado muy activo (van por la version 0.9.4a3), y que ahora está alojado en google code.

Bindings a libcroco
Para los bindings usé swig. No por decisión propia, sino porque ya lo usabamos.... No se si es lo mejor, pero es lo que hay.

En un primer intento lo que hice fue intentar atacar el interfaz de la librería. ¡Piiiiiip! Error.
Inabordable.
La solución fué hacer un recubrimiento en C sobre la librería, y hacer los bindings para ese recubrimiento.

En mi caso, el fichero de interfaz quedó como sigue:

%module css2av

%header %{
#include "css2av.h"
%}



typedef struct
{
char *selector;
char *declaration;
} AVStyleRule;

extern long numRules;


void freeResouces();
void process(const char *buffer,
long len
);
AVStyleRule *getRule(int index);


%include cpointer.i
%pointer_functions(AVStyleRule, AVStyleRulePtr)

Ya veis que api complejo y sofisticado me gasto ;)...
¿Que es necesario para generar los bindings?
  • Pues los .h y .c del codigo c
  • el .i (el codigo mostrado)
Procedimiento para generarlos:
  • Generar los bindings: swig -python [fichero]
  • Compilar nuestro código de interfaz (el .c para obtener el .o)
  • Compilar el código de los bindings (fichero [nombre_interfaz]_wrap.c ). Para compilarlo usar la opción -c del gcc e incluir con -L .../python y -L .../python/config
  • Generar la librería: gcc -shared [nombre].o [nombre]_wrap.o -o _[nombre].so -L[ruta] -lcroco-0.6 -lglib-2.0 -lxml2 -lz -lm
Ejemplo de uso:

import css2av

css2av.process(data,len(data))

for i in range(css2av.cvar.numRules):
styleRule = css2av.getRule(i)
print "Regla:",
css2av.AVStyleRulePtr_value(styleRule).selector,
css2av.AVStyleRulePtr_value(styleRule).declaration

css2av.freeResouces()


Como se puede apreciar, el código no es muy pythoniano. La solución es hacer un recubrimiento a los bindings mas pythoniano.

lunes, noviembre 12, 2007

Una Guía de estilo de código Python. Merece la pena su lectura.

lunes, octubre 29, 2007

rpm

rpm.org es el SITIO de referencia para documentarse sobre rpm.
Para comenzar el tutorial de gurulabs está realmente bien; además incluye un ejercicio para practicar...
He visto también que hay unos bindings para python.

Actualización
  • El ejercicio de gurulabs (aunque no lo he hecho) tiene realmente muy buena pinta. Es amplio (tiempo estimado 1.5 horas).
  • En el tutorial vienen también urls de recursos varios.
  • Ya en plan documentación lo mejor que he visto por ahí es:
  • Y por supuesto siempre nos quedará la wikipedia.

FHS

En linux la estructura de directorios sigue un estandar, el cual es conocido por Filesystem Hierarchy Standard (FHS). Es interesante entender esa estructura, para saber a la hora de desplegar una aplicación que estemos desarrollando donde tiene que ir cada fichero.

Otras siglas sobre estandarización relacionadas: POSIX (Portable Operating System Interface) y LSB (Linux Standard Base).

jueves, octubre 25, 2007

Probando distutils

Sobre distutils ya había hablado en: Instalando con Python.

Recientemente hemos cambiado tanto la estructura del proyecto en el subversion como en la instalación, con lo cual los antiguos setup.py ya no nos sirven (hechos para distutils).

Pero no solo queda ahí la cosa, sino que vamos a instalar con rpms. Una opción hubira sido el crear ls 'specs' de los rpms a manubrio, pero me han recomendado hacerlo con distutils, y luego si hay que modificar algo, pues hacerlo, pero de esta manera no las tienes que crear desde cero.

La verdad.... me parece una muy buena idea, pero no sólo por ese posible ahorre de trabajo, sino que ademas podemos seguir desplegando de la manera normal (directamente) o generar un tar.gz.

Todo son ventajas...

Tras hacer el setup.py he mirado a ver que diferencias hay con setuptools [ibm article]. Por lo que parece son similares; siendo la mayor ventaja que ofrece setuptools, que te busca los paquetes a instalar y se asegura de resolver las dependencias.
Otra cosa que permite setuptools es generar 'eggs files'; y contiene EasyInstall.

Volviendo al tema que nos ocupa... cuando tienes una estructura un poco complicada no te queda mas remedio que meter en el setup.py funciones de utilidad para tu problemática concreta.

En mi caso, el mayor problemilla que he tenido es que las rutas de instalación y del SVN no son exactas, con lo cual tengo que hacer un mapeo entre el paquete que se instala, y la ruta donde está el código.

Esto se solventa con los parametros packages y package_dir, lo que hago es recorrer recursivamente el arbol del SVN para obtener las rutas a los paquetes, para a partir de ellas generar el nombre del paquete destino y definir a que directorio del SVN se corresponde.

En el caso de los datos, el parametro data_files, permite resolver esta problemática sin necesidad de ningun parámetro adicional.

Como documentación, el artículo que enlacé antes (Spreading python applications) está muy bien; asi como la documentación estándar.

Un par de notas finales:
  • para pruebas podeis usar la opción --dry-run
  • con --verbose os indica si os faltan ficheros __init__.py

viernes, octubre 19, 2007

Ver correctamente todos los caracteres con vi

Si os pasa que no veis correctamente algunos caracteres en vi, como por ejemplo los acentos, estais ante un problema con el encoding.

Puede ser porque no tengais correctamente definida la variable LAN, es valor correcto para el español es 'es_ES'.

jueves, octubre 11, 2007

Han linked in, han creado un grupo de python. Mas info aquí.

jueves, octubre 04, 2007

Ultraedit

Ahora para currar utilizo Windows XP Pro, lo cual me forzó a migrar a la version 13 de ultraedit, ya que la anterior que tenía no funcionaba correctamente.
Pues bien... la version que tengo ahora mismo delante, la 13.10a+1 me ha sorprendido muy gratamente. Han mejorado y mucho el ya util menú FTP/TELNET.

El soporte a ftp lo llevan teniendo desde hace siglos, luego metieron el de sftp, y ahora puedes establecer conexiones a ssh. No se si ya estaba y no me había dado cuenta o es nuevo. Yo creo que es nuevo.
Lo que si que es seguro es que han metido la opciones 'account manager' y 'ftp browser'. La segunda está genial, ya que nos evitará el instalar un cliente de ftp/sftp.

miércoles, octubre 03, 2007

Remote Diff

Lo mas relevante en google sobre como hacer un remote diff.
La mejor solución en un comentario, que es usando ssh: ' ssh remotehost ‘cat remotefile’ | diff - localfile'.