Implementar copias de seguridad automáticas con Dropbox

Prontus ofrece desde su versión 11.2.81 soporte para la API de Dropbox, para realizar respaldos automatizados de artículos y portadas.
Introducción

Desde la versión 11.2.81, Prontus permite implementar respaldos automatizados del contenido de un sitio Prontus usando la plataforma Dropbox. Dropbox es un sistema de almacenamiento de objetos en la nube de amplio uso y también de bajo costo (USD 10 por 1 TB). A la comodidad de un almacenamiento sin preocupaciones de hardware se le suma el hecho de que posee clientes para la mayoría de los SOs de escritorio, sincronizando automáticamente lo que se encuentra en la nube con el disco de uno o más PCs.

Todo esto lo hace sumamente atractivo como sistema de respaldo secundario, primero como copia de
seguridad del contenido de un sitio hecho en Prontus (como Prontus no depende de una base de datos, se
cumple con facilidad que todos los archivos necesarios pesarán menos de 150 MB, el límite de Dropbox
para archivos continuos), aunque posiblemente se deba tener en cuenta el peso de archivos multimedia, especialmente de video. Para resolver este detalle, Prontus permite especificar si debe evitarse respaldar ciertos tipos de archivos, y también agregar directorios al respaldo.

Desde la versión 11.2.94 se utiliza la versión 2 de la API de Dropbox

Creación de la Aplicación Dropbox

Para poder usar la funcionalidad de respaldo con Dropbox es necesario primero crear una cuenta de usuario y una aplicación en Dropbox. Para esto, debe registrarse en dropbox.com y luego crear una aplicación en la sección para desarrolladores de Dropbox. Allí debe seguir estos pasos:

  1. Seleccionar la opción "Dropbox API app"
  2. Elegir como tipo de datos "Files and datastores"
  3. Limitar la aplicación a su propio directorio, marcando "Yes" en esa opción.
  4. Proveer un nombre, y dar click en "Create App".

 

Imagen foto_00000002
Creación de la aplicación Dropbox


Una vez creada la aplicación, deberá generar un token. Para esto, en la pestaña "Settings", en la sección "OAuth 2" debe hacer click en el botón "Generate". Se creará un access token, un texto semejante a "6St_M2m2Cf4AAAAAAAAPx8vNXQaJB71hs8V87hF9zhWtH0zMnAdX88B-laX6pBC4". Copie este texto, y abra el panel de control de su Prontus.

 

Imagen foto_00000001
Obtención del Access Token OAuth 2
Configuración de Prontus

Una vez tenga el access token generado, debe ir a la pestaña "Administración" de su Prontus, sección "Variables Generales". Active allí el soporte para Dropbox, y guarde la configuración. Luego de guardar, aparecerá una nueva sección "Dropbox" en el menú lateral. Allí deberá pegar el token obtenido y luego guardar la configuración nuevamente.

 

Imagen foto_00000003
Configuración de Prontus

 

La actualización de los respaldos se gatilla al guardar artículos y portadas. Al guardar, se gatilla el respaldo de ese artículo o portada y de sus archivos asociados.

Para hacer la importación inicial del sitio a Dropbox se debe diseñar un script que copie todo el contenido. El código siguiente puede servir como ejemplo. Dado que usa librerías incluídas con Prontus, debería crearse dentro del directorio cgi-cpn/ para evitar problemas de inclusión de módulos:

#!/usr/bin/perl
#
# Algoritmo recursivo para respaldar un directorio Prontus en Dropbox.
#
use strict;
use lib_dropbox;
# Token de la aplicacion en Dropbox.
my $ATOKEN = ''; # CUSTOM
&prontus_dropbox::init($ATOKEN);
# ----- Para probar acceso solamente -----
#print &prontus_dropbox::getInfo() . "\n";
#my @entries = &prontus_dropbox::getDir('/');
#foreach my $entry (@entries) {
#    print "$entry\n";
#}
# ----- /Para probar acceso solamente -----
# Copia todo a Dropbox.
&recurseDirs('/[path_al_sitio_prontus]','/[path_al_directorio_destino]'); # CUSTOM
print "\n";
# ----------------------------------------------------------------------------- #
# Recorre los directorios recursivamente, subiendo a Dropbox los archivos que no
# existen o que tienen un peso distinto.
# @param string source el path completo al directorio a respaldar
# @param string destination el path relativo de destino en Dropbox.
#  Debe ser el nombre del directorio de Prontus, para mantener la misma estructura.

sub recurseDirs {
    my($source,$destination) = @_;
    my($entry,$dropBoxEntry,$path,$esdir,$size);
    my(@entries,@dropboxEntries);
    my %dropboxFileSizes;
    print "Inicio: $source -> $destination\n"; # debug
    opendir(DIR, $source) || die "Can't opendir " . $source . $!;
    @entries = readdir(DIR);
    closedir DIR;
    # Lee las entradas de dropbox en el destino. <path>\t<es dir>\t<tamano en bytes>
    @dropboxEntries = &prontus_dropbox::getDir($destination);
    # Obtiene los tamanos de archivo. Si es un directorio asigna el tamano -1.
    %dropboxFileSizes = ();
    print " Listado de $destination en dropbox:\n";
    foreach $dropBoxEntry (@dropboxEntries) {
         ($path,$esdir,$size) = split(/\t/,$dropBoxEntry);
         # Elimina los directorios superiores del path.
         if ($path =~ /\/([^\/]+)$/) {
             $path = $1;
         }else{
             $path = '/';
         };
         # Asigna el tamano.
         if ($esdir) {
             $dropboxFileSizes{$path} = -1;
         }else{
             $dropboxFileSizes{$path} = $size;
         };
         print " $path $size\n";
    };
    # Recorre los archivos y subdirectorios.
    foreach $entry (sort @entries) {
        # Si es un directorio, entonces aplica de nuevo la rutina en forma recursiva.
        # No copia los directorios que empiezan con un punto.
        if ((-d "$source/$entry") && ($entry !~ /^\./)) {
            &recurseDirs("$source/$entry","$destination/$entry");
        };
        if (-f "$source/$entry") {
            # Si no existe en dropbox o si los tamanos son distintos, lo sube.
            if ( $dropboxFileSizes{$entry} != -s "$source/$entry") {
                print " sube: $source/$entry $destination/$entry\n";
                print &prontus_dropbox::putFile("$source/$entry","$destination/$entry");
                print "\n";
            };
        };
   };
}; # recurseDirs