Wiithon 1.0 liberado!!

Actualizado: lunes, 29 de junio de 2009

Creo que ya es el momento de publicar esta versión de wiithon con un GUI basado en GTK. Un desarrollo que empeze en abril, (trás publicar wiithon 0.98) sin tener apenas expriencia en GTK, gracias a Jose Luis Segura(LK2) y Google, he aprendido lo sufuciente en GTK para llegar al punto en el que estamos.

Sin dar más vueltas os expongo ls partes que va a tener esta presentación:

  1. Características
  2. Descargas
  3. Instalación
  4. Ejecución
  5. Actualización
  6. Traducir wiithon
  7. Agradecimientos.
  8. Team wiithon
  9. Screenshots

Lee más »

Screenshot wiithon

Cada vez estamos más cerca de una versión estable, hoy llevo toda la tarde probando el buscador y va muy muy fino. (Utilizo un ORM llamado SQlAlchemy que a su vez esta basado el SQLLite).
Lee más »

“No le deberíamos haber dejado llamar por teléfono” by ladrones=SGAE

Lo que le ha pasado a este chaval esta semana no tiene nombre, sencillamente cada vez que lo pienso me da más asco mi propio país por la simple existencia de la SGAE en él.

La lectura es imprescindible, nunca antes ha pasado algo tan heavy a pesar de su historial, la SGAE a cometido 34535 delitos en este acto (que por supuesto saldrá impune).

En resumen(es muy tarde para escribir): la SGAE se ha hecho pasar por una gente “del juzgado” con una orden judicial que le permitía llevarse sus ordenadores. El chaval un poco dormido permitió la entrada, ya que no supo reaccionar inicialmente, le revisaron todos los ordenadores e incluso intentaron acceder en ordenadores de otros familiares de los cuales la victima de la SGAE no sabía la contraseña, pues bien los “jueces” trataran un mini fuerza bruta sobre el ordenador de su hermano, en frente de sus narices, sin exito por supuesto. Por suerte antes de que siguieran tocando sus ordenadores, les pidio llamar a David bravo, le conto todo y tras una acalorado conversación pidio que se marcharan de su casa, sin ordneadores por supuesto. Como colofón final, la secretaría antes de irse y subestimando a esta persona, como si fuera un ignorante del derecho de las personas, le dijo “No TE deberíamos haber dejado llamar al abogado”. !!!!!!!!!  en fin me hierve la sangre.

Estamos cansado de dar argumentos por los cuales debe desaparecer la SGAE. Es una locura mantener esta situación y yo de corazón estoy hasta los cojones.

El autor del suceso lo cuenta mejor en su blog:

http://blog.grupoet.com/?p=54

Esta persona que antes he llamado victima se llama Juan José Coronel Carrasco, y ahora más que nunca todos los internautas debemos apoyarle a él, y a cualquier iniciativa para conseguir destruir la SGAE.

ÁNIMO JUAN JOSÉ, ESTAMOS CONTIGO!

Script para ripear imagenes masivamente* (Actualizado)

Ultima modificación: jueves, 28 de mayo de 2009

Necesitaba ripear unas 5000 imagenes en el curro, en cada una de ellos necesitaba pasarlo de TIFF a JPG y fijar el ancho a 800 y alto libre manteniendo aspect ratio.

Me he hecho este script cuyo uso simplemente es pasar todos las carpetas que vamos a trabajar como parametros. Por ejemplo:

Uso: ripearImagenes CARPETA1 CARPETA2 CARPETA3 … CARPETAN

Escribiendo ripearImagenes sin parametros es equivalente a pasar el directorio actual como primer parametro.

Simplemente gedit ripearImagenes y pasteamos, además podeis poneros el script en algún directorio “PATHeado” (evidentemente, esto ultimo es opcional xD):

#!/usr/bin/python

#
# :: Invasion Tux
# :: Ultima modificacion : jueves, 28 de mayo de 2009
# :: Script realizado por makiolo (makiolo@gmail.com) (Licencia Creative Commons con reconocimiento)
# :: Ultima version : http://blogricardo.wordpress.com/2009/05/15/script-para-ripear-imagenes-masivamente/
# :: Dependencias : python , convert
#

import os,sys,glob,subprocess,shutil

######### CONFIGURACION ##############

SUFIJO = "_RIPEADO"
DESTINO = ".png"
ANCHO = 2000
FORMATOS_VALIDOS = ["jpg","gif","png","tif"]

######################################

def getExtension(fichero):
	posPunto = video.rfind(".")
	return fichero[posPunto+1:len(fichero)]

def extensionEsValida(fichero):
	posPunto = video.rfind(".")
	if posPunto != -1:
		extension = getExtension(fichero)
		try:
			FORMATOS_VALIDOS.index(extension)
			return True
		except ValueError:
			return False
	else:
		return False

def getNombreRipeado(fichero):
	return fichero+SUFIJO+DESTINO

def getCarpetaRipeados( dir_inicial ):
	return "%s_RIPEADOS" % ( os.path.basename(dir_inicial) )

def existeRipeado(fichero):
	return os.path.exists(getNombreRipeado(fichero))

def ripear(fichero):
	ret = subprocess.call('convert "%s" -quiet -resize %d "%s"' % ( fichero , ANCHO , getNombreRipeado(fichero) ) , shell=True)
	return ret == 0

def ripearTodo( carpeta ):
	imagenes = []
	for extension in FORMATOS_VALIDOS:
		imagenes += glob.glob("*."+extension)
	borradas = 0
	copia = []
	lenFinal = len(SUFIJO+DESTINO)
	for imagen in imagenes:
		if(imagen[-lenFinal:] != SUFIJO+DESTINO):
			if os.path.isfile(imagen):
				copia.append(imagen)
		else:
			os.remove( imagen )
			borradas = borradas + 1
	print "+ Borradas %d imagenes ripeadas" % (borradas)

	total = len(copia)
	print "+ Ripeando %d imagenes: " % total
	i = 1
	for imagen in copia:
		print "  - Ripeando %d de %d\r" % (i , total),
		sys.stdout.flush()
		if ripear(imagen):
			shutil.move( getNombreRipeado(imagen) , carpeta)
		else:
			print "Error ripeando %s. Posiblemente no sea una imagen." % (imagen)
		i+=1

def App():
	try:
		if len(sys.argv) == 1:
			sys.argv.append(".")
		dir_inicial = os.getcwd()
		for parm in sys.argv:
			if parm != sys.argv[0]:
				if (os.path.isdir(parm)):
					carpeta = getCarpetaRipeados( dir_inicial )
					if not os.path.exists(carpeta):
						os.mkdir(carpeta)

					parm = os.path.abspath( parm )
					carpeta = os.path.abspath( carpeta )
					os.chdir(parm)
					print "Trabajando %s" % parm
					ripearTodo( carpeta )
					os.chdir( dir_inicial )
				else:
					print '"%s" no es un directorio' % parm
	except KeyboardInterrupt:
		print "ancelado por el usuario"

if __name__ == '__main__':
	App()

Laberinto TD, ganador del MobiGame 2009 !!!

Este es el primer año que me presento al MobiGame e incluso que aprendo J2ME como ya dije en “Aprendiendo J2ME para el MobiGame“, aunque si que he trasteado mucho con J2SE (tengo un juego Java tipo Worms por hay subido que  hice con 14 tacos y ahora tengo 23).

Gracias al ejemplo de GameCanvas que viene con NetBeans no tardé ni un rato en tener una primera versión de un muñeco moviéndose por el escenario. Un mes después presente todo el análisis y diseño y alguna screen (solo había 1 tipo de torre y 1 tipo de enemigo en ese momento.)

Ha sido mi primer año y realmente me ha gustado mucho, ha habido muy buenos juegos y cualquiera podría haber ganado, estaba muy igualado. Os doy las gracias a todos los participantes por haber hecho que realmente haya competición. También gracias a la organización y todo el ambiente que han creado.

Lee más »

wiithon . WBFS GUI en Linux para WII . v0.98!

Espacios en for i in $(ls)

#!/bin/sh

IFS=$'\x0A'$'\x0D' ;
for i in $(find -iname "*.avi"); do
mv -v "$i" . ;
done;

Chuleta:  Para que el for no considere el espacio un separador, y una tarea como la del ejemplo lo realize bien. El script de ejemplo mueve todos los videos de subcarpetas al directorio actual.

Espacio en disco ocupado por un directorio

Un comando muy útil es du. Sirve para calcular el espacio que ocupa un disco un diretorio. Para ello calcula todo lo que tiene dentro del directorio, (recursivamente para el caso de los directorios). El uso simple es pasando el directorio como primer y único parámetro. Por ejemplo:

makiolo@blog:~$ du /home/makiolo/videos/The\ Big\ bang\ Theory/temp2
3048960    /home/makiolo/videos/The Big bang Theory/temp2

Para poner las unidades comprensibles añadimos el parametro -h:

makiolo@blog:~$ du -h /home/makiolo/videos/The\ Big\ bang\ Theory/temp2
3,0G    /home/makiolo/videos/The Big bang Theory/temp2

Mostrando solo los GB libres:

makiolo@blog:~$ du -h /home/makiolo/videos/The\ Big\ bang\ Theory/temp2 | tail -n1 | cut -f1
3,0G

Jugando más con las tuberías:

makiolo@blog:~$ du -h /home/makiolo/videos/The\ Big\ bang\ Theory/temp2 | tail -n1 | awk ‘{print “El directorio “$2″ ocupa “$1}’
El directorio /home/makiolo/videos/The Big bang Theory/temp2 ocupa 3,0G

Me hago un script final que es el que usaré, gedit espacioLibre.sh y pasteamos:

#!/bin/sh

if [ $# = 0 ]; then
DIRECTORIO=`pwd`
else
DIRECTORIO=$1
fi;

du -h $DIRECTORIO | tail -n 1 | awk ‘{print “El directorio ” $2 ” ocupa ” $1}’

Presentación de Laberinto Tower Defense

Llevo 4 fines de semana haciendo el desarrollo de Laberinto TD. Aunque el análisis y diseño es un trabajo de mucho tiempo (meses/años) de un juego que estaba haciendo (y cuando pueda lo seguiré) en c++.
El juego es una defensa de Torretas, como los custom maps del Warcraft3 y esta desarrollado más o menos al 50%:
Las caracteristicas del juego son las siguientes:

  1. Busqueda de caminos por los enemigos mediante IA, he implementado el algoritmo A*.
  2. 10 mapas, 50 niveles y 4 dificultades.
  3. Haré unos 10 tipos de torretas: hielo, splash, arrow, aura, aturdir, laser,veneno, invis, ultimate ….
  4. Cada tipo de torreta se podrá actualizar entre 5 y 20 levels.
  5. Todo se financiara con oro, la forma de obtenerlo es matando enemigos y consiguiendo hitos.
  6. Haré unas instrucciones de uso y ayudas en distintos menús de elección.
  7. Se guardarán persistentemente las máximas puntuaciones en cada mapa.
  8. Las condiciones de victoria es pasarte los 50 niveles.
  9. Las condiciones de derrota es no perder todas las vidas o alcanzar un número de máximo de enemigos.

Os pongo algunas imagenes:

Acepto cualquier sugerencia e idea. En mi opinión si consigo implementar todo lo que tengo pensado el juego puede ser un autentico vicio en esta o en cualquier plataforma. Espero que al menos os parezca interesante. Un saludo.

Aprendiendo J2ME para el MobiGame

Me voy a presentar el MobiGame (a punta de pistola por nuestro profe de informática distribuidda). Tengo poco tiempo asi además de enpoyarme el API de MIDP 2.0 aprovechare el análisis y diseño de mi maze tower hecho en una arquitectura muy distinta (pc, c++, physx , ogre …). Ya pondre algun post de mis avances. Mientras tanto usaré estos post para ir poniendo recursos que me parezcan interesantes.

Desde luego un torretas para movil sería algo muy novedoso en esta plataforma, y yo sería el primero que me estaría viciando por eso lo hago ;D

Español:

http://leo.ugr.es/J2ME/MIDP/index2.htm

http://www.it.uc3m.es/celeste/docencia/j2me/tutoriales/midp2_0/PracticaGame/

http://www.lcc.uma.es/~galvez/J2ME.html

Ingles:

http://wiki.netbeans.org/CreatingJavaMEGamesWithGameBuilder

http://today.java.net/pub/a/today/2005/02/09/j2me1.html

http://developers.sun.com/mobility/midp/articles/gameapi/

http://www.mcobject.com/perst_eval

Script para hacer copias de seguridad incrementales

Actualizado : lunes, 09 de febrero de 2009
Hoy público en script que tenía hace tiempo funcionando pero muy mal estructurado, hoy he estado puliendolo y creo que esta suficientemente presentable como para publicarlo. Esta basado en bash (no es necesario python para nada) y la idea es poder hacer copias incrementales de la forma más fácil posible. (sin parametros o pocos parametros con buenos valores por defecto).

El script se puede ejecutar con 0, 1 o 2 parametros:

  • 0 parametros : si simplemente ejecutamos el script, sin parametros, considerará que quieres hacer una copia de seguridad del directorio de trabajo actual. Si el directorio activo es por ejemplo: /home/makiolo/descargas se creara el directorio copia_de_descargas con la copia principal y las copias incrementales.
  • 1 parametros : si no queremos especificar el directorio que queremos salvar de forma implicita (por directorio de trabajo), sencillamente pasamos la ruta del directorio que queremos salvar(absoluta o relativa) como primer parametro. Se creara en el mismo directorio que queremos salvar la carpeta copia_de_$nombre con la copia principal y las copias incrementales. Como he dicho las rutas pueden ser relativas o absolutas, pero es recomendable las absolutas pero definitivamente evitar el determinismo del directorio de trabajo.
  • 2 parametros : Tener la copia de seguridad junto original no es muy útil si sufrimos una perdida de información. Es evidentemente recomendable tener la copia en un disco distinto al original. Por tanto:
    • 1er parametro : carpeta que queremos salvar.
    • 2º parametro : destino de la copia de seguridad
  • Alguna cosas más importantes:
    • .rsyncExcluir : se hace un listado de directorios y archivos que se excluyen de la copia de seguridad. Si no existe se crea excluyendo a si mismo y al destino de la copia de seguridad. Para evitar hacer una copia de la copia :/
    • En copia_de_$nombre/principal/ : Esta es la copia más reciente, y si ejecutas tu comando con cierta frecuencia es una copia exacta del original.
    • En copia_de_$nombre/incrementales/ : Se crea un incremental por día, (excepto si en ese día no hubo cambios). Tal y como esto en AÑO-MES-DIA, no sería dificil cambiar el date para realizar otro tipo de partición. Si especificamos hora y minuto podría ser excesivamente particionado. Podríamos cambiar el script para agrupar por otros criterios, por ejemplo fecha+turno (grupo de mañana o de tarde), o por numero de la semana si las copias de seguridad son semanales. En los incrementos solo se guarda el cambio respecto al principal que se hizo ese día.
  • Asi que simplemente hacer gedit copiaSeguridad , copy & paste  y darle permisos.
#!/bin/sh
#
# :: Invasion Tux
# :: Ultima modificacion : lunes, 09 de febrero de 2009
# :: Script realizado por makiolo (makiolo@gmail.com)  (Licencia Creative Commons con reconocimiento)
# :: Ultima version : http://blogricardo.wordpress.com/2009/02/08/script-para-hacer-copias-de-seguridad-incrementales
# :: Dependencias : rsync
#

################################# VARIABLES ##############################################

if [ $# -eq 0 ]; then
	# Directorio que queremos salvar
	DIRECTORIO_A_SALVAR=`pwd`

	# construir nombre subdirectorio
	NOMBRE_MES_ANIO=`date +"el_mes_%m_del_%Y"`
	NOMBRE_SALVADO=`basename $DIRECTORIO_A_SALVAR`
	SUB_DIRECTORIO_A_SALVAR="copia_de_"$NOMBRE_SALVADO"_en_"$NOMBRE_MES_ANIO

	# directorio donde se guarda el backup
	DESTINO_DE_LA_COPIA=$DIRECTORIO_A_SALVAR/$SUB_DIRECTORIO_A_SALVAR
elif [ $# -eq 1 ]; then
	# Directorio que queremos salvar
	DIRECTORIO_A_SALVAR=$1

	# construir nombre subdirectorio
	NOMBRE_MES_ANIO=`date +"el_mes_%m_del_%Y"`
	NOMBRE_SALVADO=`basename $DIRECTORIO_A_SALVAR`
	SUB_DIRECTORIO_A_SALVAR="copia_de_"$NOMBRE_SALVADO"_en_"$NOMBRE_MES_ANIO

	# directorio donde se guarda el backup
	DESTINO_DE_LA_COPIA=$DIRECTORIO_A_SALVAR/$SUB_DIRECTORIO_A_SALVAR
elif [ $# -eq 2 ]; then
	# Directorio que queremos salvar
	DIRECTORIO_A_SALVAR=$1

	# construir nombre subdirectorio
	NOMBRE_MES_ANIO=`date +"el_mes_%m_del_%Y"`
	NOMBRE_SALVADO=`basename $DIRECTORIO_A_SALVAR`
	SUB_DIRECTORIO_A_SALVAR="copia_de_"$NOMBRE_SALVADO"_en_"$NOMBRE_MES_ANIO

	# directorio donde se guarda el backup
	DESTINO_DE_LA_COPIA=$2/$SUB_DIRECTORIO_A_SALVAR
else
	echo "Numero de parametros incorrecto"
	exit
fi

# Archivos donde listamos las exlusiones de la backup
FICHERO_DE_EXCLUSION=$DIRECTORIO_A_SALVAR/.rsyncExcluir

# subdirectorio donde se guarda la copia principal
COPIA_PRINCIPAL=$DESTINO_DE_LA_COPIA/principal

# subdirectorios donde se guardan las copias incrementales
COPIA_INCREMENTOS=$DESTINO_DE_LA_COPIA/incrementales

# ruta variable de copias incrementales
COPIA_INCREMENTOS_VARIABLE=$COPIA_INCREMENTOS/`date | awk '{print $3}'`

# opciones de rsync , mejor no tocar
OPCIONES="--force --ignore-errors --delete --delete-excluded \
 --exclude-from=$FICHERO_DE_EXCLUSION --backup --backup-dir=$COPIA_INCREMENTOS_VARIABLE -av"

################################# FUNCIONES ##############################################
ejecutarRsync()
{
	if [ ! -f $FICHERO_DE_EXCLUSION ]; then
		echo `basename $DESTINO_DE_LA_COPIA`"/" > $FICHERO_DE_EXCLUSION
		echo ".rsyncExcluir" >> $FICHERO_DE_EXCLUSION
		echo "*~" >> $FICHERO_DE_EXCLUSION
	fi
	rsync $OPCIONES $DIRECTORIO_A_SALVAR $COPIA_PRINCIPAL
}

################################# MAIN ##############################################

# nos aseguramos de que existen los directorio de destino de la copia de seguridad
mkdir -p $DESTINO_DE_LA_COPIA
mkdir -p $COPIA_PRINCIPAL
mkdir -p $COPIA_INCREMENTOS

if [ ! -d $DIRECTORIO_A_SALVAR ]; then
	echo "No se encontro el directorio a salvar : $DIRECTORIO_A_SALVAR";
elif [ ! -d $DESTINO_DE_LA_COPIA ]; then
	echo "No se encontro el directorio de destino de la copia : $DESTINO_DE_LA_COPIA";
else
	ejecutarRsync
fi

Es un script excelente para combinarlo con un cron 24h.

Si no entendeis para que sirve el script o no sabeis que es una copia incremental –> google xD, no hombre podeis preguntarmelo y eso xD

Tambien si encontrais algún bug os lo agradeceré mucho que lo comenteis.

GTA Real : GO 6 estrellas

Procesar y borrar elementos de una lista en O(n)

Voy a explicar que elección de diseño he elegido en mi juego para la gestión de la lista de entidades.

En todo videojuego hay una lista de entidades que necesitan hacer en su máximo nivel de abstracción 2 cosas:

  1. Procesar todos los elementos. Esto es que cada elemente tiene un metodo, tipicamente refrescar() o update() que abstrae toda la secuencia de proceso que tiene que hacer.
  2. Borrar los elementos que han muerto o a terminado su ciclo de vida.

Poder borrar el elemento de lista me dificulta la implementación, asi que he optado por que el nodo tenga un método en el que solicita la liberación. Cuando llege su turno será eliminado. Esto tambien lo hago así por que physX exige borrar sus entidades en puntos muy concretos de muy código. Cuando no lo hacía así cada 5 min de juego tenía un “segmentation fault” que me crasheaba el juego.

Hay infinitos ejemplos por los que hay que borrar una entidad. Un bot que ha cumplido su objetivo.
Por ejemplo, suponer que una entidad (un proyectil en concreto) que se mueve, esto lo hace durante el refresco, se sale del mapa, cuando se salga queremos borrarlo. Por tanto en pseucódigo será.

if(estoyDentroDeLimites())
	avanzar();
else
	pedirLiberacion();

Cuando a otro nivel llamamos al proceso de las entidades, el proceso debería quedar algo así.

void procesarSeleccionados ( list<Nodo*> * lista )
{
	Nodo * aux = NULL;
	list::iterator it = lista->begin();
	while(it != lista->end())
	{
		aux = *it;
		if(aux->getPedirLiberacion() && aux->liberar())
		{
			delete aux;
			it = lista->erase(it);
		}
		else
		{
			aux->refrescar();
			i++;
		}
	}
}

Estoy utilizando una lista del STD.  Comentar:

  • El if() podríamos sustituirlo por la condición de borrado. En este ejemplo significa:
    • si quieres que te borren. getPedirLiberacion()
    • Y te has borrado correctamente. && aux->liberar()
  • La función erase() borra a lo que apunta el iterador y automaticamente te avanza el iterador, teniendo siempre un iterador válido. Por eso el i++ esta en el else, si lo pusioramos fuera nos saltariamos un elemento de la lista cada vez que borremos.

Compactar BDD sqlite de Firefox 3

Bueno por fin he acabado los examenes y tengo bastantes posts acumulados(en mi cabeza) y que iré publicando cuando tenga tiempo.

Lei en Barrapunto que compactando la BDD de sqlite de Firefox 3 teóricamente debería acelerar las consultas, inserciones, borrados y todas las operaciones que conlleva una base de datos. Si esto es cierto, deberíamos ejecutar este script de vez en cuando. Hablo de teóricamente por que no he hecho benchmarkings pero tener más que fe que esto acelera un cierto tipo de consultas, y si no al menos reducimos el espacio en disco. Creaamos con gedit compactarFirefox.sh y pasteamos:

#!/bin/sh

for f in ~/.mozilla/firefox/*/*.sqlite; do sqlite3 $f 'VACUUM;'; done

Realmente espero que en  futuras versiones de firefox, el mismo se automantenga cada cierto tiempo, ya que estas cosas a las que ya hace años nos mal acostumbro M*cro**ft con al access. Y pienso que el aumantenimiento de las base de datos incrustadas debería ser un proceso totalmente transparente al usuario.

Importante actualización script de subtitulos

Cuando debería estar estudiando para un examen de UML me da por programary he hecho importantes actualizaciones en el script de pegar subtitulos. Esta mejor explicado en su correspondiente post. Asi que me limito a pegaros el help que devuelve el script. (Antes no tenía ni parametros xD)

Uso: pegarSubtitulos [-f] [-v] [-r] [-h] [video1 video2 video3 ... videoN]
-forzar|-f Fuerza a sobreescribir el archivo de salida : _ripeado.avi
-verbose|-v Muestra mas informacion de salida
-recursive|-r|-recursivo Busca videos recursivamente
-help|-h|-ayuda Muestra esta ayuda
Importante:
- Todo parametro desconocido se considerara un video para ripear
- Si no se especifican videos, los videos se listaran de manera automatica

Me esta siendo muy útil mi propio script y posiblemente haga 2 importantes cambios mas:

  1. Implementar multiproceso, al igual que en el script de generar el diccionario, en este último ya lo tengo hecho pero no lo publico por que no entiendo por que no aumenta apenas el rendimiento en un dual core. Lo estoy haciendo con pyprocessing
  2. Hacer un interfaz gráfica como etapa final, con GTK + glade.

Comentarioz plz en el otro post