Probé con igal2 y otros programas similares, pero al final me decidí por
escribir un script propio que automáticamente renombre y genere archivos php
con el estilo del resto de páginas del PLUG.

El script de python que adjunto debe ejecutarse dentro de una carpeta (como
/fotos) y funciona de esta forma:

   1. Busca las sub-carpetas con el formato año_nummes (ej. 2009_06) y para
   cada una de ellas:
   1. Ordena las fotos según la fecha en sus datos EXIF y las renombra
      siguiendo la convención indicada por Antonio.
      2. Genera miniaturas de 150x120 e imágenes reducidas de 800x600 y las
      guarda en las carpetas *thumb* y *med*, respectivamente.
      3. Genera archivos *imgXXX.php* para cada foto mediana y un *index.php
      * con las miniaturas, usando el nombre de la carpeta para el título
      del álbum. (ej. 2009_06 -> 'Junio 2009').
      4. Coge la primera miniatura y hace una copia (en la carpeta *thumb*)
      con el nombre *caratula.jpg*.
      2. Finalmente, genera un *index.php* en la carpeta raíz de la galería
   (ej. /fotos/) con un índice de los álbumes disponibles, usando las carátulas
   y títulos (ej. Junio 2009) de cada uno..

El script funciona con cualquier versión de python  2.3 <= x < 3 pero
necesita que la biblioteca Python Image Library
(PIL)<http://www.pythonware.com/products/pil/>esté instalada.

El script se salta todas las carpetas de fotos que ya tengan una sub-carpeta
*thumb* así que puede ejecutarse varias veces para procesar solo los álbumes
nuevos.

Con las fotos de la reunion de este mes he armado un ejemplo del resultado
del script, que pueden ver aquí: http://demo2.lucumalabs.com/fotos/
(Ya sé que en mi ejemplo no se ven los acentos, pero en el servidor del PLUG
deberían funcionar bien).

Antonio, puedes bajarte la galería armada de aquí:
http://demo2.lucumalabs.com/fotos.tar.gz
La plantilla que estoy usando para generar las páginas tiene unas líneas de
CSS incrustadas... Quizas sería mejor moverlas a /css/plug.css

Saludos.

Juan Pablo



--
Juan Pablo Scaletti


2009/7/2 Antonio Ognio <[email protected]>

> Saludos,
>
> Tal como ofrecí ayer he subido las fotos de las que tengo copia en
> esta dirección:
>
> http://www.linux.org.pe/reuniones/fotos/originales/
>
> Como pueden ver, son las originales, es decir, entan pesadas porque
> son en el formato más grande.
>
> Me ayudarian bastante si alguno de Uds., especialmente alguien que
> asistió desde el inicio de la reunión, hace lo siguiente:
>
> a) Se baja todas las fotos
>
> b) Las ordena en órden cronológico: primero yo hice la intro, luego
> fue la charla de Internacionalización, luego la de Puppy Linux, luego
> de Michael con el Software Freedom Day, luego la de Nicolás, luego la
> de Juan José y finalmente el conversatorio que dirigión Cesar Villegas
> con la participación de varios de Uds, entre ellos especialmente
> Arnaldo Ramirez, Rafael Olaechea, Alfonso de la Guarda, entre otros.
>
> c) Las renombra siguiendo esta convención:
> plug-reunion-mensul-Jun-09-001.jpg
>
> d) Generamos thumbnails a dos tamaños: pequeña y mediana, además de la
> original
>
> e) Generamos una galería en HTML usando un software como igal, en
> especial igal2:
>
> http://trexler.at/igal/
>
> Ponen todo un un .tar y vemos la manera en que me lo pasen.
>
> Saludos y gracias de antemano. Si alguien quiere ayudar que responda a
> este correo avisando asi no se duplican mucho los esfuerzos.
>
> Antonio
> _______________________________________________
> Lista de correo Linux-plug
> Temática: Discusión general sobre Linux
> Peruvian Linux User Group (http://www.linux.org.pe)
>
> Participa suscribiéndote y escribiendo a:  [email protected]
> Para darte de alta, de baja  o hacer ajustes a tu suscripción visita:
> http://listas.linux.org.pe/mailman/listinfo/linux-plug
>
> IMPORTANTE: Reglas y recomendaciones
> http://www.linux.org.pe/listas/reglas.php
> http://www.linux.org.pe/listas/comportamiento.php
> http://www.linux.org.pe/listas/recomendaciones.php
>
#!/usr/env python
# -*- coding: utf-8 -*-

import os
import re
import shutil
import sys
import time

PATRON_NOMBRE_IMG = 'plug-reunion-mensual-%(mmm)s-%(yy)s-%(n)03i%(ext)s'

PLANTILLA = '''<?php
require("%(conf)s");
require($installdir."pluglib.inc");
plug_header("PLUG: %(titulo)s");
plug_inicio_lado_izquierdo();
plug_caja_webring();
plug_fin_lado_izquierdo();
plug_inicio_centro();
?>
<style type="text/css">
ul.galeria_cabecera {
  list-style-type: none;
  text-align: center;
  padding: 0;
}
ul.galeria_cabecera li {
  display: inline;
  padding: 0 10px;
}
ol.galeria_miniaturas {
  overflow: hidden;
  padding-bottom: 30px;
  list-style-type: none;
}
ol.galeria_miniaturas li {
  display: block;
  float: left;
  padding: 5px;
  width: 150px;
  min-height: 150px;
  text-align: center;
}
ol.galeria_miniaturas li .leyenda{
  display: block;
  padding: 4px 0;
}
.galeria_foto {
  text-align: center;
  padding-bottom: 30px;
}
</style>

<h2 class="titulo_caja_01">%(titulo)s</h2>
%(contenido)s
<?php
plug_fin_centro();
plug_footer();
?>'''

TITULO = 'Reunión %s'

HTML_MINIS = '''
<ul class="galeria_cabecera">
<li><a href="../">Ver todos los álbumes</a></li>
</ul>
<ol class="galeria_miniaturas">
%s
</ol>
'''

HTML_MINI_LI = '<li><a href="img%(n)03i.php">' \
    + '<img src="thumb/%(src)s" alt="%(src)s" /></a></li>'

HTML_MED = '''
<ul class="galeria_cabecera">
<li><a href="index.php">Ver album</a></li>
%(anterior)s
%(siguiente)s
</ul>
<p class="galeria_foto"><a href="%(src)s" title="Ver en tamaño completo">
<img src="med/%(src)s" /></a></p>
'''

HTML_INDICE = '<ol class="galeria_miniaturas">%s</ol>'

HTML_INDICE_LI = '<li><a href="%(carpeta)s/">' \
    + '<img src="%(carpeta)s/thumb/caratula.jpg" alt="" /></a>' \
    + '<span class="leyenda">%(leyenda)s</span></li>'

EXT_IMAGENES = ('.jpg', '.png', '.gif')

TAM_MED = (800, 600)
TAM_MINI = (150, 120)

MESES = 'Enero Febrero Marzo Abril Mayo Junio Julio Agosto Setiembre Octubre Noviembre Diciembre'.split(' ') 

EXIF_ETIQUETA_FECHA = 0x9003


def procesar_carpeta(ruta, carpeta):
    print '\n', carpeta
    # ¿Ya fue procesada antes?
    if os.path.isdir(os.path.join(ruta, carpeta, 'thumb')):
        print '   Ya estaba pre-procesada'
        return
    archivos = os.listdir(os.path.join(ruta, carpeta))
    imagenes = [im for im in archivos if im[-4:].lower() in EXT_IMAGENES]
    if not imagenes:
        print '   No se encontraron imágenes'
        return
    imagenes = ordenar_imagenes(ruta, carpeta, imagenes)
    imagenes = renombrar_imagenes(ruta, carpeta, imagenes)
    
    procesar_imagenes(ruta, carpeta, imagenes)
    hacer_pagina_miniaturas(ruta, carpeta, imagenes)
    hacer_paginas_fotos(ruta, carpeta, imagenes)


def fecha_carpeta(carpeta):
    year, mes = carpeta.split('_')
    mes = MESES[int(mes) - 1]
    return year, mes


def ordenar_imagenes(ruta, carpeta, imagenes):
    print '   Ordenando imágenes'
    # Obtengo primero la fecha EXIF de las imagenes
    # en vez de extraerla en cada comparación
    d_exif = {}
    for src in imagenes:
        fsrc = os.path.join(ruta, carpeta, src)
        d_exif[src] = obt_fecha_exif(fsrc)
    
    def cmp_por_fecha_exif(src_x, src_y):
        x = d_exif[src_x]
        y = d_exif[src_y]
        if x > y:
            return 1
        elif x == y:
            return 0
        else: # x < y
            return -1
    
    imagenes.sort(cmp_por_fecha_exif)
    return imagenes


def renombrar_imagenes(ruta, carpeta, imagenes):
    print '   Renombrando imágenes'
    year, mes = fecha_carpeta(carpeta)
    yy = year[-2:]
    mmm = mes[:3].lower()
    # Primero renombramos a nombres aleatorios para evitar conflictos posteriores.
    for n, src in enumerate(imagenes):
        ruta_im = os.path.join(ruta, carpeta, src)
        nombre_temp = obt_nombre_temp(src)
        ruta_temp = os.path.join(ruta, carpeta, nombre_temp)
        os.rename(ruta_im, ruta_temp)
        imagenes[n] = nombre_temp
    
    # Finalmente renombramos siguiendo el patrón.
    for n, src in enumerate(imagenes):
        ext = os.path.splitext(src)[1].lower()
        nombre_nuevo = PATRON_NOMBRE_IMG % locals()
        ruta_im = os.path.join(ruta, carpeta, src)
        ruta_nueva = os.path.join(ruta, carpeta, nombre_nuevo)
        os.rename(ruta_im, ruta_nueva)
        imagenes[n] = nombre_nuevo
    return imagenes


def procesar_imagenes(ruta, carpeta, imagenes):
    ruta_meds = os.path.join(ruta, carpeta, 'med')
    ruta_minis = os.path.join(ruta, carpeta, 'thumb')
    try:
        os.mkdir(ruta_meds)
    except OSError:
        pass
    try:
        os.mkdir(ruta_minis)
    except OSError:
        pass
    for src in imagenes:
        print '   Procesando', src
        ruta_im = os.path.join(ruta, carpeta, src)
        im = Image.open(ruta_im)
        ext = im.format.upper()
        im_med = _hacer_miniatura(im, TAM_MED)
        im_mini = _hacer_miniatura(im, TAM_MINI)
        ruta_im_med = os.path.join(ruta_meds, src)
        ruta_im_mini = os.path.join(ruta_minis, src)
        _guardar_imagen(im_med, ext, ruta_im_med)
        _guardar_imagen(im_mini, ext, ruta_im_mini)
    
    # Hacer carátula
    src = imagenes[0]
    ruta_im = os.path.join(ruta_minis, src)
    ruta_caratula = os.path.join(ruta_minis, 'caratula.jpg')
    shutil.copyfile(ruta_im, ruta_caratula)


def _hacer_miniatura(im, tam):
    im_ancho, im_alto = im.size
    ancho, alto = tam
    # No hacer una miniatura si la imagen es muy pequeña
    if im_ancho <= ancho and im_alto <= alto:
        return im
    # La miniatura modifica la imagen original. No queremos eso
    mim = im.copy()
    mim.thumbnail(tam, Image.ANTIALIAS)
    return mim


def _guardar_imagen(im, ext, ruta):
    if im.mode != 'RGBA' and ext != 'GIF':
        im = im.convert('RGBA')
    im.save(ruta, ext, quality=88)


def titulo_album(carpeta):
    year, mes = fecha_carpeta(carpeta)
    return '%s %s' % (mes, year)


def hacer_pagina_miniaturas(ruta, carpeta, imagenes):
    html = [HTML_MINI_LI % {'n': n, 'src': src} for n, src in enumerate(imagenes)]
    html = '\n'.join(html)
    html = HTML_MINIS % (html, )
    ruta_archivo = os.path.join(ruta, carpeta, 'index.php')
    titulo = TITULO % (titulo_album(carpeta), )
    _guardar_pagina(ruta_archivo, titulo, html)


def hacer_paginas_fotos(ruta, carpeta, imagenes):
    max = len(imagenes) - 1
    for n, src in enumerate(imagenes):
        anterior = ''
        siguiente = ''
        if n > 0:
            anterior = '<li><a href="img%03i.php">&laquo; Anterior</a></li>' % (n-1, )
        if n < max:
            siguiente = '<li><a href="img%03i.php">Siguiente &raquo;</a></li>' % (n+1, )
        
        html = HTML_MED % locals()
        nombre = 'img%03i.php' % (n, )
        ruta_archivo = os.path.join(ruta, carpeta, nombre)
        titulo = TITULO % (titulo_album(carpeta), )
        _guardar_pagina(ruta_archivo, titulo, html)


def hacer_pagina_indice(ruta_gal, carpetas):
    html = [
        HTML_INDICE_LI % {'carpeta': carpeta, 'leyenda': titulo_album(carpeta)}
        for carpeta in carpetas
        ]
    html = '\n'.join(html)
    html = HTML_INDICE % (html, )
    ruta_archivo = os.path.join(ruta_gal, 'index.php')
    titulo = 'Fotos reuniones mensuales'
    _guardar_pagina(ruta_archivo, titulo, html, conf='../plugconf.inc')


def _guardar_pagina(ruta_archivo, titulo, contenido, conf='../../plugconf.inc'):
    pagina = PLANTILLA % locals()
    archivo = open(ruta_archivo, 'w')
    try:
        archivo.write(pagina)
    finally:
        archivo.close()


def obt_nombre_temp(nombre_nuevo):
    return str(int(time.time())) + nombre_nuevo


def obt_fecha_exif(src):
    im = Image.open(src)
    if hasattr(im, '_getexif'):
        try:
            exifdata = im._getexif()
            ctime = exifdata[ EXIF_ETIQUETA_FECHA ]
            return time.strptime(ctime, '%Y:%m:%d %H:%M:%S')
        except:
            print '\tNo tiene fecha EXIF o es ilegible:\n\t', src
    return None


if __name__ == "__main__":
    try:
        import Image
    except ImportError:
        print "Este programa necesita de PIL (Python Image Library) para funcionar."
        print "Puedes descargarlo de: http://www.pythonware.com/products/pil/";
        sys.exit(1)
    
    ruta_gal = os.path.realpath(os.curdir)
    archivos = os.listdir(ruta_gal)
    rxfotos = re.compile(r'^\d{4}_(0?[1-9]|1[0-2])$')
    carpetas = [c for c in archivos if os.path.isdir(c) and rxfotos.match(c)]
    if not carpetas:
        print 'No se encontró ninguna carpeta con el formato AÑO_NUMMES.'
        sys.exit(1)
    
    carpetas.sort()
    for c in carpetas:
        procesar_carpeta(ruta_gal, c)
    hacer_pagina_indice(ruta_gal, carpetas)


_______________________________________________
Lista de correo Linux-plug
Temática: Discusión general sobre Linux
Peruvian Linux User Group (http://www.linux.org.pe)

Participa suscribiéndote y escribiendo a:  [email protected]
Para darte de alta, de baja  o hacer ajustes a tu suscripción visita:
http://listas.linux.org.pe/mailman/listinfo/linux-plug

IMPORTANTE: Reglas y recomendaciones
http://www.linux.org.pe/listas/reglas.php
http://www.linux.org.pe/listas/comportamiento.php
http://www.linux.org.pe/listas/recomendaciones.php

Responder a