Proyecto Longinus

2may/120

Script para eliminar directorios vacios

A veces es interesante eliminar los directorios vacios de una ruta. Aunque hay formas de hacer esta tarea rápidamente con un par de comandos. He decidido hacer un script, que permite realizar esta tarea de eliminación o solo contar cuantos directorios vacios tenemos. O incluso preguntarnos antes de eliminar cada directorio, por si queremos dejar alguno sin eliminar (un directorio de plantillas por ejemplo).

El script es muy mejorable, y por ahora solo funciona en el directorio actual. Pero como ejercicio de refresco de bash scripting, me ha servido de algo.

A continuación, el código


#!/bin/bash
# Autor: Borja Rubio
# Descripcion: Script para búsqueda y eliminación de directorios vacios en el directorio actual.

function uso {
 echo "Busca los directorios vacios del directorio actual y se eliminan si así se indica."
 echo "Uso: $0 [OPCION]"
 echo -e "\t-c Muestra un conteo de directiors vacios/eliminados"
 echo -e "\t-r Elimina los directorios vacios"
 echo -e "\t-i Modo interactivo (Debe usarse junto a -r"
 echo -e "\t-h incluye los directorios ocultos"
 echo "Ejemplos:"
 echo "$0 -c -- Solo muestra el conteo de directorios vacios"
 echo "$0 -chr -- Elimina los directorios vacios, incluyendo los ocultos y muestra un resumen"
 echo "$0 -cri -- Pregunta antes de eliminar un directorio vacio"
}
if [ $# -eq 0 ] ; then
uso
exit
fi
while getopts 'hcir' OPCION
do
 case $OPCION in
 h) OCULTOS=-A
 ;;
 c) CONTEO=true
 ;;
 r) BORRAR=true
 ;;
 i) INTERACTIVE=true
 esac
done

directories=`ls $OCULTOS`
contador=0;
eliminados=0;
for j in $directories
do
 if [ -d $j ] ; then
 lines=`ls $OCULTOS $j | wc -w`
 if [ $lines -eq 0 ] ; then
 if [ $CONTEO ] ; then
 let contador=$contador+1
 fi
 if [ $BORRAR ] && [ $INTERACTIVE ] ; then
 echo "Eliminar $j ? (y/N) "
 read value
 if [ $value == "y" ] ; then
 `rmdir $j`
 let eliminados=$eliminados+1
 fi
 elif [ $BORRAR ] ; then
 `rmdir $j`
 let eliminados=$eliminados+1
 fi
 fi
 fi
done
if [ $CONTEO ] ; then
echo "$contador directorios vacios ; $eliminados directorios eliminados"
fi
19ene/120

[Hardware] La tecnología S.M.A.R.T

Hace cosa de dos meses, me comenzó a fallar un disco duro, con la mala suerte, de ser el que tiene instalado el sistema. Los errores eran los típicos: altos tiempos de carga, reinicios extraños, algún que otro fichero corrupto. Así que me puse manos a la obra y le pasé varios escaneres de superficie, que me decian que estaba todo correcto. ¿Extraño no? El caso, que utilizando una live de recuperación, llamada Parted Magic tiene en su escritorio, uno de los programas que viene, es para examinar los discos duros. Y aquí es donde entra la tecnología SMART, que muchos hemos visto, pero al no dedicarme especialmente a esto del hardware, nunca le he prestado mucha atención en que consiste.

La wikipedia nos  dice:  "La tecnología S.M.A.R.T. acrónimo de Self Monitoring Analysis and Reporting Technology consiste en la capacidad de detección de fallos del disco duro. La detección con anticipación de los fallos en la superficie permite al usuario el poder realizar una copia de su contenido, o reemplazar el disco, antes de que se produzca una pérdida de datos irrecuperable." Interesante ¿no? Con todos los parametros de diagnostico que nos da esta tecnología, nos podemos hacer una idea de que puede fallar en nuestro disco duro. Entre estos parametros, se encuentran algunos como la temperatura, flujo de aire, tiempo de vida del disco duro, etc. En la captura que os dejo, pertenece a un pantallazo de mi disco duro.

Parametros de SMART

Parametros de SMART

Podeis ver todos los parametros, y como nos indica uno en rojo. El parametro "End to End Error" indica que está fallando la caché del disco duro. Es un fallo muy crítico por lo que hay que salvar los datos y cambiar el disco duro cuanto antes. Como vemos, gracias a SMART, nos evitamos la sorpresa  de que el disco duro deje de fallar de un día para otro y perdamos todos esos valiosos datos.

De momento, mi disco duro aguanta, pero ya tengo pedido uno de marca Hitachi, que según me han recomendado, son mucho más fiables. También se puede ver que no llega a las 10k horas de vida. Así que es raro que tenga un fallo de este tipo, por suerte, Seagate parece que permite devolver los discos duros en garantia. Ya comentaré como funciona el proceso cuando lo intente.

10ene/120

Empezar con GitHub

Para nosotros los programadores, hay una cosa que puede resultar algo complejo: Crearse un portfolio. Para los artistas y diseñadores, es suficiente con crearse una página simple y unas cuantas capturas de sus trabajos. Pero para un programador, es más complejo, si has hecho una aplicación web accesible al público, puedes poner el enlace. Pero, ¿Y si solo has creado un módulo de una aplicación? ¿ Y sí has colaborado en un proyecto con una pequeña parte? ¿Y si quieres enseñar una aplicación de la universidad?. Incluso a veces, a  un posible contratador, le puede interesar más ver la calidad de nuestro código. Para este tipo de casos, tenemos una opción, que además nos permite recibir feedback de otros usuarios. Para que nos entendamos, una red social de desarrolladores.

Estoy hablando de Github, que aparte de todo esto, nos proporciona un control de versiones, que debería de ser algo obligado para todos nuestros proyectos.
A pesar de sus bondades, tiene una cosa muy buena y una cosa muy mala. La cosa muy buena esque te puedes crear una cuenta gratis, la mala cosa, esque los proyectos que subamos han de ser públicos, salvo que nos hagamos una cuenta de pago. En este último caso, el número de proyectos privados dependerá de la cantidad que paguemos. Aún así, sigue siendo una opción bastante interesante, sobre todo si tenemos algún proyecto interesante en mente, ya que nos abrimos a colaborar con más desarrolladores y eso siempre es bueno.

Os dejo una lista con los enlaces para configurar git de forma sencilla :

12oct/110

Recuperar contraseña root de mysql

Después de mucho tiempo sin trabajar con mi servidor local de prueba, habia olvidado la contraseña del usuario root de la base de datos. Así que una googleada rápida he llegado a la siguiente solución:

Usted puede recuperar la contraseña del servidor de base de datos MySQL con los siguientes pasos:

Paso 1: Detener cualquier proceso del servidor MySQL.
Paso 2: Iniciar el proceso del servidor MySQL (mysqld) con la opción –skip-grant-tables por lo cual este no preguntará por la contraseña.
Paso 3: Conectar al servidor MySQL como el usuario root
Paso 4: Configurar una nueva contraseña para la nueva contraseña root
Paso 5: Salir y reiniciar el servidor MySQL

A continuación están los comandos necesarios para cada uno de los pasos mencionados anteriormente (iniciar sesión como el usuario root):

Paso # 1: Detener el servicio mysql

# /etc/init.d/mysql stop

Salida:

Stopping MySQL database server: mysqld.

Paso # 2: Iniciar el servidor MySQL sin contraseña:

# mysqld_safe --skip-grant-tables

Salida:

[1] 5988

Iniciando el motor de mysqld de las bases de datos desde /var/lib/mysql

mysqld_safe[6025]: started

Paso # 3: Conectar al servidor mysql usando el cliente mysql:

# mysql -u root

Salida:

Bienvenido al monitor de MySQL.  Comandos y con ; o \g.

Your MySQL connection id is 1 to server version: 5.0.21-log

Tipiar ‘help;’ o ‘\h’ para obtener ayuda. Tipiar ‘\c’ para en vaciar el buffer.

mysql>

Paso # 4: Configurar una nueva contraseña del servidor MySQL para el usuario root:

mysql> use mysql;
mysql> update user set password=PASSWORD("NEW-ROOT-PASSWORD") where User='root';
mysql> flush privileges;
mysql> quit

Paso # 5: Detener el servidor MySQL:

# /etc/init.d/mysql stop

Salida:

Stopping MySQL database server: mysqld

STOPPING server from pid file /var/run/mysqld/mysqld.pid

mysqld_safe[6121]: ended

[1]+  Done                    mysqld_safe –skip-grant-tables

Paso # 6: Iniciar el servidor MySQL y verificar la contraseña:

# /etc/init.d/mysql start
# mysql -u root -p

Fuente: http://www.codigomaestro.com/mysql/recuperar-contrasena-root-de-mysql/

19sep/110

¿Quién es 192.168.1.69? o Cómo buscarse la vida para acostarse tarde otra vez

Supongo que es normal que pase. Una semana sin ir a trabajar y cuando llega el domingo justo antes de entrar, ¿me voy a dormir temprano? Pues no, me busco cualquier excusa para acabar acostandome tarde. En este caso, jugueteando con unas herramientas de escaneo de puertos, sniffers y esas cosas, descubro que mi pc principal, no para de hacer peticiones ARP, preguntando por 192.168.1.69. ¿Qué es lo primero que pasa por mi cabeza? :O:O Seguro que tengo algún bicho malvado!, Pero nadie responde a la petición ARP, no responde a ping  y no me detecta ningún puerto abierto al escanear con nmap. Hasta ahí bien, pero cuando hago un scaneo de puertos desde una máquina virtual, me detecta puertos abiertos. ¿Que cosa más rara no? ¿Será cosa del VMWare y la configuración NAT? Porque en modo bridge no detecta ningún puerto abierto. Total, formas de perder el tiempo. Al final una búsqueda en el registro, encuentro que es por una impresora en red que tengo instalada, pero el pc a través de la que accede no está en la casa. ¡Normal que nadie responda! Eliminada la impresora, solucionado el problema. El modo Pingüino paranoico me ha hecho perder un montón de tiempo, porque al final, como siempre, la solución más simple es la acertada.
Pero bueno, para la próxima lo tendré en cuenta, hora de irse a dormir.

27jun/111

Otra vez por aqui y con novedades

Después de un largo tiempo de inactividad, vuelvo a postear. Cambio de trabajo, estudios y directamente, falta de ganas por actualizar. Pero vuelta a la carga, como novedades, he subido mi primera aplicación para iOS al apple store, ya pondré más información en cuanto haya pasado el proceso de aprobación de apple. Por otro lado, he creado un twitter de la página @projectlonginus. Quizás haya alguna novedad más próximamente.

Y como consejo del día, me encontré con el siguiente problema a la hora de crear el distribution de la aplicación de iOS. La solución es bastante sencilla, si sois como yo y no habeis podido esperar y estais trabajando con la beta del ios5 y el xcode con la beta, este no permite firmar aplicaciones para distribución, así que habrá que desinstalar completamente el xcode e instalar la ultima versión no beta. Para desinstalar el xcode es suficiente con la siguiente línea de comando:

<pre>sudo /Developer/Library/uninstall-devtools --mode=all
28feb/110

El problema del Trimino

Después del parón de los exámenes volvemos a la carga. En este caso, voy a publicar la práctica de una asignatura de la carrera. El enunciado de la práctica consiste en resolver el problema del Trimino, que se trata de un tablero de X*X tamaño, siendo X una potencia de 2, y teniendo una casilla marcada. Entonces debemos recubrir el tablero utilizando triminos (un angulo de tres casillas). Una descripción más detallada del problema con su solución teórica la podemos encontrar en el siguiente enlace : http://www.dma.fi.upm.es/docencia/primerciclo/matrecreativa/juegos/poliominos/triminos/triminos.htm

Para la solución del problema se puede utilizar uno de los esquemas algorítmicos básicos, en este caso el esquema de Divide y Venceras. Que comentado por encima, consiste en coger un problema y dividirlo en partes iguales y más sencillas, hasta llegar a una solución trivial. Una vez llegada a esta solución, se va juntando las soluciones parciales para llegar a una solución completa.
La adaptación de mi esquema para este problema es el siguiente:


public static void divide(Rectangulo r){
boolean b=buscarLleno(r);
if(b) // comprobacion de si es el caso trivial
return;
// Division en subproblemas
ArrayList<Rectangulo> rects = r.dividirEnCuatro();
for(Rectangulo r1  : rects){
divide(r1); // Llamada recursiva para resolver el subproblema
}
 }

Gracias a la mayoría de las funciones auxiliares, el algoritmo  resultante es muy reducido. Pinchando aquí os podeis descargar la práctica resuelta.

10ene/111

[Android] App Inventory

Esta mañana, hablando con un viejo amigo me ha comentado algo sobre App Inventor for Android. Resulta que es una interfaz web para crear pequeñas aplicaciones para Android utilizando Drag&Drop. Cuando me lo ha comentado me he quedado bastante sorprendido, ya que es una gran iniciativa por parte de Google el acercar el acceso de desarrollo simple a más gente. Tras estar un rato toqueteandolo, os puedo decir qué me ha gustado y que no.
Vamos a empezar por lo bueno,

  1. Crear aplicaciones simples es bastante sencillo, como ya he dicho,  Drag & Drop
  2. Viene con soporte para incluir multimedia, acceso a base de datos, lanzar otras activitys, etc.
  3. Simplifca la creación de interfaces gráficas comparado con el desarrollo en eclipse.
  4. No es necesario saber ningún lenguaje de programación para crear la lógica de aplicación. Basta saber un poco de flujo, variables, etc.
  5. Puedes probarlo en tiempo real en un terminal, cada vez que guardas, se actualiza la aplicación en el terminal.

Como se puede ver, son bastantes las ventajas que tiene este sistema, pero le he encontrado las pegas siguientes:

  1. La creación de la interfaz gráfica sigue siendo demasiado simple,(despues de haber probado la de Apple, todas me lo parecen).
  2. De momento no he visto nada para poder recoger datos de un source externo a través de web (un xml, json,etc)
  3. Una vez terminada, solo puedes descargarte un APK
  4. No genera ningun tipo de fuentes con el que puedas añadir más funcionalidades.
  5. Por lo visto, aún hay problemas para subir al market.

Son pegas, que para mi son muy importantes, aunque de momento es solo una Beta, y no se sabe como nos sorprenderan estos chicos de Google de aquí a un año si siguen apostando por este camino para sus terminales.

7ene/110

[Android] Problemas con ListView dentro de un ScrollView

Preparando una vista de detalles de una aplicación de Android, me he encontradoo con un curioso funcionamiento. La idea de la vista es tener un LinearLayout e ir metiendole en tiempo de ejecución pequeñas vistas que constan de un LinearLayout con un TextView para el titulo y un ListView con unos pasos. Puesto que la vista puede quedar más grande que la pantalla, todo encerrado dentro de un ScrollView. Pero por lo visto hay un pequeño bug, que cuando se encierran un ListView dentro de un ScrollView, en vez de hacer Scroll a toda el conjunto, "obliga" a los ListView a hacer scroll haciendo que su alto sea más pequeño.
Buscando por la red sobre este problema, en todos los foros y listas de desarrollares dicen que es un problema de Google que aún no han solucionado y la mejor "solución" es no poner un ListView dentro de un ScrollView. Aunque por suerte, dí con la siguiente solución , que llamando esta función:

<pre>  public static void setListViewHeightBasedOnChildren(ListView listView) {
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null) {
            // pre-condition
            return;
        }

        int totalHeight = 0;
        for (int i = 0; i < listAdapter.getCount(); i++) {
            View listItem = listAdapter.getView(i, null, listView);
            listItem.measure(0, 0);
            totalHeight += listItem.getMeasuredHeight();
        }

        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        listView.setLayoutParams(params);
    }
</pre>

Y lo que hace es poner el tamaño del listview justo para que se muestren todos los hijos. Aunque tiene el problema que si tiene muchos hijos con bastante contenido que renderizar, puede tardar bastante.
Aún así, para ir saliendo del paso, va bastante bien.

3ene/110

¡Feliz año nuevo!

Feliz año nuevo

Feliz año nuevo

He estado el fin de semana desconectado, pero Feliz año nuevo! Y que os traigan muchas cosas los reyes.