¿Cómo MediaWiki compone las rutas de imagen?
Pregunta
Tengo una aplicación Perl que analiza las tablas de MediaWiki SQL y muestra los datos de varias páginas wiki. Necesito poder volver a crear la ruta de imagen absoluta para mostrar las imágenes, por ejemplo: ... / f / fc / Herbs.jpg / 300px-Herbs.jpg
Del manual de MediaWiki:
Autorización de la imagen: " la ruta [image] se puede calcular fácilmente a partir del nombre del archivo y ... "
¿Cómo se calcula el camino?
Solución
Una forma posible sería calcular la firma MD5 del archivo (o la ID del archivo en una base de datos), y luego construir / encontrar la ruta en base a eso.
Por ejemplo, supongamos que obtenemos una firma MD5 como " 1ff8a7b5dc7a7d1f0ed65aaa29c04b1e "
La ruta podría verse como " / 1f / f " o " / 1f / ff / 8a "
El motivo es que no desea tener todos los archivos en una carpeta, y desea tener la capacidad de " partición " a través de diferentes servidores, o una SAN o lo que sea de una manera igualmente amplia.
La firma MD5 es una cadena de 16 " hex " caracteres. Así que nuestro ejemplo de " / 1f / ff / 8a " nos da 256 * 256 * 256 carpetas para almacenar los archivos. Eso debería ser suficiente para cualquiera :)
Actualización, debido a la demanda popular:
NOTA : Me acabo de dar cuenta de que estamos hablando específicamente de cómo lo hace MediaWiki. Esto es no ahora MediaWiki lo hace, pero otra forma en la que podría haberse hecho .
Por " firma MD5 " Me refiero a hacer algo como esto (ejemplos de código en Perl):
use Digest::MD5 'md5_hex';
my $sig = md5_hex( $file->id );
$ sig ahora tiene 32 caracteres alfanuméricos: " 1ff8a7b5dc7a7d1f0ed65aaa29c04b1e "
Luego crea una estructura de carpetas como esta:
my $path = '/usr/local/media';
map { mkdir($path, 0666); $path .= "/ Una forma posible sería calcular la firma MD5 del archivo (o la ID del archivo en una base de datos), y luego construir / encontrar la ruta en base a eso.
Por ejemplo, supongamos que obtenemos una firma MD5 como " 1ff8a7b5dc7a7d1f0ed65aaa29c04b1e "
La ruta podría verse como " / 1f / f " o " / 1f / ff / 8a "
El motivo es que no desea tener todos los archivos en una carpeta, y desea tener la capacidad de " partición " a través de diferentes servidores, o una SAN o lo que sea de una manera igualmente amplia.
La firma MD5 es una cadena de 16 " hex " caracteres. Así que nuestro ejemplo de " / 1f / ff / 8a " nos da 256 * 256 * 256 carpetas para almacenar los archivos. Eso debería ser suficiente para cualquiera :)
Actualización, debido a la demanda popular:
NOTA : Me acabo de dar cuenta de que estamos hablando específicamente de cómo lo hace MediaWiki. Esto es no ahora MediaWiki lo hace, pero otra forma en la que podría haberse hecho .
Por " firma MD5 " Me refiero a hacer algo como esto (ejemplos de código en Perl):
use Digest::MD5 'md5_hex';
my $sig = md5_hex( $file->id );
$ sig ahora tiene 32 caracteres alfanuméricos: " 1ff8a7b5dc7a7d1f0ed65aaa29c04b1e "
Luego crea una estructura de carpetas como esta:
/
usr/
local/
media/
1f/
f8/
a7/
1ff8a7b5dc7a7d1f0ed65aaa29c04b1e
La estructura de la carpeta se ve como
<*>" } $sig =~ m/^(..)(..)(..)/;
open my $ofh, '>', "$path/$sig"
or die "Cannot open '$path/$sig' for writing: $!";
print $ofh "File contents";
close($ofh);
La estructura de la carpeta se ve como
<*>Otros consejos
La respuesta aceptada es incorrecta:
- La suma MD5 de una cadena es de 32 caracteres hexadecimales (128 bits), no 16
- La ruta del archivo se calcula a partir de la suma MD5 del nombre de archivo, no del contenido del archivo en sí
- El primer directorio en la ruta es el primer carácter, y el segundo directorio es el primer y segundo caracteres. La ruta del directorio no es una combinación de los primeros 3 o 6 caracteres.
La suma MD5 de 'Herbs.jpg' es fceaa5e7250d5036ad8cede5ce7d32d6. Los primeros 2 caracteres son 'fc', que dan la ruta del archivo f / fc /, que es la que se da en el ejemplo.
En PHP puede llamar a la siguiente función para obtener la URL. Es posible que desee ver el código php para averiguar cómo calculan la ruta.
$url = wfFindFile(Title::makeTitle(NS_IMAGE, $fileName))->getURL();
Creé un pequeño script de Bash llamado reorder.sh que mueve archivos desde adentro " imágenes " a las subcarpetas específicas:
#!/bin/bash
cd /opt/mediawiki/mediawiki-cur/images
for i in `find -maxdepth 1 -type f ! -name .htaccess ! -name README ! -name reorder.sh -printf '%f\n'`; do
path1=$(echo -n $i | md5sum | head -c1) &&
path2=$(echo -n $i | md5sum | head -c2) &&
mkdir -p $path1/$path2/ &&
mv $i $path1/$path2/;
done