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?

È stato utile?

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top