4 Trabes

Sincronizar con un ftp utilizando perl

Publicado por el Lunes, 28 de Mayo de 2007

Cuando necesitamos mantener dos sistemas de ficheros sincronizados hay varias opciones razonables. Podemos utilizar alguna utilidad tipo rsync, o multitud de aplicaciones de propósito específico. Incluso podemos utilizar un cvs o svn para conseguir este fin. Pero cuando el "servidor remoto" solo es accesible a través de ftp las opciones se reducen bastante.

Cuando es razonable suponer que el tamaño de los datos va a ser escaso, podemos optar por hacer backups periódicos de la totalidad del sistema de ficheros, y luego restaurarlos en el sistema a mantener sincronizado. Pero cuando el sistema de ficheros va a contener ficheros grandes, eso no es una gran idea.

El script perl que se muestra a continuación no es ni mucho menos una solución general de sincronización. Tampoco considera todos los casos posibles, ni hace sincronización recursiva, pero es una solución que funciona correctamente en el escenario para el que fué creada.

El funcionamiento es muy sencillo:

  • El script se conecta al servidor ftp indicado en las variables de configuración..
  • Para cada archivo del sistema remoto comprueba si existe en el sistema local. Si no existe lo descarga. Si existe y su fecha es anterior a la instancia del sistema remoto, también lo descarga.
  • Para cada archivo del sistema local comprueba si existe en el sistema remoto. Si no es así, lo elimina.

Partiendo de la premisa de que en el sistema local NUNCA se realizan cambios sobre los ficheros, al final del proceso tendremos en la carpeta local una réplica del contenido del sistema remoto, minimizando las transferencias de ficheros en la medida de lo posible.

A continuación se incluye el script en cuestión:

#!/usr/bin/perl -w
use strict;
use warnings;
use Net::FTP;

# Algunas variables
my $host = "dirección_host";
my $user = "usuario_ftp";
my $pass = "contraseña";
my $local_app_root = "ruta_local";
my $remote_app_root = "ruta_remota";

# Conectamos al servidor ftp
print "Conectando al servidor $host " ;
my $ftp = Net::FTP->new($host, Passive => 1, Debug => 0 ) or die "Imposible conectar al servidor FTP  en  $host";
$ftp->login( $user, $pass ) or die "..fallo en la autenticación $!";
print "[OK]\n";

# Sincronizamos las carpetas de ficheros
print "\n:::: Sincronizando Ficheros ::::\n";
repo_sync($ftp, $local_app_root, $remote_app_root);

# Desconectamos del ftp
print "\n\nDesconectando...";
$ftp->quit;
print "[OK]\n";


# Funcion para sincronizar FTP<-Local
sub repo_sync {
	my $ftp = shift;
	my $local_path = shift;
	my $remote_path = shift;
	my $rtime;


	# Obtenemos el listado de ficheros Remotos
	$ftp->cwd($remote_path);
	my @remote_files = $ftp->ls();

	# Bajamos todo lo nuevo
	for my $file (@remote_files) {

		if ( !( $rtime = $ftp->mdtm($file) ) ) {
			# Dado quer el archivo SIEMPRE existe, y mdtm solo es false cuando el archivo no existe o 
			# bien cuando es un directorio, en este casp estamos en un directorio. 
			# No hacemos nada en este caso
	    }
	    else
	   	{
			# Es un fichero, comenzamos a sincronizar
			print "\nSincronizando: $file\n";
			if ( !( my  $ltime = (stat("$local_path/$file") )[9] ) ) {
	    		# No existe el fichero en el repositorio local
	    		print "-> No existe en repositorio local";
	    		print ".Actualizando...";
				# Obtenemos el fichero por ftp
				$ftp->get ($file, "$local_path/$file");
				print "[OK]";

	    	}
	    	else
	    	{
	    		# Existe el fichero en el repositorio local
	    		print "-> Existe en repositorio local";
	    		if ($rtime > $ltime) {
			    	# La copia local no está al día
					print ". No está al día. Actualizando...";
			    	$ftp->get ($file, "$local_path/$file");
			    	print "[OK]";
			    }
			    else  {
					print". Está al día";
	    		}
	    	}

	    }

	}

	# Borramos lo que ya no está en el repositorio remoto, para ello necesitaremos iterar sobre los ficheros del sistema local
	my (@local_files, $f);
	opendir DIR, $local_path or
	      die "Imposible abrir $local_path: $!\n";
	while($f = readdir DIR) {
		if(-d "$local_path/$f"){
			# Esto son directorios. De nuevo no nos interesa tratarlos en nuestro script,
			# dejamos este comentario a modo de recordatorio para quien necesite 
			# hacer algo con ellos
		}
		else{
			# Guardamos los ficheros en un array
			push (@local_files, $f);
		}
	}
	# Iteramos sobre los ficheros
	for my $file (@local_files) {
		if ( !( $rtime = $ftp->mdtm($file) ) ) {
			# El archivo NO existe en el repositorio remoto, pues mdtm solo es false  cuando el fichero no existe o cuando es 
			# un directorio, caso imposible en esta rama.
			print "\nSincronizando: $file\n->NO existe en el repositorio. Eliminando..."  ;
			unlink "$local_path/$file";
			print "[OK]";
	    }

}
}

Espero que alguien pueda ahorrarse un rato de trabajo gracias a este post :D

746 usuarios en Galicia Global

Publicado por el Viernes, 18 de Mayo de 2007

O día xa 17 pasou, pero Galicia Global segue adiante. Xa somos 746 galegas e galegos globais espallados polo mundo, e a páxina quedará aí para que ese número creza. Moitas grazas a todos os usuarios rexistrados por participar neste proxecto!

El día 17 ha pasado, pero Galicia Global sigue adelante. Ya somos 746 gallegas y gallegos globales esparcidos por el mundo, y la página seguirá ahí para que ese número crezca. ¡Muchas gracias a todos los usuarios registrados por participar en este proyecto!

Soporte para índices fulltext en las migrations de Ruby on Rails

Publicado por el Viernes, 18 de Mayo de 2007

Como cabe esperar, las migrations de Ruby on Rails no tienen soporte directo para crear índices fulltext. Esto es bastante lógico, porque son una característica propia de mysql, no un estándar que sigan múltiples SGBD. Sin embargo, las migrations contemplan la posibilidad de ejecutar comandos directamente contra la base de datos. La sintaxis es muy sencilla:

execute "comando_a_enviar_a_la_base_de_datos"

Hay que tener en cuenta que en mysql solo es posible definir índices fulltext en tablas MyISAM.Utilizando la sintáxis que acabamos de ver, un ejemplo completo de como crear una tabla con un índice fulltext quedaría de la forma siguiente:

create_table("prueba", :force => true, : options=> "ENGINE=MyISAM") do |t|
  t.column("titulo", :string, :limit => 50)
  t.column("texto", :text)
end

execute "CREATE FULLTEXT INDEX FullText_texto_titulo ON prueba (titulo, texto)"
No es una solución portable, pero si es más elegante que tener un script separado para hacer este tipo de cosas.

Galicia Global no caduca el 17 de Mayo

Publicado por el Miércoles, 16 de Mayo de 2007

A pesar de lo aparecido en varios medios de comunicación escritos y electrónicos, Galicia Global no cerrará sus puertas el 17 de Mayo y seguirá siendo un punto de encuentro en la red para todos los gallegos (de nacimiento o corazón).

Cambios en Working with Rails

Publicado por el Martes, 15 de Mayo de 2007

Hace tiempo comentaba en un post la existencia de workingwithrails.com. Un sitio web donde los programadores Rails pueden “hacerse publicidad” y que el mundo entero conozca su existencia. Resulta que han hecho un serie de cambios en la página y ahora es posible dar de alta empresas y asociar perfiles personales a ellas (como ejemplo aqui tenéis la entrada de Trabe Soluciones en Working with Rails. Todavía no aparece Óscar, pero supongo que se apuntará en algún momento).

También tienen nuevos servicios que permiten publicar grupos de gente, proyectos y sitios web. En este último caso, al dar de alta un sitio os permiten realizar un alta en Happy Codr. Un showcase de proyectos y sitios web realizados con Rails y en el que Trabe Soluciones publica sus trabajos.

Material del taller "Primeros pasos con Ruby on Rails"

Publicado por el Miércoles, 09 de Mayo de 2007

Ya está disponible para descarga el material del taller de iniciación al desarrollo con Ruby on Rails que impartimos Asís y un servidor el 25 de Abril durante las VII Jornadas sobre Software Libre y del que os informamos en varios posts.

El material incluye las transparencias y la aplicación de ejemplo que utilizamos. Podeís descargarlo en la sección de charlas de la página web de Trabe Soluciones.

Galicia Globlal supera la barrera de los 500 usuarios

Publicado por el Miércoles, 09 de Mayo de 2007

Galicia Global está superando nuestras mejores espectativas de crecimiento y ya tiene más de 500 usuarios. Desde Trabe Soluciones agradecemos a todos los que os habeís apuntado vuestra participación. Hemos introducido alguna mejora en la página que esperemos que os guste.


Agora en galego

Galicia Global está a superar as nosas expectativas de crecemento e xa ten máis de 500 usuarios. Dende Trabe agradecemos a tódolos que vos apuntachedes a vosa participación. Fixemos algunhas melloras na páxina e esperamos que vos gusten. O polbo galego espállase polo mundo.

Galicia Global: usuario número 100

Publicado por el Viernes, 04 de Mayo de 2007

Hace un rato, cuando llegamos a la oficina después de comer me he conectado a galiciaglobal.com para ver cuantos nuevos gallegos se han convertido en "globales" en estas horas. Y como ha coincidido que el número era bastante redondo, se me ha ocurrido hacer una captura de pantalla y pegarla en este blog. Un saludo para todas las gallegas y gallegos globales!!!


Agora en galego

Cando viñemos de comer dóusenos por mirar canta xente había rexistrada na galiciaglobal.com. Parece que a iniciativa está a ser bastante ben aceptada pola comunidade de internautas galegos. Casualmente cando miramos había xustamente cen galegos globais rexistrados, e pareceunos bonito conmemorar tan especial cifra cun post neste blog. Un saúdo para todas as galegas e galegos globais!!!

Mmmmm mentres escribía este pot xurdiron 13 novos galegos globais...non non, xa somos 14 máis! Esperemos que o ritmo non se pare e cheguemos a ser unha grande comunidade global.

Favicon en aplicaciones Rails en desarrollo

Publicado por el Miércoles, 02 de Mayo de 2007

Cuando generamos una aplicación Rails, en la carpeta public se crea el fichero favicon.ico. Si lo cambiamos por nuestro propio icono podremos verlo una vez hayamos desplegado la aplicación en nuestro servidor. Lo normal es que lo hagamos utilizando un Apache o un lighty y estos se encargarán de enviarle automáticamente el icono al navegador. En desarrollo utilizando un webrick o un mongrel esto no es así y no debemos olvidarnos de que si queremos ver el icono debemos enlazarlo expresamente en el header de nuestras páginas HTML con algo como:

<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />

Algo muy sencillo y que no nos cuesta nada escribir para poder ver como quedan nuestros favicons.

Galicia Global

Publicado por el Miércoles, 02 de Mayo de 2007

El pasado 1 de mayo publicamos la web Galicia Global. Se trata de un sencillo sitio realizado a petición de capítulo gallego de la Internet Society (ISOC-Gal) para conmemorar el día de internet 2007 y que forma parte de la iniciativa Máis Internet, máis galego, máis futuro, promovida por la Dirección Xeral de Promoción Industrial e da Sociedade da Información da Xunta de Galicia.

El objetivo de Galicia Global es ofrecer a la comunidad gallega una sencilla web social donde todos los gallegos y gallegas puedan tener una pequeña ficha personal georeferenciada y puedan expresar sus opiniones en un blog comunal.

Galicia Global

La web utiliza extensivamente el API de Google Maps y ha sido desarrollada con Ruby on Rails, utilizando un par de plugins interesantes acts_as_authenticated y active_record_base_without_table. El primero consiste en un par de generadores para crear la infraestructura necesaria para tener un sistema de registro y login, con funcionalidades como remenber my password, activación de cuentas vía email, etc. El segundo permite definir modelos ActiveRecord sin necesidad de utilizar una tabla por detrás.

Nos encantaría que probaseis la web y que todos los que seais gallegos participéis. Los textos en pantalla están en gallego, esperamos que esto no eche para atrás a los hispanohablantes que no conozcan este idioma.