domingo, 25 de octubre de 2015

owncloud II (añadir repositorio)

Tanto si ya se ha instalado antes (http://rasphome.blogspot.com.es/2014/05/owncloud.html) como si se parte de cero.

En el caso de que haya una instalación previa, hay que eliminar/cambiar un fichero. Pero una vez finalizada la instalación (por eso lo voy a poner al final).

Paso 1 (desde el terminal se añade la firma del servidor):
  • wget -nv https://download.owncloud.org/download/repositories/8.2/Debian_7.0/Release.key -O Release.key
  • sudo apt-key add - < Release.key
Una vez realizado se puede eliminar el fichero "Release.key"

Paso 2 (añadir el servidor al fichero sources.list):
  •  sudo sh -c "echo 'deb http://download.owncloud.org/download/repositories/8.2/Debian_7.0/ /' >> /etc/apt/sources.list.d/owncloud.list"
Paso 3 (actualizar el listado de repositorios):
  • sudo apt-get update
Paso 4 (instalar owncloud):
  • sudo apt-get install owncloud

PARA EL CASO DE QUE YA ESTÉ INSTALADO:
Aunque ya esté instalado hay que hacer este paso de instalar. Si se le hace un sudo apt-get upgrade hace la actualización pero reteniendo el owncloud. Y permanece bloqueado hasta que se instala.
A pesar de que se deja instalar, sale un error:
  • Se encontraron errores al procesar:
     owncloud-config-apache
    E: Sub-process /usr/bin/dpkg returned an error code (1)
Este error sigue saliendo en suscesivos updates, autorremoves...
Error del autorremove:
  • Configurando owncloud-config-apache (8.2.0-2.1) ...
    ln: fallo al crear el enlace simbólico «/etc/apache2/conf.d/owncloud.conf»: El fichero ya existe
    dpkg: error al procesar owncloud-config-apache (--configure):
     el subproceso instalado el script post-installation devolvió el código de salida de error 1
    Se encontraron errores al procesar:
     owncloud-config-apache
    E: Sub-process /usr/bin/dpkg returned an error code (1)
La solución es sencilla:
  • sudo mv /etc/apache2/conf.d/owncloud.conf /etc/apache2/conf.d/owncloud.conf.old
  • sudo apt-get upgrade

Con eso ya funciona. Por lo que veo ha cambiado un poco el fichero de configuración.
  • Viejo: cat /etc/apache2/conf.d/owncloud.conf.old
    Alias /owncloud /usr/share/owncloud

    <Directory /usr/share/owncloud/>
        Options +FollowSymLinks
        AllowOverride All
        order allow,deny
        allow from all
    </Directory>
     
  • Nuevo: cat /etc/apache2/conf.d/owncloud.conf
 Alias /owncloud "/var/www/owncloud/"

<Directory "/var/www/owncloud">
    Options +FollowSymLinks
    AllowOverride All

    <IfModule mod_dav.c>
      Dav off
    </IfModule>

    SetEnv HOME /var/www/owncloud
    SetEnv HTTP_HOME /var/www/owncloud


</Directory>

<Directory "/var/www/owncloud/data/">
  # just in case if .htaccess gets disabled
  Require all denied
</Directory>

## Please enable this manually, if needed. See also
## https://doc.owncloud.org/server/8.2/admin_manual/issues/index.html#apple-ios
# Redirect 301 /.well-known/carddav /owncloud/remote.php/carddav
# Redirect 301 /.well-known/caldav  /owncloud/remote.php/caldav


Puede que lleve algún error asociado, pero de momento no ha aparecido
Lo que ha ocurrido es que ha cambiado el formato y he tenido que apañarlo.
He copiado los ficheros de la nueva estructura y en ella he metido los ficheros antiguos. Es un poco engorroso pero no es complicado. Lo que se complica es cambiar los permisos del enlace a la carpeta data.

Una vez terminado el proceso de arreglar la estructura, he creado un enlace simbólico a los datos del disco duro:
  • /var/www/owncloud $ sudo mv data data.bkup
    pi@raspberrypi /var/www/owncloud $ sudo ln /automount/owncloud/data/ ./data
    ln: «/automount/owncloud/data/»: no se permiten enlaces fuertes para directorios
    pi@raspberrypi /var/www/owncloud $ sudo ln -s /automount/owncloud/data/ ./data
El problema ahora es que /var/www/owncloud/data/ pertenece a root:root y hay que pasarlo a www-data:www-data y para eso hay que utilizar el modificador -h en chown:
  • /var/www/owncloud# chown -h www-data:www-data data
Parecía que se había resuelto, pero en realidad solo se ha resuelto el problema del almacenamiento. La nueva base de datos no lee la estructura de directorios y hay que cargar todo de nuevo. Tiene la facilidad de que está en el mismo disco y se acelera el proceso, pero hay que hacerlo a mano.

FIN

miércoles, 22 de julio de 2015

Control remoto para mpg123

Estaba buscando algo para controlar mpg123 abriendo una sesión ssh desde cualquier dispositivo a partir de su PID, pero no he visto nada. Lo único que he encontrado y parece interesante es: http://www.mpg123.de/mpg123/mpg123/README.remote

Resumen:

  • You can call mpg123 via the inetd and then do the control via telnet.
    • In /etc/services you must add something like
      •   mpg123      22123/tcp

  • In /etc/inetd.conf you add something like
    • mpg123  stream  tcp     nowait  root    /usr/bin/mpg123        mpg123 -R
La complicación (aunque pequeña) está en que raspbian no instala el demonio inetd y por lo tanto no existe el fichero /etc/inetd.conf
Para instalarlo:
  • sudo apt-get install inetutils-inetd

La otra pega es que telnet no destaca por su seguridad, pero en el ámbito casero eso no debería suponer un problema. Aunque, se podría cambiar root por nobody como indican en la página "mpg123  stream  tcp     nowait  nobody    /usr/bin/mpg123        mpg123 -R", a pesar de todo no voy a abrir puertos en el router con algo tan inseguro.

lunes, 20 de julio de 2015

Reproducir archivos mp3

La salida de sonido de raspberry está integrada en la salida hdmi. Por lo tanto es más sencillo y barato instalar una tarjeta de sonido USB que extaerlo de la salida HDMI.

Lo primero es instalar una tarjeta de sonido externa (USB) y configurar un par de cosillas:

  • Comprobar el dispositivo:
    • lusb
  • Editar /etc/modprobe.d/alsa-base.conf para poner como dispositivo predeterminado el USB
    • sudo nano /etc/modprobe.d/alsa-base.conf
      • Comentar la línea de options snd-usb-audio index=-2 (poniendo # delante)
    • Anadir estas dos líneas:
      • options snd-usb-audio index=0
      • options snd_bcm2835 index=1
  • Reiniciar:
    • sudo reboot
  • Ajustar el volumen de salida:
    • alsamixer
  • Una vez el volumen está a nuestro gusto, guardar la configuración con el comando:
    • sudo alsactl store
Con esto se termina la configuración del dispositivo de sonido. Fuente: http://fpaez.com/instalar-tarjeta-de-sonido-usb-en-raspberry-pi/

Instalar y utilizar el mpg123

  • Instalación
    • sudo apt-get install mpg123
  • Uso:
    • Reproducir un fichero:
      • mpg123 -C ruta/hasta/fichero.mp3
        • La opción -C permite controlar la reproducción. Para más detalles pulsar h durante la reproducción. Para salir, pulsar q.
    • Reproducir una lista:
      •  mpg123 -@ ruta/hasta/lista/reproduccion.m3u -C
        • Similar al anterior
    • Reproducir todos los ficheros de un directorio:
      • mpg123 -C ruta/hasta/los/ficheros/*.mp3

Acceso desde android

Como suele ser habitual, se utiliza ssh. Hay mucha oferta, pero el que más me gusta porque se porta como una terminal (con otros no funcionaba el tabulador para autocompletar) es: ConnectBot
Hay que utilizar el ConnectBot en combinación con el teclado: Hacker's Keyboard.
Tal vez se pueda poner el connectbot en modo horizontal, pero no lo he conseguido. Por eso he tenido que poner el hacker's keyboard en modo 5 filas vertical (las letras quedan muy pequeñas, pero es un teclado completo).

Con todo eso se puede reproducir contenido de raspberry controlándolo desde el teléfono.

viernes, 10 de julio de 2015

miniboxVOIP smartTV

He comrado este trasto para poder acceder a contenidos multimedia desde un televisor sin conexión de red.

Problemas del trasto:
  • Consume demasiadas pilas.
  • El sensor de movimiento va fatal y el ratón se mueve por donde le apetece.
  • Cuando accede a contenidos DLNA únicamente reproduce un vídeo y se detiene.
La mejor solución que he encontrado (que ha resultado tener ventajas añadidas ha sido instalar en otro dispositivo android (en este caso en un smartphone) una aplicación llamada GinkgoDlna (es el enlace que había cuando lo instalé).
Esta aplicación tiene tres pestañas en la parte superior:
  • LIBRARY
  • FAVORITES
  • PLAYING
Desde library se exploran los servidores DLNA
Desde favorites se accede a los directorios que se han añadido a favoritos
En playing se elige el reproductor que se desea.

En mi caso:
  • En PLAYING elijo MiniMax. Que es: AirPlay/DLNA Receiver (LITE). Generalmente marco la pestaña inferior derecha para que se reproduzca continuamente (porque se lo suelo poner al niño para que esté tranquilo)
  • En library navego por el servidor y elijo el vídeo que deseo reproducir.
La ventaja adicional es que no es necesario acercarse al niño para cambiar lo que esté viendo.

También permite utilizar listas de reproducción y alguna cosilla más.

Bonus: Hacer cosas con el bicho es extremadamente comlicado si está activado el ratón virtual, lo mejor es desactivarlo con el botón correspondiente y hacer toda la navegación con los otros botones. Una vez instalado todo, solo hay que olvidarse del mando. Tambien se puede hacer desde un ordenador normal a través de http://play.google.com/ una vez que se ha vinculado el dispositivo a la cuenta.

viernes, 2 de enero de 2015

Configurar XBMC o KODI como cliete DLNA/UPnP

Es un proceso muy sencillo y demasiado poco documentado.
Parto de una instalación limpia. Empezando por lo que no hay que hacer.
  • No hay que instalar servicios
  • No hay que instalar add-ons
  • No es necesario entrar en configuración experta o avanzada.
Únicamente hay que pulsar en videos->archivo (o en música o en imágenes) y pulsar en "Añadir Vídeos..."
Pulsar en "Buscar"
Elegir UPnP Dispositivos
Esperar a que termine de descubrir el servidor deseado y pulsar sobre él.
Explorar hasta que llegue a la carpeta deseada (si no se desea explorar se cargará el raiz cuando entremos)
OK
Cambiar el nombre si se desea.
OK
Ya está. Cuando se desee utilizar, se le da a Vídeos->Archivos->"nombre del servidor"
He grabado un vídeo (mucho más largo y con muchas revueltas). Innecesario pero que podría le podría venir bien a alguien.
https://drive.google.com/file/d/0B779vDAuKIBKVUJla1Z0VkZ4OHc/view?usp=sharing
https://www.youtube.com/watch?v=AGEbUPNKByw&index=1&list=PLZPtxEuiPHAFf45CoCh_539AQsBTEH86Q



martes, 21 de octubre de 2014

El disco externo empieza a llenarse y he decidido instalar un RAID 5 para tener algo más de espacio y de paso proteger los datos. Ahora toca estudiar el RAID, buscar discos bien ventilados y buscar una nueva ubicación para todo el equipamiento.

De momento: http://davidiesclaradelrey.blogspot.com.es/2012/10/primer-post.html

Y este otro: http://www.makeinstall.es/2011/04/reconstruir-raid5-tras-fallo-en-disco.html

miércoles, 2 de julio de 2014

script php para navegar por los directorios con vista previa de las imagenes

Va a ser una mezcla de varios scripts.
Ahora utilizo uno que recrea la estructura de cada directorio haciendo las vistas previas.
Tambien tengo uno que visualiza la estructura del arbol.
Y otro que muestra el contenido de las carpetas y permite salir a la estructura superior (si se le permite), este fué diseñado para comprobar la seguridad.
En cuanto tenga un rato comienzo el nuevo script.
  • Tiene que recrear toda la estructura desde la raiz (y no navegar hacia arriba)
  • Esa recreación debe hacerla al ir entrando en los sucesivos directorios (para no cargar demasiado en la primera visita)
  • ...

Primer script.

No recuerdo de donde saqué el original, fué hace muchos años y desde entonces ha sufrido varias modificaciones. Hay que ponerlo en la carpeta que se desea indexar y crea las miniaturas en dos tamaños.

Código fuente:

<?
//gallery titles
//$galleryTitle = "Mi galería de imagenes";
//$galleryTitle = getcwd()." ".date("l dS of F Y h:i:s A");
//contar el numero de caracteres que hay hasta la tercera barra y eliminar todo ese texto
//porque está ecribiendo toda la ruta desde el servidor: /web/htdocs/www.
$galleryTitle = basename(getcwd())." (".date("l dS of F Y h:i:s A").")";
$gallerySubTitle = "Mira mis fotos";
$thumbsPerPage = 8;
switch ($_GET['action'])
{
    case "view" :
        viewImage();
        break;
    default :
        displayThumbs();
        break;
}
function displayThumbs()
{
    outHead();
    global $galleryTitle;
    global $gallerySubTitle;
    global $thumbsPerPage;
    echo ' <body class="listBody">'."\n";
    echo '     <table align="center" cellpadding="10" style="border: 3px solid #FF8888">'."\n";
    echo '         <tr style="background-color:#8888FF">'."\n";
    echo '             <td colspan="4">'."\n";
    echo '                 <span class="head1">' . $galleryTitle . '</span><br>'."\n";
    echo '                 <span class="head2">' . $gallerySubTitle . '</span>'."\n";
    echo '             </td>'."\n";
    echo '          </tr>'."\n";   
    $dirpath = getcwd() . "/";
    $dir = opendir($dirpath);
    $files = array();   
    if (!file_exists($dirpath . "/thumbs"))
    {
        echo "creating directory"."\n";
        mkdir($dirpath . "/thumbs");
    }
    if (!file_exists($dirpath . "/browser"))
    {
        echo "creating browser directory"."\n";
        mkdir($dirpath . "/browser");
    }   
    //inicializo $key porque estoy utilizando un nuevo tipo de orden
    $key=0;   
    while ($file = readdir($dir))
    {
        $localpath = $dirpath.$file;   
        if (is_file($localpath) && ((substr(strtolower($file), -3, 3) == "jpg")))
        {
            //$key = filemtime($localpath);
            //antes ordenaba por fechas y yo lo voy a ordenar por nombre           
            $files[$key] = $file;           
            //esto es mío
            $key+=1;
        }
    }   
    //aquí ya no necesito ordenar
    //ksort($files);   
    sort($files);   
    //esto lo voy a cambiar porque lo que quiero es redondear hacía arriba
    //$pages = intval(count($files) / $thumbsPerPage)+1;   
    $aux = intval(count($files) / $thumbsPerPage);
    if ($aux*$thumbsPerPage == count($files))
    {
        $pages = $aux;
    }
    else
    {
        $pages = $aux+1;
    }  
    if (!empty($_GET['page']))
    {
        $currentPage = $_GET['page'];
        } else {
        $currentPage = 1;
    }
    $navString = "";
    $navString .= '            <tr>'."\n\t\t".'<td colspan="4" align="center">'."\n\t\t\t".'<a href="..">Subir un directorio</a> '."\n";
    if ($currentPage != 1)
    {
        $navString .= '<a href="' . $_SERVER["PHP_SELF"] . '?page=' . ($currentPage-1) . '">&lt;&lt;</a>&nbsp;&nbsp;&nbsp;'."\n";
    }   
    $temp = "";
    for ($p=1; $p<=$pages; $p++)
    {
        if ($p == $currentPage)
        {
            $temp .=  $p . "&nbsp;|&nbsp;";
        }
        else
        {
            $temp .= '<a href="' . $_SERVER["PHP_SELF"] . '?page=' . $p . '">' . $p . "</a>&nbsp;|&nbsp;"."\n";
        }
    }
    $navString .= substr($temp, 0, -13);   
    if ($currentPage != $pages)
    {
        $navString .= '&nbsp;&nbsp;&nbsp;<a href="' . $_SERVER["PHP_SELF"] . '?page=' . ($currentPage+1) . '">&gt;&gt;</a>'."\n";
    }   
    $navString .= '</td></tr>'."\n";
    echo $navString;   
    echo "<tr>"."\n";   
    reset ($files);
    while ($currentItem < (($currentPage -1) * $thumbsPerPage))
    {
        next ($files);
        $currentItem++;
    }   
    $count = 0;   
    for ($a=0; $a<$thumbsPerPage; $a++)
    {
        if (substr(strtolower(current($files)), -3, 3) == "jpg")
        {
            if (!file_exists($dirpath . "thumbs/" . current($files)))
            {
                $original = ImageCreateFromJPEG($dirpath . current($files));               
                $x = ImageSX($original);
                $y = ImageSY($original);               
                $newX = 600;               
                $ratio = $newX / $x;
                $newY = $y * $ratio;               
                $thumbnail = ImageCreateTrueColor($newX,$newY);               
                ImageCopyResized($thumbnail, $original, 0, 0, 0, 0, $newX, $newY, $x, $y);               
                ImageJPEG($thumbnail,  $dirpath . "/browser/" . current($files), 100);               
                ImageDestroy($thumbnail);
                ImageDestroy($original);
            }       
            if (!file_exists($dirpath . "thumbs/" . current($files)))
            {
                $original = ImageCreateFromJPEG($dirpath . current($files));               
                $x = ImageSX($original);
                $y = ImageSY($original);               
                $newX = 120;               
                $ratio = $newX / $x;
                $newY = $y * $ratio;               
                $thumbnail = ImageCreateTrueColor($newX,$newY);               
                ImageCopyResized($thumbnail, $original, 0, 0, 0, 0, $newX, $newY, $x, $y);               
                ImageJPEG($thumbnail,  $dirpath . "/thumbs/" . current($files), 100);               
                ImageDestroy($thumbnail);
                ImageDestroy($original);                               
            }
            echo '<td width="140" align="center" valign="top">'."\n";
            echo '<table border="0" width="135"><tr><td colspan="2" style="padding-top:3px">'."\n";
            echo '<a href="' . $_SERVER["PHP_SELF"] . '?action=view&filename=' . current($files) . '&page=' . $currentPage . '" class="imglink"><img src="thumbs/' . current($files) . '" border="0"></a>'."\n";
            echo '</td></tr>'."\n";
            echo '<tr><td width="100">'."\n";
            echo '<span class="listCaption">' . str_replace("_", " ", substr(current($files), 0, -4)) . '</span>'."\n";
            echo '</td><td width="35">'."\n";
            echo '<a href="' . $_SERVER["PHP_SELF"] . '?action=view&filename=' . current($files) . '&page=' . $currentPage . '" class="print"><img src="'."$SERVER_HOST".'/static/view.gif" height="16" width="16" alt="View" border="0"></a>'."\n";
            echo '<a href="' . current($files) . '" class="print"><img src="'."$SERVER_HOST".'/static/print.gif" height="16" width="16" alt="Print" border="0"></a>'."\n";
            echo '</td></tr></table>'."\n";           
            echo '</td>'."\n";
            $count++;
            if ($count % 4 == 0)
            {
                echo '</tr><tr>'."\n";
            }
        }               
        next ($files);
    }   
    echo "</tr>"."\n";
    echo $navString;
    echo "</table>"."\n";
}
function viewImage()
{
    outHead();   
    echo '    <body class="viewBody">'."\n";       
    echo '    <table align="center">'."\n";
    echo '    <tr><td colspan="2">'."\n";
    echo '    <img src="browser/' . $_GET['filename'] . '" alt="Gallery Image"> '."\n";
    echo '    </td></tr>'."\n";       
    echo '    <tr valign="bottom">'."\n";
    echo '    <td class="viewCaption">'."\n";
    echo str_replace("_", " ", substr($_GET['filename'], 0, -4));
    echo '    </td><td align="right">'."\n";
    echo '<a href="' . $_GET['filename'] . '" class="print"><img src="'."$SERVER_HOST".'/static/print.gif" height="16" width="16" alt="Print" border="0"></a>'."\n";
    echo '    <a href="' . $_SERVER["PHP_SELF"] . '?action=list&page=' . $_GET['page'] . '" >Back</a>'."\n";
echo '    </td></tr></table>'."\n";
}
function outHead()
{
    global $galleryTitle;
    echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">'."\n";   
    echo '<html>'."\n";
    echo '<head>'."\n";   
    /*
    echo date( "M d Y H:i:s",mktime(0,0,0,1,1,1998) )."\n";
    echo gmdate( "M d Y H:i:s",mktime(0,0,0,1,1,1998) )."\n";
    echo date("l dS of F Y h:i:s A")."\n";
    */   
    echo ' <title>' . $galleryTitle . '</title>'."\n";
    echo ' <style type="text/css">'."\n";
    echo '     .listBody'."\n";
    echo '          {'."\n";
    echo '              font-family:arial; '."\n";
    echo '              font-size:12px; '."\n";
    echo '              background:#44bbbb;'."\n";
    echo '          }'."\n";
    echo '     .small'."\n";
    echo '          {'."\n";
    echo '              font-size:10px; '."\n";
    echo '              font-weight:normal'."\n";
    echo '          }'."\n";
    echo '     .listCaption'."\n";
    echo '          {'."\n";
    echo '              font-family:arial; '."\n";
    echo '              font-size:11px; '."\n";
    echo '              font-weight:bold'."\n";
    echo '           }'."\n";
    echo '     .head1 '."\n";
    echo '          {'."\n";
    echo '              font-family:arial;'."\n";
    echo '              font-size:24px;'."\n";
    echo '              color:#ffff88;'."\n";
    echo '              font-weight:bold'."\n";
    echo '          }'."\n";
    echo '     .head2'."\n";
    echo '          {'."\n";
    echo '              font-family:arial; '."\n";
    echo '              font-size:16px; '."\n";
    echo '              color:#88ffff'."\n";
    echo '          }'."\n";
    echo '     td'."\n";
    echo '          {'."\n";
    echo '             font-family:arial;'."\n";
    echo '             font-size:13px;'."\n";
    echo '             font-weight:bold;'."\n";
    echo '         }'."\n";
    echo '             a:link,'."\n";
    echo '             a:visited,'."\n";
    echo '             a:active { color: #224466; }'."\n";
    echo '             a:hover  { color: #ffff00; }'."\n";
    echo '             a.imglink:link,'."\n";
    echo '             a.imglink:visited,'."\n";
    echo '             a.imglink:active'."\n";
    echo '              {'."\n";
    echo '                 display:block; '."\n";
    echo '                 border-top: 3px solid #888888; '."\n";
    echo '                 border-left: 4px solid #888888;'."\n";
    echo '                 border-bottom: 3px solid #888888;'."\n";
    echo '                 background-color:#888888'."\n";
    echo '              }'."\n";
    echo '             a.imglink:hover'."\n";
    echo '              {'."\n";
    echo '                 display:block; '."\n";
    echo '                 border-top: 3px solid #88ff88; '."\n";
    echo '                 border-left: 4px solid #88ff88;'."\n";
    echo '                 border-bottom: 3px solid #88ff88;'."\n";
    echo '                 background-color:#88ff88'."\n";
    echo '              }'."\n";
   
    echo '         .viewBody'."\n";
    echo '          {'."\n";
    echo '             margin:20px 20px 20px 20px;'."\n";
    echo '             background:#44bbbb;    '."\n";
    echo '             font-family:arial;'."\n";
    echo '             font-size:10pt;'."\n";
    echo '             font-weight:bold;    '."\n";
    echo '         }'."\n";
    echo '         .viewCaption'."\n";
    echo '          {'."\n";
    echo '             font-family:arial;'."\n";
    echo '             font-size:14pt;'."\n";
    echo '             font-weight:bold;    '."\n";
    echo '         }'."\n";
    echo ' </style>'."\n";
    echo '</head>'."\n";
    return;
}
?>

Tiene unos iconos asociados de una lupa y de una impresora. El de la lupa ve la imagen a 600 y el de la impresora ve la imagen original.

Segundo script

También tiene asociados iconos. Este script muestra la estructura de directorios en forma de arbol.
Es de: http://www.metalhead.ws/phpbin/ y tiene modificaciones hechas por mi. Tampoco recuerdo que cosas le hice ni cuando. Creo que los comentarios que comienzan con javi los hice yo, pero no recuerdo que modifiqué ni por qué. Esposible que en metalhead todavía tengan el original. En este encuentro demasiados símbolos extraños.

Código fuente:

<?
/*javi: inicializaci󮠤e la variable z*/
/*global $zz;*/
$zz=0;
$galleryTitle = basename(getcwd())." (".date("l dS of F Y h:i:s A").")";
/* Sitemap version 2.0 (C) copyright Metalhead 2003
 * P⨩na web: http://www.metalhead.ws/phpbin/
 * Este script se distribuye bajo los t곭inos de la
 * Licencia P򢬩ca General GNU (GNU GPL)
 * Una copia de la GPL ha sido inclu con el script. */
/* Secci󮠤e Configuraci󮠪/
$showsize = 1; /* Mostrar el tama񯠤e los archivos? 1 = s�0 = no */
/* Array de tipos de archivos visualizados y sus respectivos iconos.
 * Sintaxis: $display[filetype] = "picture"; */
$display[php] = "$SERVER_HOST/listado/php.gif";
$display[html] = "$SERVER_HOST/listado/html.gif";
$display[htm] = "$SERVER_HOST/listado/html.gif";
$display[shtml] = "$SERVER_HOST/listado/html.gif";
/* Array de directorios que no deben ser visualizados.
 * Sintaxis: $excludedir[] = "directory"; */
$excludedir[] = "temp";
$excludedir[] = "tmp";
$excludedir[] = "browser";
$excludedir[] = "static";
$excludedir[] = "thumbs";
$excludedir[] = "test";
$excludedir[] = "cgi-bin";
$excludedir[] = "privado";
/* Array de archivos que no ser⮠visualizados. */
$excludefile[] = "index.php";
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <!-- <title>Mapa del sitio web</title> -->
<?
    echo '      <title>' . $galleryTitle . '</title>'."\n";
?>
    </head>
<body>
<b>Mapa del sitio web</b><p>
<?
$stime = gettimeofday();
/* prueba inicial... */
$root = getcwd();
/*echo "root=$root";
$largo=strlen($root);
echo " longitud root=$largo";*/
$pre = explode("/", $REQUEST_URI);
array_pop($pre);
$prefix = join("/", $pre);
/* Si el script se encuentra en un subdirectorio, descomenta las
 * siguientes dos lineas para generar el Ⳣol de todos los
 * archivos y directorios del servidor web */
/*NO QUIERO MOSTRAR EL ARBOL DE DIRECTORIOS POR ENCIMA DEL ACTUAL*/
/*POR ESO VOY A PONER COMO COMENCTARIO ESE CODIGO*/
//$root = str_replace($prefix, "", $root);
//$prefix = "";
//$root .= "/";
/* Visualiza el nombre del servidor y el directorio */
echo "<table cellspacing=0 cellpadding=0 border=0>\n";
echo "<tr><td><img align=absmiddle src=$SERVER_HOST/listado/server.gif> http://$SERVER_NAME";
echo "$prefix/";
echo "</td></tr><tr><td><img align=absmiddle src=$SERVER_HOST/listado/vertical.gif></td></tr>\n";
function get_extension($name)
{
   $array = explode(".", $name);
   $retval = strtolower(array_pop($array));
   return $retval;
}
/* Rekurencja... */
function list_dir($chdir)
{
   /*javi: el nivel de la recurrencia es:*/
   /*global $zz;
   global $zdir, $zdir1, $zcount;
   /*echo " zz=$zz";*/
   /*if ($zz == 0)
   {
   $zdir = getcwd();
   $zdir1 = str_replace($root, "", $dir."/");
   $zcount = substr_count($dir1, "/") + substr_count($dir1, "\\");
   }
   global $root;
   global $largo;
   echo "root=$root";
   echo "largo=$largo"; */
   /* algunas variables globales y un poco de orden */
   global $root, $prefix, $PHP_SELF, $SERVER_NAME, $showsize, $display, $excludedir, $excludefile;
   unset($sdirs);
   unset($sfiles);
   chdir($chdir);
   $self = basename($PHP_SELF);
  /* abrimos el directorio actual */
  $handle = opendir('.');
  /* leemos el directorio. Si el objeto
  * es un directorio lo introducimos a
  * $sdirs, si se trata de un archivo
  * que nos interesa (exceptuando el
  * que contiene este script), lo colocamos
  * en $sfiles */
   $dir = getcwd();
   $dir1 = str_replace($root, "", $dir."/");
   $count = substr_count($dir1, "/") + substr_count($dir1, "\\");
   /*javi: voy a almacenar los n򭥲os de barras para restarlos despu곪/
   /*echo " dir=$dir dir1=$dir1 count=$count";
   echo " zdir=$zdir zdir1=$zdir1 zcount=$zcount";*/
   /*echo " chdir=$chdir";*/
  while ($file = readdir($handle))
  {
    if(is_dir($file) && $file !=
       "." && $file != ".."
       && !in_array($file,
         $excludedir))
    { $sdirs[] = $file; }
    elseif(is_file($file)
      && $file != "$self"
      && array_key_exists(
        get_extension($file),
          $display)
      && !in_array($file,
        $excludefile))
    { $sfiles[] = $file; }
  }
   /* contamos las barras para saber la profundidad a la que estamos
    * o en la estructura de directorios y cu⯴os segmentos debemos
    * usar de la rama en la que estamos */
   $dir = getcwd();
   $dir1 = str_replace($root, "", $dir."/");
   $count = substr_count($dir1, "/") + substr_count($dir1, "\\");
   /*javi: voy a almacenar los n򭥲os de barras para restarlos despu곪/
   /*echo " dir=$dir dir1=$dir1 count=$count";*/
   /*echo "dir= $dir dir1= $dir1 count=$count";*/
   /* mostramos por pantalla los nombres y obtenemos la lista recursiva de los
    * directorios */
   if(is_array($sdirs)) {
      sort($sdirs);
      reset($sdirs);
      for($y=0; $y<sizeof($sdirs); $y++) {
         echo "<tr><td>";
         for($z=1; $z<=$count; $z++)
         { echo "<img align=absmiddle src=$SERVER_HOST/listado/vertical.gif>&nbsp;&nbsp;&nbsp;"; }
         if(is_array($sfiles))
         { echo "<img align=absmiddle src=$SERVER_HOST/listado/verhor.gif>"; }
         else
         { echo "<img align=absmiddle src=$SERVER_HOST/listado/verhor1.gif>"; }
         echo "<img align=absmiddle src=$SERVER_HOST/listado/folder.gif>
               <a href=\"http://$SERVER_NAME$prefix$dir1$sdirs[$y]\">$sdirs[$y]</a>";
         //echo " SERVER_NAME=$SERVER_NAME , prefix=$prefix , dir1=$dir1 , sfiles[$y]=$sfiles[$y]";
         /*javi: voy a controlar la profundidad de la recurrencia*/
         ++$zz;
         list_dir($dir."/".$sdirs[$y]);
      }
   }
   chdir($chdir);
   /* visitamos cada uno de los elementos del array de archivos
    * y los imprimimos */
   if(is_array($sfiles)) {
      sort($sfiles);
      reset($sfiles);
      $sizeof = sizeof($sfiles);
      /* ࠱u顴ipos de ficheros deben ser visualizados? */
      for($y=0; $y<$sizeof; $y++) {
         echo "<tr><td>";
         for($z=1; $z<=$count; $z++)
         { echo "<img align=absmiddle src=$SERVER_HOST/listado/vertical.gif>&nbsp;&nbsp;&nbsp;"; }
         if($y == ($sizeof -1))
         { echo "<img align=absmiddle src=$SERVER_HOST/listado/verhor1.gif>"; }
         else
         { echo "<img align=absmiddle src=$SERVER_HOST/listado/verhor.gif>"; }
         echo "<img align=absmiddle src=\"";
         echo $display[get_extension($sfiles[$y])];
         echo "\"> ";
         //echo "<a href=\"http://$SERVER_NAME$prefix/$dir1$sfiles[$y]\">$sfiles[$y]</a>";
         echo "<a href=\"http://$SERVER_NAME$prefix$dir1$sfiles[$y]\">$sfiles[$y]</a>";
         //echo " SERVER_NAME=$SERVER_NAME , prefix=$prefix , dir1=$dir1 , sfiles[$y]=$sfiles[$y]";
         if($showsize) {
            $fsize = @filesize($sfiles[$y])/1024;
            printf(" (%.2f kB)", $fsize);
         }
         echo "</td></tr>";
         echo "<tr><td>";
      }
      echo "<tr><td>";
      for($z=1; $z<=$count; $z++)
      { echo "<img align=absmiddle src=$SERVER_HOST/listado/vertical.gif>&nbsp;&nbsp;&nbsp;"; }
      echo "</td></tr>\n";
   }
}
list_dir($root);
echo "</table>\n";
/* ࠃu⯴o tiempo nos llev󿠪/
$ftime = gettimeofday();
$time = round(($ftime[sec] + $ftime[usec] / 1000000) - ($stime[sec] + $stime[usec] / 1000000), 5);
echo "<center>Tiempo de generaci󮠤e la p⨩na: $time segundos</center>\n";
echo "<A HREF=http://$HTTP_HOST>http://$HTTP_HOST</A>\n";
?>
</body></html>
 

Tercer script

Lo he sacado de: http://www.wextensible.com/herramientas/explorador-php/
Es muy interesante porque está centrado en la seguridad.

Código fuente:

<?php
/* EXPLORADOR DE CARPETAS Y ARCHIVOS CON PHP
 * Documento explora.php
 * Explorador de carpetas y archivos usando el sistema de ficheros de PHP.
 * Autor: Andrés de la Paz © 2010
 * Contacto: www.wextensible.com
 */

//Por defecto la primera vez que abrimos este explorador toma
//como carpeta la del php actual. La constante __FILE__ es la
//ruta del archivo PHP actual. Con dirname obtenemos la carpeta.
$ruta = dirname(__FILE__)."/";
//Para abrir archivos necesitaremos poner la codificación
//adecuada con estos valores
$array_codif = Array(
"UTF-8",
"ISO-8859-1",
"ISO-8859-15"
);

//Por defecto usamos esta para htmlentities (ver más abajo)
$codificacion = "ISO-8859-1";

//Vemos si hay algo en el GET
if (isset($_GET)){
    foreach($_GET as $campo=>$valor){
        switch ($campo) {
            //Obtenemos una ruta, carpeta o archivo
            case "una-ruta":
                $ruta = htmlspecialchars($valor, ENT_QUOTES);
                if (get_magic_quotes_gpc() == 1) $ruta = stripslashes($ruta);
                break;
            //Vemos la codificación
            case "una-codificacion":
                $codificacion = htmlspecialchars($valor, ENT_QUOTES);
                if (get_magic_quotes_gpc() == 1) $codificacion = stripslashes($codificacion);
                break;

        }
    }
}

//Si la ruta es vacía, pone la del presente script
if ($ruta == "") $ruta = dirname(__FILE__)."/";

//Esta variable contendrá la lista de nodos (carpetas y archivos)
$presenta_nodos = "";

//Esta variable es para el contenido del archivo
$presenta_archivo = "";

//Si la ruta es una carpeta, la exploramos. Si es un archivo
//sacamos también el contenido del archivo.
if (is_dir($ruta)){//ES UNA CARPETA
    //Con realpath convertimos los /../ y /./ en la ruta real
    $ruta = realpath($ruta)."/";
    //exploramos los nodos de la carpeta
    $presenta_nodos = explora_ruta($ruta);
} else {//ES UN ARCHIVO
    $ruta = realpath($ruta);
    //Sacamos también los nodos de la carpeta
    $presenta_nodos = explora_ruta(dirname($ruta)."/");
    //Y sacamos el contenido del archivo
    $presenta_archivo = "<br />CONTENIDO DEL ARCHIVO: ".
    $ruta."<pre>".
    explora_archivo($ruta, $codificacion).
    "</pre>";
}
//Función para explorar los nodos de una carpeta
//El signo @ hace que no se muestren los errores de restricción cuando
//por ejemplo open_basedir restringue el acceso a algún sitio
function explora_ruta($ruta){
    //En esta cadena haremos una lista de nodos
    $cadena = "";
    //Para agregar una barra al final si es una carpeta
    $barra = "";
    //Este es el manejador del explorador
    $manejador = @dir($ruta);
    while ($recurso = $manejador->read()){
        //El recurso sera un archivo o una carpeta
        $nombre = "$ruta$recurso";
        if (@is_dir($nombre)) {//ES UNA CARPETA
            //Agregamos la barra al final
            $barra = "/";
            $cadena .= "CARPETA: ";
        } else {//ES UN ARCHIVO
            //No agregamos barra
            $barra = "";
            $cadena .= "ARCHIVO: ";
        }
        //Vemos si el recurso existe y se puede leer
        if (@is_readable($nombre)){
            $cadena .= "<a href=\"".$_SERVER["PHP_SELF"].
            "?una-ruta=$nombre$barra\">$recurso$barra</a>";
        } else {
            $cadena .= "$recurso$barra";
        }
        $cadena .= "<br />";
    }
    $manejador->close();
    return $cadena;
}

//Función para extraer el contenido de un archivo
function explora_archivo($ruta, $codif){
    //abrimos un buffer para leer el archivo
    ob_start();
    readfile($ruta);
    //volcamos el buffer en una variable
    $contenido = ob_get_contents();
    //limpiamos el buffer
    ob_clean();
    //retornamos el contenido después de limpiarlo
    //aplicando la codificación seleccionada
    return htmlentities($contenido, ENT_QUOTES, $codif);
}

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="es">
<head>
    <title>Explora carpetas</title>
    <meta http-equiv="X-UA-Compatible" content="IE=8" />
    ...
</head>
<body>
    ...
    <h3>Opciones de configuración PHP (restringen explorador)</h3>
    <ul>
    <?php
        $opciones = "<li><a href=\"http://docs.php.net/manual/es/ini.sect.safe-mode.php#ini.safe-mode\">".
        "<code>safe_mode</code></a> ";
        if (ini_get("safe_mode")){
            $opciones .= ": activado";
        } else {
            $opciones .= ": desactivado";
        }
        $opciones .= "</li>".
        "<li><a href=\"http://docs.php.net/manual/es/ini.core.php#ini.open-basedir\">".
        "<code>open_basedir</code></a>: ".ini_get("open_basedir")."</li>".
        "<li><a href=\"http://docs.php.net/manual/es/function.getmyuid.php\">".
        "<code>getmyuid()</code></a>: ".getmyuid()."</li>".
        "<li><a href=\"http://docs.php.net/manual/es/function.getmygid.php\">".
        "<code>getmygid()</code></a>: ".getmygid()."</li>";
        echo $opciones;
    ?>
    </ul>

    <h3>Exploración</h3>
    <form action="<?php echo $_SERVER["PHP_SELF"] ?>" method="get">
        Ruta <small>(En Windows pueden usarse ambas barras "/" y "\")</small>
        <br /><textarea rows="5" cols="50" name="una-ruta"
        ><?php echo $ruta; ?></textarea><br />
        Codificación para ver archivos:
        <select name="una-codificacion">
            <?php
                foreach ($array_codif as $i=>$val){
                    echo "<option value=\"$val\"";
                    if ($codificacion == $val) echo " selected=\"selected\"";
                    echo ">$val</option>";
                }
            ?>
        </select><br />
        <input type="submit" value="enviar" />
    </form>

    <?php
        echo "<br />$presenta_nodos";
        echo "<br />$presenta_archivo";
    ?>
</body>
</html>

Cuarto script

Tampoco recuerdo si lo copié o lo creé. Es muy sencillo y permite listar el contenido de la carpeta, pero no permite navegar.

Código fuente:

<html>
    <head>
        <title>Videos de Miki</title>
    </head>
    <body>
        <?php
            $dirpath = getcwd() . "/";
            $dir = opendir($dirpath);
            $files = array();
            $i=0;
            while ($file = readdir($dir))
            {
                $files[$i] = $file;
                $i+=1;
            }
            sort($files);
            $i=0;
            while ($files[$i])
            {
                if (is_dir($files[$i]))
                {
                    echo '<a href=./'.$files[$i].'>'.$files[$i];
                    echo '<br>';
                }
                $i+=1;
            }
        ?>
    </body>
</html>

Otro script

 Tiene un funcionamiento adecuado excepto por el detalle de que no crea las vistas previas y por lo tanto tiene que generar la página completa cada vez que se visita. No me parece ni necesario ni adecuado utilizar tanta potencia para un proceso que se podría realizar una sola vez.
Fuente: http://www.syntaxerror.es/proyectos/minigallery
Plugin Name: WP-MiniGallery
Tiene 809 líneas y ocupa 25 K. Excesivo para ponerlo aquí.

Definitivo

A partir de aquí habrá que ir sacando el "definitivo" porque empiezo a estar cansado de poner el script cada vez que creo un directorio con fotos.
La idea es crear una carpeta con un nombre que no se vaya a indexar y que sirva como base_de_datos/tabla_de_localización_de_ficheros (será la que vaya explorando el script en vez de la "real") y que cuando se visita una carpeta:
  • Si es la primera vez que se visita, cree una vista previa del contenido y lo visualice.
  • Si ya se ha visitado antes, cargue la vista previa anterior y compruebe si se ha cambiado algo desde la última visita:
    • Si ha habido cambios, se cambie la página guardada.
    • Si no ha habido cambios todo sigue igual.
  • ... ya se me irán ocurriendo más cosas
Ya va estando una pre-casi-primera versión.
Tenía una duda sobre si debería utilizar md5 o sha y después de buscar mucho he encontrado algo (todo el mundo hace las comparativas refiriendose a la seguridad de contraseñas y yo deseo comparar un listado de ficheros): http://www.monografias.com/trabajos76/funciones-hash-criptografia/funciones-hash-criptografia2.shtml
En el apartado Pasos y tasas de cifra en MD5 y SHA-1.
Por estos motivos la ejecución del algoritmo SHA-1 es más lenta que la de MD5 usando un mismo hardware, por ejemplo un programa realizado en C entregaba en un Pentium a 266 Mhz (no importa que esta velocidad sea tan baja) una tasa del orden de 20 Mbits/seg para SHA-1 y para MD5 esta tasa llegaba a los 60 Mbits/seg.
Puesto que lo deseado es que sea rápido y consumir pocos recursos, en este caso lo ideal es md5.
El código fuente-chapuza de lo que llevo hasta ahora es:
/////////////////////////////////////////////////////////////////////////////////////////////
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="es">
<head>
    <title>Explora carpetas</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<?php
    $ruta = dirname(__FILE__)."/";
    echo "La ruta es: ".$ruta."<br />";
    $privado=$ruta."privado";
    //en su momento habrá que crear una opción para que cree o actualice todo el arbol
    if(!file_exists($privado)){
        echo 'No existe '.$privado.'<br />';
        echo 'Se va a crear un directorio ...<br />';
        mkdir ($privado,0777);//habría que comprobar si se ha creado por si no se tiene permiso de escritura
        if(!file_exists($privado)){
            echo 'Ha sido imposible crear el directorio privado. Se abandona la ejecución<br />';
            return;
        }else{
            echo 'Se ha creado el directorio y no ha habido problemas<br />';
        }
    }else{
        echo 'Existe el fichero o el directorio. Falta hacer esa comprobación<br />';
        if(is_dir($privado)){
            echo 'Ya existe el directorio. Todo va bien...<br />';
        }else{
            echo 'Hay un problema. Existe un fichero de nombre "privado". Imposible resolverlo desde aquí<br />';
            return;
        }
    }
    //Si ha llegado aquí es que todo ha ido bien. Se supone que se ha comprobado si se creó en caso de que se haya tenido que crear.
    //Debería comprobar si hay un fichero index.html. En caso de que exista cargarlo y comprobar si ha habido cambios. En caso de que no exista, generarlo a partir del contenido.
    //explorar el directorio y crear el fichero index.html
    if(!file_exists($privado.index.html)){
        //hay que generarlo para poder visualizarlo
        echo 'No existe index.html<br />';
        $index=$privado.'/index.html';
        echo 'el fichero index.html se va a crear en: '.$index.'<br />';
        $fp=fopen($index,"w");//'w' Para solo escritura. Se pone el puntero al principio, y si existe, BORRA todo su contenido. Si no existe el fichero, LO CREA.
        //ya se tiene un puntero a fichero llamado fp que apunta al comienzo de un fichero vacío.
        //algo va mal en este bloque
        //está localizado. al crearlo no le da permiso de escritura.
        //Ya pertenecía al usuario/grupo www-data
        //dando permisos 777 funciona una vez y se los quita
        echo 'los permisos son: '.base_convert(fileperms($privado),10,8).'<br />';
        //llamar a la función que escribe el fichero html
        //a su vez esta función llama a otra que escribe las cabeceras
        fwrite($fp, '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">'."\n");
        fwrite($fp, '<html xmlns="http://www.w3.org/1999/xhtml" lang="es">'."\n");
        fwrite($fp, '<head>'."\n");
        fwrite($fp, '<title>Probando...</title>'."\n");
        fwrite($fp, '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'."\n");
        fwrite($fp, '</head>'."\n");
        fwrite($fp, '<body>'."\n");
        fwrite($fp, '<h1>Titulo</h1>'."\n");
        fwrite($fp, '1');
        fwrite($fp, '23');
        fwrite($fp, '45<br />'."\n\n\n\n\n");
        fwrite($fp, '<h1>hache 1</h1>');
        fwrite($fp, '</body>'."\n");
        fwrite($fp, '</html>'."\n");
        echo 'los permisos son: '.base_convert(fileperms($privado),10,8).'<br />';
        fclose($fp);
    }else{
        echo 'Ya esixte index.html. Se procede a cargarlo<br />';
        //hay que cargar el existente y comprobarlo en segundo plano
        //la comprobación debe ser sencilla, contar el número de ficheros y compararlo con un número alamacenado
        //y si son iguales hacer una comprobación tipo md5 con el listado de ficheros
       
        //string md5 ( string $str [, bool $raw_output = false ] )
        //str es una cadena
       
    }
?>
</body>
</html>
/////////////////////////////////////////////////////////////////////////////////