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:
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:
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.
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:
Mariano Guerra: si los profesores de fisica explicaran asi..
recomiendo ver los 12
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.

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.
Sebastian Bassi: Downgrade pago
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.
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/
Mariano Guerra: Bad Wildbad
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 [...]
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!!
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:
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:
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/
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.
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 :)
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).



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 route e ifconfig.
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:
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!
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.
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.
import sys
from PyQt4 import QtGui, QtCore
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()
#MenuAhora 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.
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')
#SIGNAL->SLOT"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.
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)
#SystemTrayAhora 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)
self.tray = QtGui.QSystemTrayIcon(QtGui.QIcon(pixmap), self)
self.tray.setToolTip('PyTest')
self.tray.setVisible(True)
self.tray.setContextMenu(self.menu)
def showWindow(self):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:
self.setVisible(True)
def closeEvent(self, event):
event.ignore()
self.hide()
def show(self):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.
pass
app = QtGui.QApplication(sys.argv)Para descargar el ejemplo completo: pytest.zip
pytest = PyTest()
pytest.show()
sys.exit(app.exec_())
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:
Diego Sarmentero: Los Piratas de las Aguas Negras
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!
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:
Diego Sarmentero: PyTv! 1.0


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!
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 [...]
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...
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

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:
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
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...
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:

No me parece que esté tan mal.
Gustavo Carmona: Estoy Jugando con Django
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.
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 [...]
Andrés Gattinoni: Tips Apache: ver configuración desde la línea de comandos
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:
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:
Mariano Guerra: Stuttgart - apertura de la temporada asadistica
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
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
John Lenton: cumpleaños
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
Evita: Definiciones de archivos, estándares, gorilas y garcas
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:
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