Python Argentina •  Sólo Python

miércoles, 10 marzo

16:07

Andrés Gattinoni: Ver dominios de Apache que más transferencia consumen

Frecuentemente me encuentro ante la necesidad de saber qué dominios de los que tengo alojados en mis servidores consumen más tráfico HTTP. Como éste es el tipo de tráfico más importante y que más incide en el desempeño general de mis servidores, saber qué dominios transfieren más datos por HTTP me orienta en la búsqueda de heavy users. Para ello hice un script hace algún tiempo, y ahora lo estuve revisando, retocando y simplificando, y decidí compartirlo.

En el entorno de Directadmin, los logs de Apache se encuentran en /var/log/httpd. Allí hay una carpeta “domains” que guarda los logs de cada dominio. Por cada dominio hay tres logs: dominio.com.log, dominio.com.error.log y dominio.com.bytes. El primero es el access_log, el segundo el error_log y el tercero solamente guarda la cantidad de bytes de cada request. La opción más sencilla es trabajar con este último tipo de logs, pero el problema que tienen es que no indican la fecha. Si bien se supone que los logs de Directadmin rotan una vez por día, alguna vez me ha pasado que por razones que nunca pude descubrir, algunos logs no rotaban y generaban ciertas confusiones. Por lo tanto, el script que dejo usa los access_logs. Además esta opción es reutilizable en otras implementaciones de Apache que no tengan archivos de bytes.

El código:

# Access Log Parser
#
# Parses all the files in a directory
# treating them as access_log files
# and outputs the list of files sorted
# by transfered megabytes. Useful for
# identifying heavy users.
#
# Usage:
# ./access_log_parser.sh <base_dir>
# base_dir = directory where the access_log files are

if [ -z $1 ]; then
    echo "Usage: $0 "
    exit 1
fi

BASE_DIR=$1
T1=`date +%s`
for file in $BASE_DIR/*;
do
    size=`stat -c %s $file`
    if [ $size -gt 0 ]; then
        from=`head -1 $file | awk ‘{print($4)}’ |sed ’s/^\[//’`
        to=`tail -1 $file | awk ‘{print($4)}’ |sed ’s/^\[//’`
        bytes=`cat $file | awk ‘{a+=$10}END{print a}’`
        mbytes=`echo $bytes | awk ‘{print $1 / 1048576}’`
        echo  "$mbytes MB ($bytes bytes) | From: $from | To: $to | ${file:${#BASE_DIR}+1}"
    fi
done \
| sort -nb
T=`date +%s`

Un detalle importante: el script levanta todos los archivos de un directorio que se especifica por parámetro. Esto es así porque yo lo invoco desde otro script:

#!/bin/bash
LOG_DIR=/var/log/httpd/domains/
TMP=/tmp/domain_logs
if [ ! -d $TMP ]; then
    mkdir -p $TMP
fi

rm -f $TMP/*

cd $LOG_DIR
for i in `ls *.log |grep -v error`; do
    ln $i $TMP/$i
done
/root/access_log_parser.sh $TMP

Este último script lo que hace es crear un directorio temporal (si no existe). Vaciar su contenido. Y luego generar hardlinks a todos los access_logs de /var/log/httpd/domains. De esta forma, no me tengo que preocupar por si los logs son modificados mientras yo estoy ejecutando el script. Por último, ejecuta mi primer script (access_log_parser.sh) y le pasa como parámetro el directorio temporal donde están los access_logs.

Por último, la salida del script sería algo así:

...
186.995 MB (196078184 bytes) | From: 10/Mar/2010:00:27:47 | To: 10/Mar/2010:16:51:09 | dominio1.com.ar.log
187.096 MB (196184596 bytes) | From: 10/Mar/2010:03:24:55 | To: 10/Mar/2010:16:51:24 | dominio2.com.ar.log
245.692 MB (257626221 bytes) | From: 10/Mar/2010:02:53:50 | To: 10/Mar/2010:16:39:54 | dominio3.com.log
273.46 MB (286743390 bytes) | From: 10/Mar/2010:02:48:33 | To: 10/Mar/2010:14:59:29 | dominio4.com.ar.log
306.344 MB (321224473 bytes) | From: 10/Mar/2010:00:23:09 | To: 10/Mar/2010:16:51:20 | dominio5.com.ar.log
444.097 MB (465669066 bytes) | From: 10/Mar/2010:00:49:35 | To: 10/Mar/2010:16:51:20 | dominio6.com.ar.log
Generated in 6 seconds

Les dejo, de yapa, la opción del script utilizando los logs de bytes. Como dije, esta opción es un poco más sencilla y veloz, pero no nos dice las fechas de los logs.

#!/bin/bash

if [ -z $1 ]; then
    echo "Usage: $0 "
    exit 1
fi

BASE_DIR=$1
T1=`date +%s`
for file in $BASE_DIR/*.bytes;
do
    size=`stat -c %s $file`
    if [ $size -gt 0 ]; then
        bytes=`cat $file | awk ‘{a+=$1}END{print a}’`
        mbytes=`echo $bytes | awk ‘{print $1 / 1048576}’`
        echo  "$mbytes MB ($bytes bytes) ${file:${#BASE_DIR}+1}"
    fi
done \
| sort -nb
T=`date +%s`
echo "Generated in $(($T-$T1)) seconds"

Y la salida sería así:

# ./parser.sh /var/log/httpd/domains
...
181.716 MB (190543470 bytes) dominio1.com.bytes
187.115 MB (196203973 bytes) dominio2.com.ar.bytes
189.093 MB (198278283 bytes) dominio3.com.ar.bytes
245.692 MB (257626221 bytes) dominio4.com.bytes
273.472 MB (286756234 bytes) dominio5.com.ar.bytes
314.32 MB (329588717 bytes) dominio6.com.ar.bytes
444.516 MB (466108759 bytes) dominio7.com.ar.bytes
Generated in 2 seconds

Quizás te interese:

  1. Sacar una foto con la webcam y enviarla por mail desde BASH
  2. Netstat con colorcitos
  3. Actualizar software con Custombuild para Directadmin

12:50

Mariano Guerra: si los profesores de fisica explicaran asi..

recomiendo ver los 12

12:23

John Lenton: PyCamp

El fin de semana me pude hacer una escapada el PyCamp. Fue muy lindo ver cómo seguía teniendo la misma idea (por demás simple) de juntar pythoneros para que hueveen hasta el hartazgo (o hasta quedarse sin voz de hablar de cómo arreglar el país y el mundo, o darse cuenta a las 5am que era la hora que era y que el resto se había ido a dormir horas antes mientras vos cazabas ese bug tan interesante).

Me pude desenchufar por dos días de la carrera contra reloj que es meter cosas nuevas en Lucid (que es mi trabajo). Y, mientras estuve ahí, construí una cosa. Bah, dos.

Por un lado, hice una aplicacioncita GTK+ que te deja bajar videos de YouTube eligiendo su resolución. Como soy super original, le puse YouTube Downloader.

YouTube Downloader screenshot

Por otro lado, como parte de lo anterior, hice una librería para bajar cosas asincrónicamente desde aplicaciones hechas en pygtk. Usa solamente gio, sin usar threads ni nada así (por lo menos que uno se entere). Y por ahora, es parte de ytd. Se usa así:

AsyncDownloader('http://pyvore.com/bg.jpg', file_factory, done_cb)

con eso, cuando termina de bajar el archivo se llama a done_cb con el objeto que devolvió file_factory (por ejemplo, file_factory puede ser tempfile.NamedTemporaryFile). Es así de fácil! Tiene ganchos para complicarla, por ejemplo para mostrar progreso, pero es la misma idea.

10:52

Sebastian Bassi: Downgrade pago


Downgrade pago
Cargado originalmente por sbassi
Cartel visto en una librería en el barrio de Congreso. Proponen pagar para hacer un downgrade. Como para no tenerle lástima a los usuarios de Windows.

07:46

Evita: Paso a la inmortalidad del compañero Lucho

Es un dolor enorme comunicar al pueblo, que el compañero Lucho, Ubuntero y, (aunque no peronista) seguidor incansable de la causa del pueblo, ha dejado de acompañarnos y se ha ido para siempre a lo que él llamaba "la tierra sin mal".
Este amigo, que literalmente ha dado su vida por los demás, sin esperar nada a cambio, ha sido un ejemplo de  vida, sirviendo constantemente a todos los que necesitaron ayuda. Inquieto, participador, comprometido,ejemplo que los que aquí quedamos debemos tomar como otra bandera del pueblo hacia la victoria definitiva.



Compañero Lucho, Presente Carajo!

00:37

Marcos Vanetta: Tutorial de Bazaar

Hace algunas semanas hable sobre Bazaar [1] en este post. Lo he probado durante algún tiempo y me ha parecido muy simple! por supuesto, yo trabajo solo y casi nunca tengo conflictos con… migo mismo, pero en fin. Aquí presento un pequeño tutorial al respecto:

Primero básico e imprescindible: Iniciar un proyecto. Podemos empezar uno nosotros mismos o clonar uno de algún repositorio. (Es decir copiarnos el de alguien para modificarlo nosotros).

1) Creamos nosotros un nuevo proyecto
mkdir proyecto_nuevo
cd proyecto_nuevo
bzr init
2) hacemos branch de un proyecto:
bzr branch lp:lalita

Configuramos nuestro repositorio: Principalmente, se seleccionan que archivos no queremos formen parte del repositorio: archivos propios del IDE, configuraciones exclusivas de nuestro sistemas, la base de datos que estemos usando, backups del sistema, *.pyc, etc. Si bien ya hay un archivo que se encarga de esto en Bazaar, también podemos crear el nuestro .bzrignore. Ojo! debe estar dentro de un commit (ver más adelante)

*.o
*~
*.tmp
*.py[co]
bzr ignore
bzr ignore –old-default-rules

Listo! ya podemos empezar a trabajar en nuestro proyecto. Una vez que tengamos algunos cambios y estemos seguros de que funcionan deberíamos hacer commit. En el caso de que hayamos creado o borrado algunos archivos a drede antes deberíamos avisarle a Bazaar:

bzr add nombre_del_archivo
bzr add . #agregamos todos los archivos nuevos
bzr remove nombre_del_archivo
bzr commit -m “esto es un commit”
bzr commit -m “solo comiteamos un archivo” file_name
bzr commit –author “Patricio Rey “

Revisemos como vamos:

bzr status # nos dice si hicimos cambios desde el último commit
bzr diff # nos muestra todos los cambios desde el último commit
bzr diff file.py #exclusivo para un archivo
bzr diff –diff-options –side-by-side foo.py #a probar!
bzr log # nos muestra un historial de commits
bzr log foo.py # el historial de un solo archivo
bzr cat -r X file #la versión X del archivo file
bzr viz # Herramienta gráfica!

¡Errores! Supongamos que hemos hecho algunos cambios y … no nos gusta ninguno. Podemos hacer un:

bzr revert # y eliminar los cambios hasta el último commit
bzr revert archivo # elimina los cambios de un archivo
bzr uncommit # elimina el último commit
bzr uncommit -r -3 # vuelve 3 commits para atrás

A veces, tenemos una versión funcional, pero le queremos agregar algunas opciones nuevas. A riesgo de no “romper” el programa que ya está andando, lo que hacemos es crear un branch y luego, cuando nos aseguramos que las nueva features funcionan genial, hacemos un merge entre las dos versiones:

#no ubicamos un directorio antes en el árbol:
pwd -> /home/malev/code/lalita
cd..
bzr branch lalita nuevo_branch
# jugamos en nuevo_branch y cuando nos convence
# en el directorio de lalita hacemos
pwd -> /home/malev/code/lalita
bzr merge ../nuevo_branch
# y si no hay conflictos, YA ESTÁ!

Preparando un release! Esta opción nos permite copiar todos los archivos y directorios de un branch y empaquetarlos en un archivo o directorio. También es posible taggear o etiquetar un conjunto de archivos con un número de versión.

bzr export ../releases/my-stuff-1.5.tar.gz
bzr tag version-1-5
bzr diff -r tag:version-1-5
bzr tag 2.0-beta-4 –delete #si nos confundimos :)

Todo este tutorial ha sido extraído de [2]. Aunque también recibí ayuda de Facu, Dermi y Gonzalo, todos del canal de IRC de PyAr [3]
También existe una aplicación visual [4], pero todavía no descubrí como instalarla :(
Y por último, he encontrado otro tutorial en español que parece interesante aquí en [5]
[1] http://bazaar.canonical.com
[2] http://doc.bazaar.canonical.com
[3] http://python.org.ar
[4] http://doc.bazaar.canonical.com/explorer/en/visual-tour-gnome.html
[5] http://palangano.com.ar/tag/bazaar/

martes, 09 marzo

07:17

Mariano Guerra: Bad Wildbad

viaje cortito de domingo a un pueblo que ni conocía pero que esta bastante bueno, esta en la selva negra y es característico por sus aguas termales.



viajamos con unos amigos desde pforzheim y pasamos unas horas paseando por el lugar.


para allá vas a ver a U2 (?)

lunes, 08 marzo

21:32

Javier Castrillo: Un amigo se nos ha ido

Vivías el sueño, soñabas la vida…. así te presentabas. Nos contó tu mamá que estabas comiendo, y luego te fuiste, así rápido, sin quejarte de nada, sin protestar, sin saludar, sin darnos tiempo a acostumbrarnos a estar sin vos. Justamente sin vos que nos malacostumbraste a tus correos del día de la madre, de tu [...]

18:55

Juan Pedro Fisanotti: PyCamp 2010, día 4

Bueno, ya estoy en Retiro, en un rato estoy saliendo para Rafaela. Así que posteo el resumen de hoy. Probablemente después haga un post más completo con mis conclusiones de lso 4 días.


Algo muy interesante de hoy fué el hacking con OpenCV. Se hizo un programita que detecta cuando hay una cara cerca del monitor, si no hay nadie pone solo el protector de pantalla, y si hay alguien lo saca. Está genial :).


Y a la tarde se hizo el cierre, donde se expuso brevemente las cosas que se habían logrado en cada uno de los proyectos, y se charlaron algunas ideas para el próximo PyCamp, y PyCon.

Estoy muerto, pero estuvo todo muy, muy bueno. Después haré el resumen. Saludos!!

18:31

Andrés Gattinoni: Grave exploit para Apache descubierto

Leo en Slashdot que se descubrió un grave exploit para Apache. De acuerdo con la nota de ZDNet, la compañía de seguridad “Sense of Security” descubrió un serio bug en el servidor web Apache que podría permitir a un atacante remoto obtener control sobre una base de datos. Una vulnerabilidad existente en el módulo “mod_isapi” del core de Apache podría permitirle a un atacante obtener privilegios de administrador, comprometiendo seriamente la seguridad de la información.

La nota de ZDNet no da muchos detalles del bug, pero indica que comprometería especialmente a los servidores Windows. Por otra parte, el reporte de Sense of Security es más detallado e incluye una “prueba de concepto” acerca de cómo explotar el bug.

Se recomienda actualizar a la versión 2.2.15 de Apache que corrige el bug.

Directadmin ya ha hecho los cambios correspondientes, así que con Custombuild podemos actualizar rápida y fácilmente a la nueva versión siguiendo el procedimiento que explique recientemente.

Quizás te interese:

  1. Actualizar software con Custombuild para Directadmin
  2. Apache: 15 años
  3. Tips Apache: ver configuración desde la línea de comandos

16:40

Andrés Gattinoni: httping: herramienta para medir la latencia de un servidor web

El otro día, Pablo Morales me pasó el dato de httping. Se trata de una herramienta similar al ping, pero que en vez de enviar paquetes por ICMP a una IP, envía peticiones HTTP a un servidor web. De esta forma podemos medir la latencia del servicio.

Instalación

En Debian/Ubuntu podemos instalar el paquete httping:

# sudo apt-get install httping

Para otras distribuciones, accediendo a la página de httping encontrarán RPMs y el tar.gz con los fuentes. Descargando los fuentes solamente hace falta descomprimirlo y darle “make && make install”.

Ejemplo de uso

Usarlo es muy sencillo. Por ejemplo, para pingear un servidor local:

elbarto@tarantino:~$ httping -c 5 -g http://localhost
PING localhost:80 (http://localhost):
connected to localhost:80, seq=0 time=1.56 ms
connected to localhost:80, seq=1 time=1.30 ms
connected to localhost:80, seq=2 time=1.30 ms
connected to localhost:80, seq=3 time=1.27 ms
connected to localhost:80, seq=4 time=1.19 ms
--- http://localhost ping statistics ---
5 connects, 5 ok, 0.00% failed
round-trip min/avg/max = 1.2/1.3/1.6 ms

El parámetro “-c 5″ define la cantidad de pings a realizar. Esto es igual que el ping de Linux.

También puedo pingear esta web.

httping -c 5 -g http://www.tail-f.com.ar
PING www.tail-f.com.ar:80 (http://www.tail-f.com.ar):
connected to www.tail-f.com.ar:80, seq=0 time=55.48 ms
connected to www.tail-f.com.ar:80, seq=1 time=45.74 ms
connected to www.tail-f.com.ar:80, seq=2 time=34.24 ms
connected to www.tail-f.com.ar:80, seq=3 time=41.79 ms
connected to www.tail-f.com.ar:80, seq=4 time=40.31 ms
--- http://www.tail-f.com.ar ping statistics ---
5 connects, 5 ok, 0.00% failed
round-trip min/avg/max = 34.2/43.5/55.5 ms

En este caso los tiempos son mayores, y tenemos que tener en cuenta dos cosas. En primer lugar, hay una diferencia por la conexión (no es lo mismo conectarme a localhost que a un servidor externo). En segundo lugar, este blog es un sitio dinámico hecho en PHP que realiza una serie de operaciones antes de mostrar el resultado. Pero, ¿cómo sabemos qué toma más tiempo, si la conexión o el procesamiento del sitio?. Para ello podemos separar ambos tiempos con el parámetro -S.

httping -c 5 -Sg http://www.tail-f.com.ar
PING www.tail-f.com.ar:80 (http://www.tail-f.com.ar):
connected to www.tail-f.com.ar:80, seq=0 time=25.96+22.93=48.89 ms
connected to www.tail-f.com.ar:80, seq=1 time=22.74+17.37=40.11 ms
connected to www.tail-f.com.ar:80, seq=2 time=21.90+20.39=42.29 ms
connected to www.tail-f.com.ar:80, seq=3 time=25.36+18.01=43.37 ms
connected to www.tail-f.com.ar:80, seq=4 time=27.81+15.85=43.66 ms
--- http://www.tail-f.com.ar ping statistics ---
5 connects, 5 ok, 0.00% failed
round-trip min/avg/max = 40.1/43.7/48.9 ms

Aquí vemos primero el tiempo de conexión, luego el de procesamiento y por último el total. En este caso, por lo general toma un poco más la conexión que el procesamiento, aunque es bastante parejo.

Otra cosa a tener en cuenta es que en este tipo de pruebas que venimos haciendo, el httping envía una petición HEAD al servidor. Para enviar un GET (que obtenga todo el contenido de la página), debemos agregar el parámetro “-G”. Por ejemplo:

elbarto@tarantino:~$ httping -c 5 -Gg http://www.tail-f.com.ar
PING www.tail-f.com.ar:80 (http://www.tail-f.com.ar):
connected to www.tail-f.com.ar:80, seq=0 time=210.41 ms
connected to www.tail-f.com.ar:80, seq=1 time=211.78 ms
connected to www.tail-f.com.ar:80, seq=2 time=194.49 ms
connected to www.tail-f.com.ar:80, seq=3 time=184.41 ms
connected to www.tail-f.com.ar:80, seq=4 time=210.62 ms
--- http://www.tail-f.com.ar ping statistics ---
5 connects, 5 ok, 0.00% failed
round-trip min/avg/max = 184.4/202.3/211.8 ms

Aquí los tiempos se incrementan, lógicamente, porque el tamaño de los paquetes traficados es mucho mayor.

Por último, podemos usar httping para hacer pruebas de stressing, con la opción “flood connect” (-f) que envía peticiones sin esperar respuesta.

elbarto@tarantino:~$ httping -fg http://www.tail-f.com.ar
PING www.tail-f.com.ar:80 (http://www.tail-f.com.ar):
connected to www.tail-f.com.ar:80, seq=0 time=51.54 ms
connected to www.tail-f.com.ar:80, seq=1 time=48.47 ms
connected to www.tail-f.com.ar:80, seq=2 time=56.07 ms
connected to www.tail-f.com.ar:80, seq=3 time=55.58 ms
connected to www.tail-f.com.ar:80, seq=4 time=55.99 ms
connected to www.tail-f.com.ar:80, seq=5 time=52.46 ms
connected to www.tail-f.com.ar:80, seq=6 time=56.06 ms
connected to www.tail-f.com.ar:80, seq=7 time=52.99 ms
connected to www.tail-f.com.ar:80, seq=8 time=52.54 ms
connected to www.tail-f.com.ar:80, seq=9 time=76.56 ms
connected to www.tail-f.com.ar:80, seq=10 time=63.04 ms
connected to www.tail-f.com.ar:80, seq=11 time=53.01 ms
connected to www.tail-f.com.ar:80, seq=12 time=36.00 ms
connected to www.tail-f.com.ar:80, seq=13 time=48.93 ms
connected to www.tail-f.com.ar:80, seq=14 time=42.78 ms
connected to www.tail-f.com.ar:80, seq=15 time=44.82 ms
connected to www.tail-f.com.ar:80, seq=16 time=52.41 ms
connected to www.tail-f.com.ar:80, seq=17 time=56.62 ms
connected to www.tail-f.com.ar:80, seq=18 time=48.44 ms
connected to www.tail-f.com.ar:80, seq=19 time=53.05 ms
connected to www.tail-f.com.ar:80, seq=20 time=54.13 ms
^Cconnected to www.tail-f.com.ar:80, seq=21 time=60.53 ms
--- http://www.tail-f.com.ar ping statistics ---
22 connects, 22 ok, 0.00% failed
round-trip min/avg/max = 36.0/53.3/76.6 ms

Luego tiene muchas otras opciones interesantes, como configuración de la salida para integrarse con Nagios y la posibilidad de definir un User-Agent y un Referer específicos en los requests. Les recomiendo instalarlo y hacer “man httping” para ver todas las opciones.

Quizás te interese:

  1. Grave exploit para Apache descubierto
  2. Python-Directadmin: API para conectarse a Directadmin desde Python
  3. Actualizar software con Custombuild para Directadmin

16:20

Diego Sarmentero: Aprender a Programar en 21 Dias

Muy bueno!! La verdadera (y posiblemente unica) forma de aprender a programar en 21 dias en C++:
Visto en: http://mundogeek.net/

12:50

Mariano Guerra: Neuschwanstein

el sábado con pato fuimos al neuschwanstein, aunque el nombre no suene conocido es bastante conocido por el castillo que hay ahí.





Para bien o para mal después de semanas sin nieve nos despertamos para salir a las 5:30 de la ma~nana con una tormenta de nieve importante por decir poco, durante el viaje no importo mucho porque los trenes tienen calefacción, pero una vez allá estaba fresquito por decirlo de alguna manera.



paseamos por los alrededores, hicimos una visita guiada por el castillo mas chico y a la hora de subir al castillo grande nos agarro una tormenta de nieve como nunca había visto y nos dejo con una pared blanca alrededor nuestro que no nos dejaba ver nada.




Como no sabíamos a que hora iba a parar decidimos bajar la monta~na con la tormenta. Una vez abajo mientras tomábamos un café para pasar el frió y darle tiempo a mi cerebro de que recuerde que tiene que hacer que sienta mis manos. milagrosamente salio el sol y me dejo sacar algunas fotos que son las que muestro.



No creo que quieran ver monta~nas escondidas atrás de una pared blanca :D.



En resumen estuvo muy bueno, tuvimos una llegada con nieve suave y aguantable, una experiencia de tormenta de nieve y un final despejado que estuvo muy bueno.


domingo, 07 marzo

20:49

Juan Pedro Fisanotti: Pycamp 2010, día 3

Resumen de hoy :)


A la mañana me quedé medio dormido, jeje, porque anoche nos habíamos quedado hasta las 4 a.m.


A la siesta participé en un mini-cursito de empaquetado de aplicaciones Python para Debian. La verdad que era más complejo de lo que esperaba, pero nada que un programador no pueda hacer. Conclusión: tengo que aprender setuptools


Más tarde participé en el Bug Day de Python: cada uno elegía algún bug de Python y trataba de mandar un parche con la corrección. No pude hacer ningún parche, pero aprendí un poco viendo código de cómo está hecho Python, lo que estuvo bueno.


Y ahora a la noche, después de comer empanadas y panqueques, vuelvo a programar un poco el juego que empezamos el sábado.


Saludos!!


update!: me acabo de enganchar en una reunión de otro juego que se va a desarrollar para una competencia, veremos que onda :)

19:42

Diego Sarmentero: Navegador Web en 63 Lineas de Codigo!

Gracias a Python y PyQt es posible programar un Navegador Web en solo 63 lineas de código (e incluso menos).

Utilizamos QtWebKit para el manejo de la página web y el componente que renderiza la página, etc.

Este simple navegador permite:
  • Navegar por las paginas de forma tradicional
  • Muestra una barra de progreso para poder ver como se va cargando la página
  • Posee boton para cargar la página anterior
  • Boton para ir a la siguiente página
  • Boton recargar la página actual
  • Boton para parar la carga de la página actual
  • Y en la barra de direcciones podemos escribir una url, o tambien escribir simplemente las palabras que estamos buscando y nos realiza automaticamente la busqueda en Google (al mejor estilo Chrome)
Screenshots del Navegador:



Para ver el código: PyBrowser.py
Para descargarlo: Descarga

19:42

Andrés Gattinoni: Enrutamiento Avanzado y Control de Tráfico en Linux

Leyendo El CóDiGo K me entero sobre la existencia de este manual de Enrutamiento Avanzado y Control de Tráfico en Linux. Anoche lo bajé y lo estuve hojeando un poco. La verdad que es muy interesante y vale realmente la pena. Dejo la explicación de Daniel que me pareció muy clara.

Uno de los documentos más completos y más leídos por los Administradores de Redes cuando se habla de Calidad de Servicio (QoS) en los sistemas conectados.

Este interesante documento pretende descubrir a fondo herramientas que perteneces a la poderosa infraestructura iproute2, sustituyendo antiguos comandos tales como routeifconfig.

Actualmente el documento “Enrutamiento Avanzado y Control de Tráfico en Linux” se encuentra en 8 idiomas totalmente traducidos, con diversos ejemplos para dominar por completo la administración de recursos de los sistemas.

Enlaces

Quizás te interese:

  1. Instalar ConfigServer Security & Firewall en Linux con Directadmin

18:33

Juan Pedro Fisanotti: PyCamp 2010, día 2

Ayer no postee porque no tuve tiempo en todo el día, así que posteo ahora el resumen. Supongo que esta noche volveré a postear con el resumen de hoy


Lo más interesante de ayer fue el sprint de Django. Sprint = gente que se junta a programar, Django = framework para hacer desarrollo web usando Python, el mejor que probé hasta ahora. O sea, los que querían se juntaron para sobre todo corregir bugs en Django, para la versión nueva que va a salir dentro de unos días. Sinceramente fui más que nada para ver y aprender, porque pensaba que estaba a un nivel en el que yo no podía aportar mucho. Pero para mi sorpresa, terminamos corrigiendo un bug de Django juntos con Javi :). Mi granito de arena para Django, así devuelvo algo de todo lo que me está sirviendo.


Por la tarde me enganché en el momento de cocos2d (el framework para juegos que nació en un PyCamp anterior, que estamos usando para el juego que empezamos el sábado). Me enganché medio tarde, pero estuvo bueno, me ayudó a entenderlo mejor.


Finalmente, a la noche tuvimos el "fogón", pero sin fuego porque no se consiguió leña. Se empezó hablando de los temas más comunitarios, objetivos, realidad de Python en Argentina, etc. Se habló también de PyCon Atlanta 2010 y PyCon Argentina 2010. Y después se terminó hablando de política, sociedad, valores, ideologías, etc. Discusiones acaloradas pero muy interesantes. Algo parecido a los threads de PyAr, jajaja.


Hoy viene siendo interesante también, pero esta noche hago el resumen. Saludos!

13:56

Andrés Gattinoni: Nuevo look

Acabo de instalar un nuevo theme en el blog. Ya estaba un poco cansado del look anterior. Por bastante tiempo estuve utilizando Neoglow de Lunamedia. Lo tenía ajustado con algunos detalles, sobre todo para incorporar publicidad y con estilos para mostrar los bloques de código.

Ahora instalé Piano Black, que por ahora me resulta bastante agradable. Ya hice algunos ajustes. Quizás en algún momento traduzca todos los textos en inglés, por ahora no tengo tiempo ni ganas.

La idea del cambio era, además de renovar un poco el aspecto, buscar algo que fuera un poco más legible y atractivo. No creo que este theme sea mucho más legible que el anterior, pero es un poco mejor. Adicionalmente, en la última semana estuve haciendo algunos otros cambios, reemplazando WP Cache por WP Super Cache, agregando SEO Super Comments y tratando de mejorar un poco la velocidad de carga del sitio. Todavía me quedan algunas cositas para hacer, que las iré completando en cuanto tenga algún ratito.

¿Qué les parece el nuevo look?

No se encontraron posts relacionados.

13:34

Diego Sarmentero: PyQT: Aplicacion en SystemTray

La idea de este Post es explicar de forma simple, como realizar una aplicación en Python, utilizando PyQt, donde esta aplicación corra en el SystemTray (o pueda minimizarse al SystemTray) y tengamos un menu desplegable al presionar el icono de la aplicación en el SystemTray.


Primero que nada necesitamos importar algunos modulos que seran usados por nuestra aplicación:
import sys
from PyQt4 import QtGui, QtCore
  • El modulo "sys", nos permite poner a correr la aplicación usando utilidades del sistema.
  • El modulo PyQt4, es el binding de Qt para Python y contiene todos los componentes graficos que podamos precisar, manejo de eventos de los componentes, etc. Principalmente se usara "QtGui" para crear instancias de los componentes gráficos, y "QtCore" para conectar señales de estos componentes con alguna operación.
Una vez importados los modulos necesarios, procedemos a crear una clase que extienda de QWidget para construir la aplicación, y le daremos un icono y nombre a la ventana cuando se muestre:
import sys
from PyQt4 import QtGui, QtCore

class PyTest(QtGui.QWidget):

def __init__(self):
QtGui.QWidget.__init__(self)
#cargar imagen para icono
pixmap = QtGui.QPixmap('pytv.png')
#setear el nombre de la ventana
self.setWindowTitle('PyTest!')
#colocar el icono cargado a la ventana
self.setWindowIcon(QtGui.QIcon(pixmap))
#creamos objeto Style para hacer uso de los iconos de Qt
self.style = self.style()

En la primer linea del método lo que debemos hacer es invocar el constructor de la clase Padre, luego creamos un objeto QPixmap pasandole la ruta del archivo imagen (en este caso es una ruta relativa en el mismo directorio de ejecución), y luego le damos el nombre e icono a la ventana.

Ahora para crear un Menu y agregarle Acciones (cada elemento del menu) hay diversas formas, podemos crear un objeto accion y luego agregarlo al menu pasandole ese objeto, tambien podemos llamar al método "addAction" de menu pero esta vez pasarle un String y nos devolvera una instancia de un objeto QAction con ese nombre ya inicializado, y diversas formas mas.
En este caso vamos a usar la opción del String que es más fácil y directa:
#Menu
self.menu = QtGui.QMenu('PyTv')
#accion mostrar
show = self.menu.addAction(self.style.standardIcon
(QtGui.QStyle.SP_ArrowRight), 'Show Window')
#accion salir
exit = self.menu.addAction(self.style.standardIcon
(QtGui.QStyle.SP_TitleBarCloseButton), 'exit')
Ahora que contamos con el Menu creado, vamos a conectar las distintas señales del Menu con operaciones que queremos que se realicen para responder a los eventos del usuario.
#SIGNAL->SLOT
QtCore.QObject.connect(exit, QtCore.SIGNAL("triggered()"),
lambda: sys.exit())
QtCore.QObject.connect(self.menu, QtCore.SIGNAL("clicked()"),
lambda: self.menu.popup(QtGui.QCursor.pos()))
QtCore.QObject.connect(show, QtCore.SIGNAL("triggered()"),
self.showWindow)
"QtCore.QObject.connect" nos permite conectar una señal de alguno de nuestros objetos de QtGui con una acción que queremos que se realice.
La conexión SIGNAL->SLOT es una forma de decir que con determinada señal se va a ejecutar determinado fragmento de código. En Python a diferencia de C++ no hace falta que implementemos un método SLOT, simplemente podemos pasarle el nombre del método que deseamos que se ejecute como se ve en el tercer caso donde se conecta la señal "triggered()" del objeto QAction "show" con el método "showWindow(self)" de la actual Clase.
En cambio, las otras 2 señales se prentenden conectar a métodos que o no pertenecen a la Clase actual, o deben recibir algún parametro al ser invocado, para estos casos podemos hacer uso de "lambda" en Python y llamar a cualquier función que deseemos.
En el caso del menu, es necesario que sea definido como una variable de la Clase, porque sino es posible que la señal asociada al menu deje de responder en algún momento.

Ahora vamos a crear el icono de SystemTray, hacerlo visible en el SystemTray y agregarle el Menu que ya creamos para que este se despliegue al presionar el boton derecho del mouse sobre el icono:
#SystemTray
self.tray = QtGui.QSystemTrayIcon(QtGui.QIcon(pixmap), self)
self.tray.setToolTip('PyTest')
self.tray.setVisible(True)
self.tray.setContextMenu(self.menu)
Ahora procedemos a crear la función que se ejecuta al presionar la acción del Menu: "Show Window" (este método lo que hara es mostrar la ventana del programa cuando este evento es disparado)
    def showWindow(self):
self.setVisible(True)
Ahora si queremos que al cerrar la ventana no se cierre la aplicación sino que se minimice al SystemTray, lo que tenemos que hacer es sobreescribir el método "closeEvent" de la clase QWidget de la que heredamos de la siguiente forma:
    def closeEvent(self, event):
event.ignore()
self.hide()
  • "event.ignore()" lo que hace es ignorar la señal de cierre de la aplicación que esta por ejecutarse.
  • "self.hide()" oculta la ventana pero mantiene corriendo la aplicación
Ahora supongamos que queremos que al abrirse la aplicación no se muestre ninguna ventana, sino que se inicie directamente solo con el icono en el SystemTray, para ello debemos sobreescribir el método "show" de la Clase padre QWidget:
    def show(self):
pass
Debido a esto, cuando necesitemos mostrar la ventana, como en el caso de la acción "Show Window", deberemos invocar el metodo "setVisible(bool)" como se puede ver en el método mas arriba, ya que si llamaramos a "self.show()" no sucederia nada.

Y por último, hacer que nuestra aplicación pueda ser ejecutable:
app = QtGui.QApplication(sys.argv)
pytest = PyTest()
pytest.show()

sys.exit(app.exec_())
Para descargar el ejemplo completo: pytest.zip

10:41

Andrés Gattinoni: Actualizar software con Custombuild para Directadmin

En esta pequeña guía veremos cómo actualizar muy sencillamente el software de nuestro servidor Directadmin usando Custombuild. Ya en otro artículo habíamos visto lo sencillo que era instalar software con Custombuild. En esta oportunidad, veremos que es igual de sencillo utilizarlo para mantener nuestro software actualizado.

Lo primero que debemos hacer es un update para descargar las nuevas versiones de las aplicaciones:

# cd /usr/local/directadmin/custombuild
# ./build update

Ahora que tenemos actualizado el propio custombuild, verificadas las versiones locales del software y descargadas las actualizaciones, podemos ver qué podemos actualizar.

# ./build versions

Esto nos va a mostrar por cada uno de los programas y librerías que maneja Custombuild, qué versión tenemos instalada y si hay una nueva para instalar. En base a esta lista, lo que podemos hacer es instalar la actualización para un programa/librería en particular, o actualizar todo.

Por ejemplo, si queremos actualizar solamente Apache, usaremos:

# ./build httpd

En cambio, si queremos actualizar todo, ejecutaremos:

# ./build update_versions

El Cron

Custombuild permite instalar un cronjob para manejar las actualizaciones. Tiene dos funcionalidades: avisarnos por mail cuando hay actualizaciones y actualizar automáticamente el software. Esto se configura en el archivo options.conf de Custombuild.

#Cron settings
cron=yes
email=nuestroemail@dominio.com
notifications=yes
updates=no

La variable “cron” habilita/deshabilita el cronjob. Si lo queremos instalar tiene que estar en “yes”. La variable “email” es la dirección donde recibiremos las notificaciones. Luego “notifications” habilita/deshabilita las notificaciones por email y “updates” habilita/deshabilita la actualización automática.

Personalmente, recomiendo no activar las actualizaciones automáticas, pues puede generar problemas inesperados en momentos en que no podemos resolverlos. Es preferible hacerlas manualmente cuando lo consideremos adecuado. Por otro lado, el cron se ocupa de actualizar automáticamente las aplicaciones web (los webmails), lo cual no suele traer problemas.

Para instalar el cron debemos configurar las opciones mencionadas en el options.conf (indicando cron=yes) y luego ejecutar:

# ./build cron

Quizás te interese:

  1. Grave exploit para Apache descubierto
  2. Instalar ConfigServer Security & Firewall en Linux con Directadmin
  3. Python-Directadmin: API para conectarse a Directadmin desde Python

01:04

Diego Sarmentero: Los Piratas de las Aguas Negras


Esto si que se llama "nostalgia"!! jeje
De la nada me acorde de este dibujito que veia cuando era chico: "Los Piratas de las Aguas Negras"
Y me dieron ganas de volverlo a ver... probablemente pase como con todas las cosas viejas, donde el recuerdo difiere muchisimoooooo de lo que es en realidad... pero bueno, hay que sacarse las ganas.

sábado, 06 marzo

22:26

Javier Castrillo: “Saque eso de acá, compañero Lula!” (?)

Sí Cristina, a mí me da la misma sensación. Ni de lejos esos colores Macristas. Los mismos que defienden los de la mesa de engarque. Vade retro!

15:38

Diego Sarmentero: Cuento: Una Historia Realista

Anoche mientras leia un libro me colgue pensando como muchas veces los principales de la historia son extremadamente grosos, esta claro que tienen que tener algo que los haga resaltar, pero a veces parece ya demasiado y algunas cosas me causaban gracia, entonces me puse a pensar como sería una historia mas realista y escribi este cuento:


viernes, 05 marzo

21:48

Diego Sarmentero: PyTv! 1.0


PyTv! Terminado!

Despues de colgarme un par de días programando, termine lo que considero una versión estable de PyTv.
PyTv es un programa bastante util para aquellos que sean tan fanaticos de las series de televisión como yo. Con PyTv lo unico que hacemos es decirle el nombre de la serie que nos interesa (por ejemplo: "the big bang theory"), y listo!
El programa se encargara de buscar en Google la lista de episodios de esa serie, de los resultados obtenidos abrira la pagina correspondiente de Wikipedia, comprobara cual es la ultima temporada disponible, y bajara toda la información de numero de temporada y episodio, nombre del episodio y fecha de emisión del mismo.
Se guarda localmente esa información para no tener que hacer uso de internet cada vez que el programa se abre, y PyTv se encargara de avisarnos cada vez que se estrene un nuevo capitulo de alguna de las series que seguimos.

SystemTray

Menu

Pantalla Principal

Notificaciones


Preferencias/Configuración

Calendario

Detalle de Calendario

Información de la Serie

Tambien esta la opción de abrir un pequeño calendario y presionando en alguno de los días nos mostrara la información de los episodios que sean estrenado ese día, como asi tambien, se puede elegir ese episodio y consultar la información referente a la serie en IMDB presionando un boton o ver el trailer del episodio en YouTube.
Si una Serie terminara su temporada, PyTv comprobaria cuando comienza la nueva temporada de dicha serie y al estar disponible, descargaria la información de la misma, sin tener que preocuparnos por andar pendiente de cuando empiezan los nuevos episodios, etc.

Código: pytv-1.0.zip
Instaladores DEB: i386, amd64

21:34

Juan Pedro Fisanotti: PyCamp 2010, día 1

No voy a hacer un post muy completo, eso lo dejo para cuando vuelva. Pero cada día voy a postear un breve resumen de como pasé/pasamos el día.


El viaje fue largo... salí de Rafaela el jueves a las 11 de la noche, y recién llegamos al lugar hoy a las 13, justo para la comida :).
El lugar muy bueno. Todavía no pude recorrer mucho, pero tiene hasta para hacer cayack (o como se escriba, jeje).

Está todo super organizado el tema de wifi, hay cables y antenas atadas con cinta por las paredes, jeje. Y por suerte no se necesitó usar mi router (hubiese sido para renegar nomás).

Lo primero que se hizo a la tarde fué presentar todos los proyectos, y anotar cuántos interesados había en cada uno. A partir de eso se organizó un cronograma, armado como para favorecer la participación el los proyectos más votados. Pero todos los proyectos quedaron en el cronograma, y cada uno elije en cuáles participar y cuáles no :).

De hoy, el proyecto en el que más participé y me interesó fue el de desarrollo de un juego de tipo "Tower Defense", usando la librería para juegos en Python COCOS2D. Es una librería que se había empezado a desarrollar en un PyCamp anterior, jeje.

La verdad que tenía miedo de no poder aportar mucho, pero en un rato nomás ya estaba a tono y codeando para modificar la lógica de disparo de las torres :D.

Y ahora, a la noche, algunos seguimos codeando, mientras otros están con juegos de mesa, o más relajados.

La gente hasta ahora genial!


13:48

Javier Castrillo: El MPB con el Gobierno Nac&Pop

Ante el golpe de mano, viciado de ilegalidad y con clara intención destituyente, consumado el día de ayer en el Senado de la Nación y ante el evidente desprecio de ciertos sectores político/mediáticos por la representación popular, el Movimiento Peronista Bloguero exhorta al Vicepresidente Julio Cobos y a los demás dirigentes opositores que perpetraron la [...]

jueves, 04 marzo

15:45

Juan Pedro Fisanotti: Apple vs HTC

Alguien vio el detalle de las pantentes que Apple esta usando para demandar a HTC? Es un desastre, tienen patentadas cosas que existen desde hace 20 años, que existían mucho antes de cualquier iPhone. No se cómo les da la cara para hacer algo así...
Una de las pantentes por ejemplo, es sobre tener objetos en memoria que se refieren a elementos en la pantalla. Cualquier programa con ventanas tiene eso! Existe desde hace décadas!!


Cualquiera que sabe de programación, viendo el detalle de las patentes aquí, puede darse cuenta del fraude que esto es. La mayoría de las pantentes son sobre cosas que no inventó Apple, y que existían desde hacía años antes que el iPhone...


Nunca me había gustado mucho Apple, pero después de esto, sinceramente la imagen que tenía de ellos cayó hasta lo más hondo. En lugar de competir haciendo mejores productos, están tratando de matar a la competencia con un fraude legal...

13:21

Mariano Guerra: CLQLGHCCQUA: cosas locas que la gente hace con cosas que uno hace



un tal mariano verdu hizo lo siguiente con repiola (un proyecto de un rato para programar pseudo assembler que hace dibujos)


set r0 150
set r1 50
put 0

set r0 225
set r1 200
put 0

set r0 75
set r1 200
put 0


rnd r0
mod r0 300

rnd r1
mod r1 300

: start
rnd r2
mod r2 3 #modificar por 3

eq r2 0 punto1
eq r2 1 punto2
eq r2 2 punto3

: punto1
add r0 150
div r0 2
add r1 50
div r1 2
put 0
jmp start

: punto2
add r0 225
div r0 2
add r1 200
div r1 2
put 0
jmp start

: punto3
add r0 75
div r0 2
add r1 200
div r1 2
put 0
jmp start


pueden probarlo copypasteando el codigo ya sea en repiola desktop o en repiola web (que fue hecho por dos usuarios de repiola :D)

no creo que lo quieras tipear en tu celular, probablemente se derrita :D

para los impacientes, dibuja esto:


parece que estos chicos se emocionaron con dibujar cosas y j0hn se mando unas cuantas mas, esta vez con canvas y javascript

mandelbrot
Sierpinski triangle

miércoles, 03 marzo

22:15

Marcos Vanetta: Decimal, la evolución de los floats

Desde Python 2.4 se nos ha unido un módulo con un nuevo tipo de datos: Decimal, que permite manejar las matemáticas de punto flotante con algunas ventajas respecto a float:

  • Contiene números como 1.1 que no tienen representación binaria
  • Más exacto: 0.1 + 0.1 + 0.1 – 0.3 = 0 pero cero en serio! y no 5.5511151231257827e-017 como en los floats
  • Tiene precisión regulable (28 lugares por defecto), pero extensible.
  • El módulo se centra en 3 conceptos: el número decimal, el contexto aritmético y las señales.
    Número decimal: inmutable, tiene un signo, coeficientes y un exponente. No trunca ceros a la derecha y posee los valores especiales: infinito, – infinito y NaN (no es un número). También diferencia entre -0 y +0.
    El contexto aritmético es el ambiente donde se especifica la precisión, las reglas de redondeo, los límites en los exponentes, banderas que indican los resultados de las operaciones y “trampas” que permiten que ciertas señales sean tratadas como excepciones. La opciones de redondeo incluyen: ROUND_CEILING, ROUND_DOWN, ROUND_FLOOR, ROUND_HALF_DOWN, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_UP, and ROUND_05UP.
    Las señales son un conjunto de condiciones que surgen durante el proceso de cálculo. Y dependiendo de las necesidades de la aplicación, pueden ser ignoradas, consideradas información o tratadas como excepciones. Las señales en el módulo decimal son: Clamped, InvalidOperation, DivisionByZero, Inexact, Rounded, Subnormal, Overflow, and Underflow.
    Para cada señal hay una flag (bandera) y una trap (trampa¿?). Cuando se encuentra una señal, la flag se pone a uno, luego si la habilitador de la trap está puesto en uno, entonces se envía una excepción (exception). Las flags quedan en uno, por lo que es necesario reiniciarlas antes de monitorear el cálculo.

    Probando:

    1
    2
    3
    4
    
    from decimal import *
    getcontext()
    # Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999, capitals=1, flags=[], traps=[Overflow, DivisionByZero, InvalidOperation])
    getcontext().prec = 7       # Set a new precision

    Los objetos decimal se instancian a partir de integers, string o tuplas. Para convertir una desde un float primero es recomendable convertilo primero a string.
    Ya se, este post parece una traducción de [1] y medio que lo es, pero lo hice para obligarme a leer toda la documentación ;) También les dejo un tutorial más que interesante en [2].
    El contra de decimal: No se pueden realizar operaciones entre números Decimal y floats. Antes los floats deben ser convertidos a string y luego a decimal. Bastante molesto cuando cargamos constantes, o algunos valores numéricos de una ecuación. Seguro hay alguna forma de hacer esto simple, pero todavía no la he encontrado :(
    [1] http://docs.python.org/library/decimal.html
    [2] http://broadcast.oreilly.com/2009/08/pymotw-decimal—fixed-and-flo.html

    17:50

    Mariano Draghi (cHagHi): Desarrollar software te hace mal

    Extracto de una conversación real por IM en el trabajo, con alguien a quien no vamos a delatar TAN de frente ;)

    (5:48:07 PM) cHagHi: te transfiero o queres el cash?
    (5:48:29 PM) XXXXX: si tenés cash prefiero el cash, si estás corto de cash, transferime, 0 drama
    (5:49:04 PM) XXXXX: pero si me das a elegir.... entre tú y... las estrellas... me quedo con ellas... porque tu.....
    (5:49:21 PM) XXXXX: de pronto flash! La IDE del cosito azul!
    (5:49:28 PM) XXXXX: zarazaaaa
    (5:49:30 PM) XXXXX: toy limado
    (5:49:37 PM) cHagHi: AH BUENO

    Si desarrollás software, tené cuidado. A la larga, es perjudicial para la salud...

     


    16:28

    Roberto Alsina: Un par de horitas hackeando Kuatia...

    Como he comentado hace un tiempito, de a ratos ando tratando de hacer un procesador de texto tipo "prueba de concepto". Por ahora está hsoteado en googlecode y se llama kuatia.

    Obviamente no está ni cerca de ser útil para algo, pero... puede hacer listas itemizadas o numeradas anidadas.

    Acá hay una captura del editor y de la salida PDF que produce vía reStructured Text:

    editando2

    No me parece que esté tan mal.

    15:46

    Gustavo Carmona: Estoy Jugando con Django

    Proximamente pondré algunos ejemplos en django con Modelos en relacion ManyToMany, y cargando la Base de Datos desde la shell.

    Sean Pacientes!


    01:45

    Juanjo Conti: os.path en el settings.py de Django para mayor comodidad

    En el archivo de configuración settings.py de un proyecto Django, por lo general tenemos que setear variables como MEDIA_ROOT o STATIC_DOC_ROOT. Su contenido en una instalación Windows suele ser algo como: 'C:\Windows\camino\hasta\mi\projecto'. Y en Linux: '/home/usuario/camino/a/mi/proyecto'. El problema surge cuando el proyecto es desarrollado en varias máquinas a la vez, y con distintos sistemas operativos. Más aún, si hacemos lo anterior, seguramente versionaremos el proyecto y con él, al archivo de configuración. No sería raro que tras una actualización, el archivo se actualice con los valores que puso algún compañero de trabajo.

    Mi solución es definir primero una variable para el proyecto:

    PROJECT_PATH = os.path.abspath(os.path.dirname(__file__))

    Luego podemos usarla para definir el path absoluto a la carpeta con archivos de media:

    MEDIA_ROOT = os.path.join(PROJECT_PATH, 'media')

    nuestros templates:

    TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    os.path.join(PROJECT_PATH, 'templates')
    )

    o cualquier otra variable de configuración que requiere una ruta de directorios.

    Con esta solución podemos cambiar el proyecto de carpeta, disco o computadora y seguirá funcionando.

    martes, 02 marzo

    10:50

    Javier Castrillo: Inauguración de las sesiones ordinarias del congreso

    Esta sana costumbre democrática que consiste en celebrar mi cumpleaños iniciando la actividad legislativa, la compañera Presidenta Cristina, dió un notable discurso, cuya transcripción completa es la siguiente: Muy buenos días a todos y a todas. Vengo a dar cumplimiento a lo prescripto por el artículo 99 inciso 8 en cuanto a dar inauguración a la [...]

    lunes, 01 marzo

    13:19

    Andrés Gattinoni: Tips Apache: ver configuración desde la línea de comandos

    Apache Web Server

    A veces queremos saber algunas cosas de la configuración de Apache, pero no queremos revisar el httpd.conf ni seguir sus includes. El binario httpd acepta algunos parámetros que nos pueden servir, proveyéndonos esa información. Dejo un par de ejemplos.

    Verificar sintaxis de los archivos de configuración

    Muy facilmente podemos pedirle al Apache que verifique la sintaxis de los archivos de configuración. Esto es útil por si hicimos una modificación de la que no estamos seguros y queremos verificarla antes de reiniciar el servicio (y dejar a los clientes sin servicio hasta que lo resolvamos).

    Comando:

    httpd -t

    Salida:

    Syntax OK

    Obtener versión de Apache

    La más sencilla y obvia, para ver la versión de Apache sólo basta con:

    httpd -v

    Y la salida es algo así:

    Server version: Apache/2.2.14 (Unix)
    Server built:   Jan 28 2010 12:43:06

    Ver información de compilación

    Eventualmente podemos querer tener algunos datos sobre cómo fue compilado Apache.
    Esta es una versión más completa de lo que ofrece httpd -v.
    Entre otros datos, nos sirve para saber qué módulo de MPM está usando Apache.

    Comando:

    httpd -V

    Salida:

    Server version: Apache/2.2.14 (Unix)
    Server built:   Jan 28 2010 12:43:06
    Server's Module Magic Number: 20051115:23
    Server loaded:  APR 1.3.9, APR-Util 1.3.9
    Compiled using: APR 1.3.9, APR-Util 1.3.9
    Architecture:   32-bit
    Server MPM:     Prefork
      threaded:     no
        forked:     yes (variable process count)
    Server compiled with....
     -D APACHE_MPM_DIR="server/mpm/prefork"
     -D APR_HAS_SENDFILE
     -D APR_HAS_MMAP
     -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
     -D APR_USE_SYSVSEM_SERIALIZE
     -D APR_USE_PTHREAD_SERIALIZE
     -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
     -D APR_HAS_OTHER_CHILD
     -D AP_HAVE_RELIABLE_PIPED_LOGS
     -D DYNAMIC_MODULE_LIMIT=128
     -D HTTPD_ROOT="/etc/httpd"
     -D SUEXEC_BIN="/usr/sbin/suexec"
     -D DEFAULT_PIDLOG="/var/logs/httpd.pid"
     -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
     -D DEFAULT_LOCKFILE="/var/logs/accept.lock"
     -D DEFAULT_ERRORLOG="logs/error_log"
     -D AP_TYPES_CONFIG_FILE="conf/mime.types"
     -D SERVER_CONFIG_FILE="conf/httpd.conf"

    Ver módulos

    Hay dos alternativas diferentes para ver los módulos. Por un lado podemos ver todos los módulos que están compilados con Apache. Por otro lado, podemos ver todos los módulos que carga Apache (esto incluye módulos compilados aparte).

    Módulos compilados

    httpd -l

    Esto no muestra el listado de módulos compilados en el binario de Apache:

    Compiled in modules:
      core.c
      mod_authn_file.c
      mod_authn_default.c
      mod_authz_host.c
      mod_authz_groupfile.c
      mod_authz_user.c
      mod_authz_default.c
      mod_auth_basic.c
      mod_include.c
      mod_filter.c
      mod_deflate.c
      mod_log_config.c
      mod_logio.c
      mod_env.c
      mod_headers.c
      mod_unique_id.c
      mod_setenvif.c
      mod_version.c
      mod_proxy.c
      mod_proxy_connect.c
      mod_proxy_ftp.c
      mod_proxy_http.c
      mod_proxy_scgi.c
      mod_proxy_ajp.c
      mod_proxy_balancer.c
      mod_ssl.c
      prefork.c
      http_core.c
      mod_mime.c
      mod_dav.c
      mod_status.c
      mod_autoindex.c
      mod_asis.c
      mod_suexec.c
      mod_cgi.c
      mod_dav_fs.c
      mod_dav_lock.c
      mod_negotiation.c
      mod_dir.c
      mod_actions.c
      mod_userdir.c
      mod_alias.c
      mod_rewrite.c
      mod_so.c

    Módulos cargados:

    httpd -M

    Así veremos todos los módulos que carga Apache:

    Loaded Modules:
     core_module (static)
     authn_file_module (static)
     authn_default_module (static)
     authz_host_module (static)
     authz_groupfile_module (static)
     authz_user_module (static)
     authz_default_module (static)
     auth_basic_module (static)
     include_module (static)
     filter_module (static)
     deflate_module (static)
     log_config_module (static)
     logio_module (static)
     env_module (static)
     headers_module (static)
     unique_id_module (static)
     setenvif_module (static)
     version_module (static)
     proxy_module (static)
     proxy_connect_module (static)
     proxy_ftp_module (static)
     proxy_http_module (static)
     proxy_scgi_module (static)
     proxy_ajp_module (static)
     proxy_balancer_module (static)
     ssl_module (static)
     mpm_prefork_module (static)
     http_module (static)
     mime_module (static)
     dav_module (static)
     status_module (static)
     autoindex_module (static)
     asis_module (static)
     suexec_module (static)
     cgi_module (static)
     dav_fs_module (static)
     dav_lock_module (static)
     negotiation_module (static)
     dir_module (static)
     actions_module (static)
     userdir_module (static)
     alias_module (static)
     rewrite_module (static)
     so_module (static)
     python_module (shared)
     evasive20_module (shared)
     qos_module (shared)
     php5_module (shared)
    Syntax OK

    Aquí se puede notar la diferencia entre los módulos compilados con el Apache (linkeados como ’static’) y los compilados como objetos compartidos que se cargan en tiempo de ejecución (’shared’).

    Ver virtual hosts

    También podemos ver todos los virtual hosts que están configurados en el Apache.

    httpd -S

    Esto nos va a mostrar una lista como esta:

    VirtualHost configuration:
    1.1.1.1:80       is a NameVirtualHost
             default server localhost (/etc/httpd/conf/extra/httpd-vhosts.conf:29)
             port 80 namevhost localhost (/etc/httpd/conf/extra/httpd-vhosts.conf:29)
             port 80 namevhost www.midominio.com (/usr/local/directadmin/data/users/usuario/httpd.conf:11)
    1.1.1.1:443      is a NameVirtualHost
             default server localhost (/etc/httpd/conf/extra/httpd-vhosts.conf:38)
             port 443 namevhost localhost (/etc/httpd/conf/extra/httpd-vhosts.conf:38)
             port 443 namevhost www.midominio.com (/usr/local/directadmin/data/users/usuario/httpd.conf:48)

    En el ejemplo vemos un hipotético servidor (usando Directadmin) con IP 1.1.1.1, y los virtual hosts para el puerto 80 y el 443, tanto los default como los que corresponden al dominio “www.midominio.com” del usuario llamado “usuario”.

    Nota sobre diferentes distribuciones

    El artículo lo escribí pensando en CentOS y otras distros donde el binario de Apache se llama httpd. En Debian y sus derivados, el binario es apache o apache2. Todos los comandos que comenté acá se pueden correr invocando esos binarios o apachectl (que en algunos casos puede ser apache2ctl).

    Quizás te interese:

    1. Ver dominios de Apache que más transferencia consumen
    2. Grave exploit para Apache descubierto
    3. mod_wsgi + Python 2.6 en CentOS

    12:58

    Mariano Guerra: Zürich

    mediante un artilugio transporteril que nos permitió ahorrar mucho dinero a cambio de unas cuantas horas de viaje llegamos a zurich.

    para los que anden por estos lares alguna vez, compramos un ticket de la región "Baden-Württemberg-Ticket" por 27 € que permite hasta a 5 personas viajar por toda la región durante todo un día (o €38 para toda Alemania), nos fuimos hasta Kontanz, ciudad que esta de los dos lados de la frontera, nos bajamos en la estación del lado alemán, caminamos unos metros y ya en suiza compramos unos tickets de ida y vuelta a zurich con una promoción con descuento si visitábamos un museo.

    Una vez allí dimos vueltas como es usual, las fotos son mejores que yo para describir el lugar (aunque no sea buen fotógrafo).

    algunas observaciones sobre el lugar:

    • Supongo que debido a su historia de cordura institucional y belica (o antibelica) la ciudad cuenta con muy pocas edificaciones despampanantes presentes en países donde monarquías o imperios se erigieron en algún momento. Tampoco hay estatuas (solo una y es de un gobernador) ni lugares describiendo batallas, guerras o algún tipo de destrucción.
    • Los semáforos peatonales tienen amarillo y son muy cortos :D
    • Al menos el día que estuvimos el clima fue muy cambiante.
    • Los precios son altos incluso cuando el franco suizo esta mas bajo que el euro.
    • Los ba~nos parecen ser mas preciados que las cuentas de banco secretas porque en todos lados te cobran 2 CHF (francos suizos) y en mc donals y similares te dan un código en el ticket para que los uses.



    pato en Alemania, yo en Suiza


    cisne rolinga






    los alpes al fondo

    el siempre presente sambuchito viajero (esta ves recargado con unos snacks que compramos para gastar los últimos francos suizos que teníamos)

    11:53

    Mariano Guerra: Stuttgart - apertura de la temporada asadistica

    El cumplea~nos de German fue el evento que marco la apertura de la temporada de asados 2010 en Stuttgart.






    el lugar

    la refrigeracion

    la gente
    la hora de finalizacion

    09:03

    Mariano Guerra: realizar accion al cambiar un archivo en un directorio

    este post esta sponsoreado por la necesidad de subir los cambios de una aplicación hecha con couchapp cada vez que realizo un cambio en un archivo*


    $ sudo aptitude install inotify-tools
    $ inotifywait -q -e modify -m -r . | while read line; do if echo $line | grep -v .*.swp
    ; then couchapp push; fi; done


    como uso vim y constantemente guarda el estado de la edición en archivos ocultos que terminan en .swp los filtro para evitar actualizar innecesariamente.

    * tengo el tick de hacer un cambio y probarlo

    abuante inotify y bash

    domingo, 28 febrero

    23:55

    Facundo Batista: Más y más películas.

    Hace casi cinco meses que no actualizaba la lista de vistas/anotadas, y por eso se juntó tanto... Vistas: 88 minutes : +0. Buen ritmo, buen enigma, aunque nada del otro mundo. Alatriste : +1. Buenas actuaciones, buena historia, y muy bien ambientado. Anamorph : +0. Interesante desde un par de puntos de vista, pero nada del otro mundo. Avatar : +1. Buenísima historia, fascinante la producción. Lo real de la "realidad inventada" asusta. Burn after reading : -0. Buenos actores, buenas actuaciones, y una historia mezclada e interesante, pero que no conduce a nada. Cloverfield : -0. Lo único que tiene piola es el manejo de la cámara... Deception : +0. Buena trama, buenas actuaciones, podría tener más consistencia. Eastern promises : +0. Historia simple, pero bien armada, bien llevada. El amor en los tiempos del cólera : +1. Muy buenas actuaciones, y por supuesto la historia no tiene desperdicio. Get smart : +0. Si te gusta o gustó el Superagente 86, no te la podés perder. Hanckok : +1. Es divertida y dinámica, y le da un punto de vista nuevo al concepto de "superhéroe". I am legend : +1. Dinámica y bien armada, muestra un muy posible futuro cercano. Indiana Jones and the kingdom of the Crystal Skull : +1. Indiana Jones como siempre. Martín Fierro, el ave solitaria : +0. La historia es conocida, los dibujos de Fontanarrosa son espectaculares. Michael Clyton : +0. Una buena historia sobre la ética y los valores de una persona en su vida personal y laboral. Star Trek : +1. Dinámica y bien armada, es absolutamente imperdible si te gusta Viaje a las Estrellas. The day the Earth stood still : -0. La idea está buena, pero se podría explorar un poco más serio, y queda demasiado en el sentimentalismo barato. The forbidden kingdom : -1. Pensé que el humor la iba a salvar y quería darle una oportunidad a estas pelis de patadas... me equivoqué. The hunting party : +1 muy buena peli que muestra algunos tejes y manejes atrás de las guerras eternas de medio oriente. The mist : +0. No deja de ser una película de terror más, pero es de un libro de Stephen King, y aparte tiene uno de los finales más duros que ví en una película. The nines : +0. Película muy loca, interesante, pero rara. The notebook : +1. Fantástica historia, presentando dos o tres preguntas que hay que contestarse en la vida. The sentinel : +0. Se nota que es la peli de una novela, porque quedan mil detalles a medio explicar. Más allá de eso es entretenida. Things we lost in the fire : +1. Una historia muy bien contada sobre dos personas que necesitan salir de su pozo en particular. Benicio del Toro, *muy* bien. Wanted : +1. Acción de la buena, bien armada y contada, con lo justo de misterio. Zeitgeist : +1. Documental en tres partes, imperdible para enterarse de algunas verdades. Nuevas: Pirate radio Los abrazos rotos A Nightmare on Elm Street Toy story 3 The imaginarium of Dr Parnassus Extraordinary measures Robin Hood Salt Daybreakers The sorcerer's apprentice Clash of the Titans Prince of Persia: The sands of time Hot tub time machine From Paris with love Inception Cop out When you're strange Wall Street: Money never sleeps Chloe Edge of darkness The ghost writer Finalmente, el resumen según cuando las anoté, ya con más historial: (26-Jan-2007)   1    1 (26-Mar-2007)   7    2 (15-Jun-2007)   4    2 (19-Nov-2007)  14   12    3 (23-May-2008)  25   24   21    4 (24-Sep-2008)  37   34   31   29 (21-Ene-2009)  22   19   19   19 (09-May-2009)       17   16   14 (15-Oct-2009)            21   20 (01-Mar-2010)                 19 Total:        113  111  111  105

    18:47

    John Lenton: cumpleaños

    Ayer fue mi cumpleaños. Tengo fotos!

    blend

    (del otro lado del link está todo el set).

    16:01

    Marcos Vanetta: Python en la tribu

    Ayer fui a al tribu y me di con esto en un mural:

    Actualización Me dice diegoM que ya salió un artículo similar en el blog de Facu [1]
    [1] http://www.taniquetil.com.ar/plog/post/1/438

    11:38

    Evita: Definiciones de archivos, estándares, gorilas y garcas

    Compañeros y compañeras:
    Muchas veces me llegan cartas a la Fundación Eva Perón, en la que me preguntan qué formatos de archivos se deben usar, cuáles son los estándares y cuáles responden a los intereses de los monopolios. Es fundamental para un linuxero peronista conocer a los leales y a los traidores. A los formatos libres y a los que solamente llevan agua para el molino de las multinacionales y las oligarquías explotadoras.
    Veremos una serie de formatos de archivo y sus cualidades.

    Archivos de oficina:
    Son los más usados en general por la clase media, ya que todo lo hacen con suites de oficina. Pero a medida que el peronista se va afianzando en su carrera de libertad, usa cada vez menos estos formatos. Lamentablemente muchos usan los archivos de cualquier maner, y para enviar una imagen, por ejemplo, la pegan en un archivo de procesador de texto (.odt o .doc Puaj!) siendo que no es el formato destinado para imágenes sino para texto enriquecido.
    Esta humilde servidora les pide:
    NO usar los privativos: .doc, .xls, .ppt, .mdb
    SÍ los libres y estandarizados: .odt, ods, odp, odb (Genéricamente ODF, incluyendo al .odg que es de gráficos vectoriales)
    también se puede usar el célebre PDF.
    Qué pasaría si mañana una empresa dice "el metro no vale nada. A partir de ahora se usará mi unidad de medida". Ergo, todas las reglas, centímetros de costurera, calibres, planos, moldes, etc. No se podrían usar. ¿Qué corresponde a un peronista libertario? ¿Seguir el negocio de la empresa o luchar por mantener los estándares mundiales? Si usamos .doc y esas mugres cipayas, estamos comportándonos según la primera opción, es decir, haciendo el juego a los monopolios.

    Gorilas que son gorilas desde siempre:
    Vienen de cuna gorila, con antepasados gorilas e historia gorila. Se han manifestado en contra del General Perón en el 55 y contra la compañera Cristina en estos tiempos de lucha popular. Podemos citar a Federico Pinedo, Padre, hijo y nieto. Familia de gorilas singularmente coherente con los intereses opresores del pueblo. Increíblemente, votantes "pensantes" lo siguen eligiendo, por lo que puede inferirse que se trata lisa y llanamente de garcas que no les importa el bienestar del pueblo trabajador. Macri, Martínez de Hoz, Blaquier, Noble, Roca, Mitre, Zuberbuhler, Guido, Rojas, Biolcati, Anchorena, Bullrich y en general los nombres de calles porteñas, son inherentes a este tipo de garcas con trayectoria. Asimismo, pequeños rufianes con plata quieren ser como ellos y lo manifiestan a los cuatro vientos, como los Susana Gimenez, Mirtha Legrand, Facho Castaña, Carlos Menem, Gerardo Sofovich, Biblita Carrió y demás perros falderos de las oligarquías de turno.

    Formatos multimediales:
    Con el desarrollo de las tecnologías, los archivos multimedia van siendo cada vez más populares. Hoy cualquier grasita puede tener en su computadora  un archivo, por ejemplo, con los mensajes basales del General Perón:


    Para los archivos multimediales es menester usar los formatos libres .ogg (audio), .ogv (vídeo), .jpg y .png (imágenes), .svg (gráficos vectoriales)

    Fulanos que eran progres y ahora son garcas:
    El peronista deberá saber discriminar quienes son los que abrazan las causas populares sin esperar nada a cambio y quienes buscan su bienestar o riquezas simulando ser parte de la lucha de la masa obrera. Tenemos por ejemplo a un León Gieco, que ha hecho muchas cosas del lado popular, pero en momentos de lucha contra la Sociedad Rural, no ha levantado ni un dedo para defender al gobierno popular. En cambio hace lobby para conseguir una ley de canon para que la masa deba pagar más caro un CD porque seguramente va a copiar un tema sin licencia (?). Lo mismo con varios artistas que no han dado ni la menor muestra de adhesión a la lucha contra los golpistas agrogarcas, ni la lucha contra el monopolio desinformativo Clarín. Afortunadamente sus propios compañeros han tomado nota de estas traiciones. Seudo progres como Alfredo Leuco, Ernesto Ténembaum, Nelson Castro, Fabián Gianola, Pepe Eliaschev, Castells, Lorena "si resucitara Castello te cagaría a patadas en el orto" Maciel, Gisela "ídem Maciel y encima te comiste a Grondona" Marziotta. Estos forjadores de una nueva "Unión Democrática" son los golpistas del mañana. Cuidado con ellos. El peronismo, como único e histórico defensor de los derechos populares, debe anticiparse a los movimientos de los que quieren, únicamente, vivir como reyes a expensas de la miseria de la clase obrera.
    Atentos compañeros y compañeras, estamos en tiempos difíciles, en los que hay que estar a la altura de la situación histórica.

    10:59

    Andrés Gattinoni: Apache Subversion

    Me entero leyendo VivaLinux que después de haber sido “incubado” desde finales del año pasado en la Apache Software Foundation (ASF), el sistema de control de versiones centralizado de Subversion (SVN) finalmente ya es oficialmente un proyecto de primer nivel en la prestigiosa organización sin fines de lucro.

    El 17 de febrero, un comité de directores de la ASF así lo votó. La comunidad de SVN se apresuró a festejarlo poco después. El nuevo hogar de Subversion ahora puede encontrarse en subversion.apache.org.

    Queda abierta la pregunta de Cristian, si con esta incorporación ¿se está convirtiendo Apache en el cementerio de elefantes de los proyectos de código abierto?

    Quizás te interese:

    1. Apache: 15 años
    2. Grave exploit para Apache descubierto
    3. Nuevo look

    sábado, 27 febrero

    23:45

    Facundo Batista: Lalita liberada por primera vez

    Python Argentina se deleita en anunciar la versión 0.1.1 de Lalita . Lalita es otro bot IRC más, uno donde es simple crear nueva funcionalidad agregando plugins fáciles de escribir. Esta es una liberación pre-alfa, nuestra primera liberación, pero el producto entregado es bastante robusto: lo estamos usando desde hace casi un año. Lalita está escrita con algunos objetivos en mente: Twisted! (no nos gustan los hilos) Enchufable: es fácil escribir nuevas funcionalidades Divertirse: sí, es Python Como se indica arriba, es realmente fácil agregar nueva funcionalidad (sólo hace falta copiar el plugin ejemplo y tocar un par de lineas), pero Lalita misma trae muchos plugins ya incluidos, entre los que se destacan: freenode: Ejecuta todo el diálogo de autenticación contra los servidores de Freenode (este plugin no ofrece funcionalidad al usuario final, pero permite que Lalita se conecte a Freenode usando un usuario registrado). misc: Implementa una funcionalidad muy simple: contesta "pong" al usuario cuando recibe un "ping". url: Colecciona todas las URLs que se dicen en los diferentes canales, permitiendo luego buscar entre las mismas. seen: Implementa dos comandos: "last" y "seen". El primero indica que es lo último que dijo un usuario, y el segundo muestra cuando un usuario fue visto por última vez (a veces ambos coinciden, a veces no). Para más información, esta es la página del proyecto .

    Administración y hosting cortesía de Net Managers SRL

    Tema por Andrés Antista

    Banner por Joaquín Sorianello

    Grazr OPML - FOAF - RSS - Log

    Blogs

    Anthony Lenton
    Leito Monk
    Gustavo Carmona
    Manuel Muradás
    Gonzalo Sainz Trápaga
    Marcos Vanetta
    Nicolás César
    Alberto Paparelli
    Santiago Peresón (Yaco)
    Margarita Manterola
    Javier Castrillo
    Santiago Bruno
    Mariano Draghi (cHagHi)
    Esteban Ordano
    Evita
    Alejandro Santos
    Manuel Kaufmann (Humitos)
    Joaquin Sorianello
    Angel Freire (cuerty)
    Marcelo Fernández
    Roberto Alsina
    Pablo Benjamín Arroyo
    Juan Pedro Fisanotti
    Gabriel Patiño
    Guillermo Heizenreder
    Marcos Dione
    John Lenton
    José C. Massón
    Ezequiel Gutesman
    Mauro Lizaur
    Mariano Guerra
    Matías E. Gieco
    Nicolás Miyasato
    Martín Gaitán
    Pablo Alejandro Costesich
    Mario Zorz
    PyAr en la OLPC
    Carlos Joel Delgado Pizarro
    Mariano Reingart
    Ramiro Morales
    Roberto Allende
    San Cayetano
    Alejandro Alvarez
    Martín Cerdeira
    Diego Sarmentero
    Walter Alini
    Sebastian Bassi
    César Portela
    Nicolás Echániz
    Fabián Gallina
    Juanjo Conti
    Héctor Sánchez (Karucha)
    Patricio Molina
    Andrés Gattinoni
    Facundo Batista
    Francisco Malbrán