Escrito por Iván Alonso el Jueves 28 de Enero de 2010

He estado resolviendo algunos problemas del Proyecto Euler y, tras conseguir los primeros veinticinco, me ha sorprendido con esto:

Parece que esté avanzando en un videojuego. Ya estoy dentro del veinte por ciento de usuarios que han hecho algo más que resolver los dos primeros (algo que hice hace un par de años). Ha costado volver a ponerme con el tema, pero estoy aprovechando que quería conseguir algo más de soltura con Python para, en vez de ponerme a hacer tutoriales insípidos, practicar con problemas de otro tipo.

Escrito por Iván Alonso el Viernes 22 de Enero de 2010

Si estás utilizando la última versión de Ubuntu (9.10 Karmic Koala) y la última versión de Eclipse (descargada de su propia página web, no la que se obtiene de los repositorios de Ubuntu), es posible que des con un error en el que algunos botones de determinados menús no reaccionan a las pulsaciones del ratón como deberían (aunque sí a las combinaciones de teclas Alt-letra, por ejemplo). Parece estar debido a algunos “trucos” gráficos que hace eclipse para saltarse algunas cosas del gdk, y para solucionarlo lo que hay que hacer es lanzar eclipse desde un script como este:

#!/bin/sh
export GDK_NATIVE_WINDOWS=1
/opt/eclipse-3.5/eclipse

Cambiando el path último por aquél en el que resida la instalación de Eclipse, claro.

Solución encontrada en norio.be. Otra opción es utilizar la versión de Eclipse del repositorio de Ubuntu, con esa versión el error no aparece.

Escrito por Iván Alonso el Domingo 17 de Enero de 2010

Vamos a instalar en nuestra máquina DLink DNS-323 la aplicación Tucan Manager, un software capaz de realizar descargas de servidores como Rapidshare, Megaupload, etc. Dado que Tucan Manager está desarrollada en Python, lo primero que haremos será instalar el intérprete de este lenguaje:

wget http://www.drak0.com/files/dns323/Python-2.5.2-2.tgz
funpkg -i Python-2.5.2-2.tgz

Tras esto nos descargamos e instalamos Tucan Manager, mediante:

wget http://forja.rediris.es/frs/download.php/1470/tucan-0.3.9.tar.gz
gzip -d tucan-0.3.9.tar.gz
tar -xvf tucan-0.3.9.tar
cd tucan-0.3.9/
make
make install

Y con esto los scripts de Python estarán disponibles donde deben. Si intentamos ejecutar la aplicación esta no funcionará (al menos en un sistema DNS-323). Si comprobamos la cabecera de cualquiera de los archivos, veremos que indica que para ejecutarse utilizará:

#! /usr/bin/env python

Que es un directorio que no existe. Lo solucionamos con:

ln -s /bin/env /usr/bin/env

Tendremos nuestro script en /usr/local/bin, y desde allí podríamos teóricamente lanzarlo mediante

./tucan

Pero eso nos devolverá un error ya que estará intentando lanzarse con el interfaz gráfico (y nos dirá que no encuentra el paquete pygtk). La forma de ignorar esto es lanzar tucan con el parámetro –cli (y para eso no podemos utilizar env, debemos lanzarlo con el intérprete de python):

python /usr/local/bin/tucan --cli

Aquí tenéis un manual de todas las opciones que tenéis para usar tucan desde línea de comandos, donde la más interesante será utilizarlo como un demonio que se descargue todos los enlaces incluidos en un archivo de texto (un enlace por línea), y que se ocupe de las descargas de modo completamente transparente. Comenzaremos a utilizar la aplicación con:

tucan -w updates
tucan -c -i archivo.txt

Si tenemos un error de No module named ImageFile, podemos solucionarlo descargándonos la librería pil (Python image library) e instalándola:

wget http://effbot.org/downloads/Imaging-1.1.6.tar.gz
gzip -d Imaging-1.1.6.tar.gz
tar -xvf Imaging-1.1.6.tar
cd Imaging-1.1.6/
python setup.py install

Tras esta compilación e instalación (que tardará un rato), aún nos faltan algunos otros proyectos que darán lugar a errores futuros si no los tenemos instalados. Primero instalaremos la librería tesseract-OCR, que tenemos disponible mediante el sistema de instalación de optwareipkg (si no lo tenéis configurado, podéis hacerlo con el este tutorial con apenas media docena de instrucciones). Instalaremos la librería (y todas sus dependencias automáticamente), mediante:

ipkg install tesseract-ocr
ipkg install tesseract-ocr-lang-eng
Escrito por Iván Alonso el Domingo 17 de Enero de 2010

Encontré un script de ejecución para MLDonkey mejor que el incluye el sistema de fonz por defecto, en el blog Writings on the wall. No me funcionaba tal y como estaba escrito, así que tuve que cambiar un par de cosas y ahora parece que hace lo que debe.

Ahora, puede especificarse en el arranque si quieres que la máquina se pare cuando terminen de descargarse todos los archivos de MLDonkey, o si sólo quieres que sea el propio MLDonkey el que se cierre, gracias a una tarea en el crontab que comprueba periódicamente el estado del servidor.

El script es el siguiente, sólo teniendo que cambiar la contraseña de tu usuario administrador de MLDonkey (para poder conectarte al servidor de descargas y poder pedirle su estado actual):

#!/bin/sh
 
# Found in:
# http://bfg100k.blogspot.com/2008/02/enhanced-mldonkey-script-for-your-dns.html
# Some things changed by Ivan Alonso (www.neverbyte.net)
#  - Changed the pattern searched in the mldonkey downloads status
#  - Changed FUNSH variable with SHELL
#  - Some minor changes in the echo messages
#  - Some paths changed to fit with the default installation paths
#    (fonz fun plug and shadowandy mldonkey versions)
 
###################################################################
# author: Sidney Chong (bfg100k[at]gmail[dot]com)                 #
# version: 0.2                                                    #
# date: 18/02/2008                                                #
#                                                                 #
# Version History                                                 #
# ---------------                                                 #
# v0.1 - expanded ShadowAndy(http://www.shadowandy.net) script    #
#        to be more robust on startup as well as added functions  #
#        to check status, stop, restart and auto-stop when        #
#        downloads are completed.                                 #
# v0.2 - added option to shutdown the DNS-323 when downloads are  #
#        completed. By default, the script only stops the         #
#        mldonkey process when there are no more active downloads.#
#                                                                 #
###################################################################
 
if [ -z ${SHELL} ]; then
  #setup the ENV variables if not found
  #this can happen when running from crontab
  echo "Environment variables not found, including fun_plug defaults."
  . /mnt/HD_a2/ffp/etc/profile
fi
 
export MLDONKEY_DIR="/mnt/HD_a2/mldonkey"
export TMPDIR="/mnt/HD_a2/mldonkey/temp"
 
MLNETBINDIR="/mnt/HD_a2/ffp/bin"
MLNETLOG="/mnt/HD_a2/mldonkey/mlnet.log"
TMP_CRONTAB="/mnt/HD_a2/ffp/var/log/crontab.tmp"
TMP_DL_STATUS="/mnt/HD_a2/ffp/var/log/dl.status.tmp"
ADMIN_PSWD="PUT HERE YOUR MLDONKEY ADMIN PASSWD"
 
mlnet_start() {
  echo "Starting mlnet startup sequence... "
  #check if mlnet is already running. if yes, do nothing
  if [ `mlnet_status` = "running" ]; then
    echo "INFO: mldonkey already running! Nothing to do."
    return
  fi
  #check for inproper clean up from the past
  if [ -e ${MLDONKEY_DIR}/mlnet.pid ]; then
    rm ${MLDONKEY_DIR}/mlnet.pid
  fi
 
  if [ -d "${MLDONKEY_DIR}" ]; then
    echo "mldonkey directory found."
  else
    echo "mldonkey directory (${MLDONKEY_DIR}) not found. Creating one..."
    mkdir ${MLDONKEY_DIR}
    #change ownership of the folder to the user account we will use to run mlnet
    #chown 504:703 ${MLDONKEY_DIR}
  fi
  #chmod 664 ${MLDONKEY_DIR}/*
  ${MLNETBINDIR}/mlnet > ${MLNETLOG} 2>&1 &
  #${MLNETBINDIR}/mlnet -run_as_useruid 504 > ${MLNETLOG} 2>&1 &
  if [ -d "${MLDONKEY_DIR}/incoming" ]; then
    chmod 777 ${MLDONKEY_DIR}/incoming/
    chmod 777 ${MLDONKEY_DIR}/incoming/*
  fi
  _mlnet_setup_softstop stop_when_done
  echo "mlnet startup sequence completed."
  echo "Check ${MLNETLOG} for more details."
}
 
mlnet_stop() {
  echo "Stopping mlnet... "
  if [ `mlnet_status` = "running" ]; then
    echo -n "Killing mlnet process... "
    if [ -e ${MLDONKEY_DIR}/mlnet.pid ]; then
      cat ${MLDONKEY_DIR}/mlnet.pidxargs kill
    else
      pidof mlnet  xargs kill
    fi
    echo "done. All mlnet processes killed."
  else
    echo "INFO: mlnet not running! Nothing to kill."
  fi
  _mlnet_setup_softstop
  echo "mlnet stop sequence completed."
}
 
# this routine checks to see if mlnet is still alive
# and if there are any downloads active.
# if no downloads are active, it attempts to stop mlnet.
# if "off_when_done" option is specified, it will attempt to
# shutdown the DNS-323 as well.
_mlnet_softstop() {
  echo -n "`date`: Checking downloads... "
  #touch ${TMP_DL_STATUS}
  wget -O ${TMP_DL_STATUS} -q "http://admin:${ADMIN_PSWD}@127.0.0.1:4080/submit?q=vd"
  if grep -q '<td class="dl al np">R</td>' ${TMP_DL_STATUS}
  then
    echo "downloads are still active!"
  else
    echo "no active downloads found!"
    mlnet_stop
    if [ "${1}" = "off_when_done" ]; then
      echo "attempting to shutdown the DNS-323 now. Bye Bye!"
      touch /tmp/shutdown
    fi
  fi
  rm ${TMP_DL_STATUS}
}
 
# this routine sets up softstop as a cron job that runs every half hour
# to ADD the cron job, pass "add" into the routine,
# to ADD the cron job with shutdown option, pass "off_when_done",
# any other values (or no value) means REMOVE by default
_mlnet_setup_softstop() {
  echo "Setting up softstop on crontab... "
  crontab -l > ${TMP_CRONTAB}
  sed -i -e '/mlnet.sh softstop/d' ${TMP_CRONTAB}
  TMP_NAME=""
  case "$1" in
    stop_when_done)
      TMP_NAME="softstop"
      echo "INFO: This job will stop mldonkey when all downloads are completed."
    ;;
    off_when_done)
      TMP_NAME="softstop_off"
      echo "INFO: This job will attempt to shutdown the DNS-323 when all downloads are completed."
    ;;
    *)
      echo -n "Removing job from crontab... "
    ;;
  esac
  if [ "${TMP_NAME}" != "" ]; then
    # sanity check - do not allow adding any job if mlnet is not already running
    if [ `mlnet_status` = "running" ]; then
      echo -n "Adding cron job to run every half hour... "
      echo -e "0,30 * * * * /mnt/HD_a2/ffp/start/mlnet.sh ${TMP_NAME} >> /mnt/HD_a2/mldonkey/mlnet.log 2>&1" >> ${TMP_CRONTAB}
      sed -i -e '/^\s*$/d' ${TMP_CRONTAB}
    else
      echo "ERROR: mlnet is not running. NOT adding job to crontab."
    fi
  fi
  crontab ${TMP_CRONTAB}
  rm ${TMP_CRONTAB}
  echo "done."
}
 
mlnet_restart() {
  mlnet_stop
  echo "Waiting 10 secs before starting daemon..."
  sleep 10
  mlnet_start
}
 
mlnet_status() {
  if [ -n "$(pidof mlnet)" ]; then
    echo "running"
  else
    echo "stopped"
fi
}
 
case "$1" in
  stop)
    mlnet_stop
    ;;
  softstop)
    _mlnet_softstop
    ;;
  softstop_off)
    _mlnet_softstop off_when_done
    ;;
  set_off_when_done)
    _mlnet_setup_softstop off_when_done
    ;;
  set_stop_when_done)
    _mlnet_setup_softstop stop_when_done
    ;;
  restart)
    mlnet_restart
    ;;
  status)
    mlnet_status
    ;;
  start'')
    mlnet_start
    ;;
  *)
    echo "Usage: $0 start | stop | restart | status | set_off_when_done | set_stop_when_done"
    ;;
esac
Escrito por Iván Alonso el Domingo 27 de Diciembre de 2009

Tras trastear un rato con sed y distinta posibilidades de búsqueda de archivos para poder aplicarlo a varios de ellos, he encontrado esta única instrucción en perl que acaba siendo mucho más sencilla:

perl -pi -w -e 's/texto viejo/texto nuevo/g;' *.php

En las secciones a buscar y reemplazar hay que acordarse de escapar con la barra invertida (‘\’) determinados caracteres, como paréntesis, barras, etc.

Actualizado: para hacerlo recursivo desde un determinado directorio, la mejor solución que he encontrado ha sido:

perl -pi -w -e 's/oldstring/newstring/g;' `grep -ril oldstring *`
Escrito por Iván Alonso el Lunes 21 de Diciembre de 2009

Hace ya unos meses que había comenzado a rediseñar esta página, pero me había quedado parado tras terminar la cabecera y un par de detalles más. He hecho un par de cosas nuevas y lo he traducido todo a un theme de WordPress, para poder ponerlo en pruebas en la página y así poder ir trabajando sobre algo visible.

Está en permanente construcción, como todo en Internet…  

Captura de pantalla 2009-12-21 a las 17.51.54.png

Escrito por Iván Alonso el Lunes 21 de Diciembre de 2009

Vamos a por nuestro primer ejemplo con OpenGL. Tras las explicaciones del anterior post sobre OpenGL, la única puntualización necesaria sería sobre qué es eso de GLUT que pone en el título del post. GLUT es el acrónimo de openGL Utility Toolkit, y viene a ser poco más que un wrapper para facilitar las tareas más comunes, con llamadas algo más sencillas. A los desarrolladores de OpenGL debería decirles algo el hecho de que este tipo de productos existan y sean tan ampliamente utilizados. Como veremos, también incluye algunas facilidades para el uso del teclado y ratón.

Nosotros lo utilizaremos únicamente para este primer ejemplo, para afianzar conceptos básicos… porque con él estamos perdiendo una gran cantidad de productos potenciales en lo que ejecutar nuestro código (GLUT únicamente existe para los sistemas principales, pero no para consolas, específicamente para productos homebrew que no disponen de SDKs oficiales, ni para el iPhone). Además se dejó de trabajar en GLUT hace tiempo, ahora habría que utilizar freeglut y blablabla… conclusión: no lo vamos a utilizar en el futuro.

Lo primero que haremos será crear un nuevo proyecto, de tipo Command Line Tool, para C++, al que pondremos como nombre lo que más rabia nos dé (a mi se me ha ocurrido Demo01, en un arranque de originalidad):

Captura de pantalla 2009-11-17 a las 11.04.11.png

Se creará un proyecto con un único archivo de código (main.cpp). La siguiente tarea a realizar será añadir las referencias a los frameworks/librerías que vamos a utilizar, en este caso OpenGL. Esto lo haremos haciendo click derecho sobre el proyecto, Add, Existing Frameworks:

Captura de pantalla 2009-11-17 a las 11.07.48.png

Otra de las buenas cosas de los Mac es que todo está localizado donde debe. Así que todos los frameworks instalados en el sistema se mostrarán en una lista de la que tan sólo hemos de escoger OpenGL.framework y GLUT.framework (OpenGL Utility Toolkit) y añadirlos al proyecto.

Lee el resto de esta entrada »

Escrito por Iván Alonso el Viernes 18 de Diciembre de 2009

200912181358.jpg

Vía Nunca me entero de nada

Escrito por Iván Alonso el Martes 15 de Diciembre de 2009

http://technorati.com/tools dice:

Technorati has redesigned our sites and many things have changed. Technorati tools are not currently available with the new site launch. We plan to bring some back soon! Thank you for your patience.

Creo que la muerte de Technorati es más que patente. Define claramente la vida útil de la mayor parte de proyectos y empresas en internet. Cualquier emprendedor debería tener bastante claro que su objetivo debería ser crecer, crecer y crecer, vender lo más caro posible y desentenderse del proyecto. De todas formas antes o después el interés en el mismo va a caer…

Escrito por Iván Alonso el Martes 15 de Diciembre de 2009

Esta mañana me he puesto a revisar neverbot.com, y he descubierto que tenía cincuenta y tantos errores que impedían que la página validara correctamente según el W3C… principalmente eran culpa del nuevo sistema para ver el estado de twitter, del badge inferior donde se veía una foto aleatoria de mi flickr y del contador de visitas de statcounter (invisible).

Cambios principales:

  • En llamadas a scripts y similares, cambiar todos los ampersand (&) por &amp;
  • Cambiar completamente el badge de flickr por uno ad hoc. Yo he seguido este post, y ahora muestro cuatro imágenes siendo el resultado perfectamente válido.
  • No olvidar los atributos alt en las imágenes que incluyamos en la página, aunque estén vacíos (alt=”"). A mí siempre se me pasa.

Ahora puede comprobarse la validez de la página… sólo me queda comprobar todas las demás que mantengo, como esta misma.

Actualizado: neverbyte también pasa el test XHTML 1.0 Transitional