In che modo MediaWiki compone i percorsi dell'immagine?
Domanda
Ho un'applicazione Perl che analizza le tabelle SQL di MediaWiki e visualizza i dati da più pagine wiki. Devo essere in grado di ricreare il percorso dell'immagine assoluto per visualizzare le immagini, ad esempio: ... / f / fc / Herbs.jpg / 300px-Herbs.jpg
Dal manuale MediaWiki:
Image_Authorisation: " il percorso [image] può essere calcolato facilmente dal nome del file e ... "
Come viene calcolato il percorso?
Soluzione
Un modo possibile sarebbe calcolare la firma MD5 del file (o l'ID file in un database), quindi creare / trovare il percorso basato su quello.
Ad esempio, supponiamo di ottenere una firma MD5 come " 1ff8a7b5dc7a7d1f0ed65aaa29c04b1e "
Il percorso potrebbe apparire come " / 1f / f " o " / 1f / ff / 8a "
Il motivo è che non vuoi avere tutti i file in 1 cartella e vuoi avere la possibilità di " partizionare " attraverso server diversi, o una SAN o qualsiasi altra cosa in modo equamente distribuito.
La firma MD5 è una stringa di 16 "esadecimale" personaggi. Quindi il nostro esempio di " / 1f / ff / 8a " ci dà 256 * 256 * 256 cartelle in cui archiviare i file. Dovrebbe essere sufficiente per chiunque :)
Aggiornamento, a causa della richiesta popolare:
NOTA - Ho appena realizzato che stiamo parlando in particolare di come MediaWiki lo fa. Questo non è non ora MediaWiki lo fa, ma un altro modo in cui avrebbe potuto essere fatto .
Per " Firma MD5 " Intendo fare qualcosa del genere (esempi di codice in Perl):
use Digest::MD5 'md5_hex';
my $sig = md5_hex( $file->id );
$ sig ora è lungo 32 caratteri alfanumerici: " 1ff8a7b5dc7a7d1f0ed65aaa29c04b1e "
Quindi crea una struttura di cartelle come questa:
my $path = '/usr/local/media';
map { mkdir($path, 0666); $path .= "/ Un modo possibile sarebbe calcolare la firma MD5 del file (o l'ID file in un database), quindi creare / trovare il percorso basato su quello.
Ad esempio, supponiamo di ottenere una firma MD5 come " 1ff8a7b5dc7a7d1f0ed65aaa29c04b1e "
Il percorso potrebbe apparire come " / 1f / f " o " / 1f / ff / 8a "
Il motivo è che non vuoi avere tutti i file in 1 cartella e vuoi avere la possibilità di " partizionare " attraverso server diversi, o una SAN o qualsiasi altra cosa in modo equamente distribuito.
La firma MD5 è una stringa di 16 "esadecimale" personaggi. Quindi il nostro esempio di " / 1f / ff / 8a " ci dà 256 * 256 * 256 cartelle in cui archiviare i file. Dovrebbe essere sufficiente per chiunque :)
Aggiornamento, a causa della richiesta popolare:
NOTA - Ho appena realizzato che stiamo parlando in particolare di come MediaWiki lo fa. Questo non è non ora MediaWiki lo fa, ma un altro modo in cui avrebbe potuto essere fatto .
Per " Firma MD5 " Intendo fare qualcosa del genere (esempi di codice in Perl):
use Digest::MD5 'md5_hex';
my $sig = md5_hex( $file->id );
$ sig ora è lungo 32 caratteri alfanumerici: " 1ff8a7b5dc7a7d1f0ed65aaa29c04b1e "
Quindi crea una struttura di cartelle come questa:
/
usr/
local/
media/
1f/
f8/
a7/
1ff8a7b5dc7a7d1f0ed65aaa29c04b1e
La struttura delle cartelle assomiglia
<*>" } $sig =~ m/^(..)(..)(..)/;
open my $ofh, '>', "$path/$sig"
or die "Cannot open '$path/$sig' for writing: $!";
print $ofh "File contents";
close($ofh);
La struttura delle cartelle assomiglia
<*>Altri suggerimenti
La risposta accettata non è corretta:
- La somma MD5 di una stringa è di 32 caratteri esadecimali (128 bit), non di 16
- Il percorso del file viene calcolato dalla somma MD5 del nome file, non dal contenuto del file stesso
- La prima directory nel percorso è il primo carattere e la seconda directory è il primo e il secondo carattere. Il percorso della directory non è una combinazione dei primi 3 o 6 caratteri.
La somma MD5 di 'Herbs.jpg' è fceaa5e7250d5036ad8cede5ce7d32d6. I primi 2 caratteri sono 'fc', che fornisce il percorso del file f / fc /, che è quello che viene dato nell'esempio.
In PHP puoi chiamare la seguente funzione per ottenere l'URL. Potresti voler guardare il codice php per capire come calcolano il percorso.
$url = wfFindFile(Title::makeTitle(NS_IMAGE, $fileName))->getURL();
Ho creato un piccolo script Bash chiamato reorder.sh che sposta i file dall'interno di " images " nelle sottocartelle specifiche:
#!/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