• Non ci sono risultati.

3.1 Implementazioni e strumenti nel Museo Virtuale in VR

3.1.4 Recupero delle informazioni da Wikimedia Commons

Il recupero delle informazioni dalla repository di Wikimedia Commons prevede una serie di passi aggiuntivi rispetto ai metodi riservati a Google Images. In questo paragrafo verranno elencati i vari metodi implementativi per il recupero delle informazioni e dei metadati da Wikimedia Commons.

3.1.4.1 La funzione getWikimediaFiles()

Il primo passo consiste nel recuperare le informazioni riguardanti i files da scaricare. Per fare ciò, la funzione getWikimediaFiles() utilizza una libreria esterna (scritta in C++) e le API di Wikimedia Commons per trovare, data una determinata stringa contenente il nome della galleria d’arte, la lista delle opere d’arte contenute nella medesima pagina.

Come nella precedente funzione getGoogle(), anche in questi casi vengono dichiarate delle direttive per caricare una libreria esterna e per comporre un pattern di ricerca da passare allo script scritto in C++. La funzione prende in input il nome della galleria d’arte selezionata dall’utente nella pagina HTML e restituisce un array di stringhe corrispondente alla lista dei file recuperata da internet.

function getWikimediaFiles(url, num){ SETLOCALDIR();

//Carico la libreria esterna

var libreria = CVmExternDLL("curlWikimedia.dll"); //Aggiungo la funzione dalla libreria esterna libreria.__AddFunction(C_PSTR, "decripta", C_PSTR);

var b = space(80000000);

//pattern di ricerca dei files in Wikimedia Commons

var myurl =

"https://commons.wikimedia.org/w/api.php?format=xml&action=query&list=cate gorymembers&cmtitle="+url+"&cmlimit=500";

b = libreria.decripta(myurl);

//Incapsulo i risultati nella variabile b

return b; }

77 3.1.4.1.1 La libreria esterna curlWikimedia.dll

La struttura della seguente libreria78 rispecchia quasi perfettamente quella utilizzata per il recupero delle informazioni provenienti da Google Images, con l’unica differenza che viene effettuato un parsing manuale all’interno della stringa che contiene il codice XML ricevuto dai server di Wikimedia. Le operazioni effettuate riguardano la ricerca delle stringhe contenenti i nomi dei file contenuti nelle gallerie d’arte e la concatenazione di essi in una stringa che verrà restituita al programma di XVR.

3.1.4.2 Accesso casuale ai file recuperati

Per questa modalità di recupero sono state dichiarate alcune funzionalità per l’accesso casuale dei file. La ragione di questa implementazione è dovuta al fatto che alcune gallerie d’arte contengono molte più informazioni di quante l’utente ne abbia richieste; è possibile infatti non recuperare alcune opere che si trovano in fondo alla lista, poiché l’algoritmo precedentemente implementato recupera soltanto le prime n informazioni a partire dall’inizio dei risultati. Per garantire una certa varietà dei risultati ottenuti è stato implementato questo meccanismo di accesso casuale alla lista dei file, in modo da ottenere risultati sempre diversi a seguito di una grande mole di informazioni.

78 https://pastebin.com/JCTK7jhM //stringa vuota std::string s; //pattern di ricerca std::string s2 = "File:"; //accedo al file XML std::istringstream f(readBuffer); //leggo il file XML riga per riga while (getline(f, s, '\"')) {

//trovo il file

if (s.find(s2) != std::string::npos) {

//converto il nome del file con la notazione percentuale char *output = curl_easy_escape(curl, s.c_str(), 0); //concateno le stringhe

strings = strings + output + "\n"; }

78

Vengono eseguite alcune operazioni per accedere in modo casuale alla lista dei file:

 Per prima cosa, viene convertita la stringa che contiene la lista dei file in un array, in modo che si possa accedere a un suo indice tramite un numero intero (che verrà generato casualmente):

 Successivamente viene dichiarata una stringa che conterrà tutti i numeri casuali generati dal programma e un contatore per gestire la quantità di volte in cui un numero casuale dovrà essere generato:

 Lla condizione per cui i numeri casuali vengano generati è che il numero delle opere d’arte trovate nella collezione sia maggiore rispetto al numero di opere richieste dall’utente:

 Vengsono generati tanti numeri casuali quanto il numero delle opere richieste dall’utente e viene controllato che nessun numero casuale venga inserito due volte. Successivamente si passa al recupero casuale dei file:

splitFiles = Split(

//Stringa contenente i files getFiles,

//parametro di splittamento "\n"

);

//L’ultimo indice dell’array corrisponde a una stringa vuota //E quindi va eliminato

adel(splitFiles, len(splitFiles)-1);

var randomString = ""; //stringa var contValidRandom =0; //contatore

if(len(splitFiles)>val(splitP[1])){

//istruzioni per generare casualmente dei numeri }

else{

//istruzioni per recuperare i metadati }

79

3.1.4.3 La funzione getWikiMeta()

Questa funzione serve per recuperare i file e i metadati contenuti in ciascun file dell’array preso in input. Viene caricata una libreria esterna denominata curlGetWikimediaUrl.dll e viene effettuata un’iterazione all’interno di un array, scaricando soltanto le informazioni dei file consistenti in immagini in formato JPEG. Alla fine di queste operazioni verrà restituita una stringa contenente i metadati relativi alle immagini.

//condizione valida finché non viene raggiunto il numero di opere richiesto dall’utente in splitP[1]

while(contValidRandom!=val(splitP[1])){ //numero random

var random = Rand(len(splitFiles));

//verifica che il numero generato non sia un doppione if(!str_contains(randomString, str(random)))

{

//concateno il numero generato in una stringa randomString = randomString + str(random)+ ","; //aggiorno il contatore

contValidRandom++; }

}

//converto la stringa con i numeri casuali in un array var randomArray = Split(

randomString,

","

);

//elimino l’ultimo elemento corrispondente a uno spazio vuoto adel(randomArray, len(randomArray)-1);

//creo un array per ospitare i files presi in modo casuale var randomFiles = array(0);

//recupero i files e li aggiungo all’array for(var i = 0; i<len(randomArray);i++){

aadd(randomFiles, splitFiles[val(randomarray[i])]); }

80 3.1.4.3.1 La libreria esterna curlGetWikimediaUrl.dll

In questa libreria esterna79 infatti sono presenti diverse istruzioni per il recupero di informazioni relative alle opere d’arte tramite l’utilizzo di un parser per oggetti JSON, ovvero la libreria RapidJSON. Rispetto a Google Images, nelle informazioni prese da Wikimedia Commons sono presenti i metadati relativi all’artista, al nome dell’opera e altre informazioni riguardo gli oggetti presenti nelle collezioni. Anche se si utilizza la stessa procedura per la richiesta HTTP, la struttura di questa libreria è più articolata rispetto a quella di Google e contiene dei metodi che permettono un’estrazione più mirata e intelligente. Le operazioni fondamentali sono le seguenti:

 Prima della HTTP Request vengono dichiarate delle variabili di tipo std::wstring80 in modo da poter contenere caratteri non appartenenti all’alfabeto latino:

79 https://pastebin.com/KF8nh6TZ

80 Questo tipo è riservato alle stringhe che contengono i caratteri wide, ovvero quei caratteri che contengono un

numero di informazioni maggiore di 8 bit.

function getWikiMeta(files){

var result = array(0); SETLOCALDIR();

//carico la libreria esterna

var libreria = CVmExternDLL("curlGetWikimediaUrl.dll"); //dichiaro la funzione della libreria

libreria.__AddFunction(C_PSTR, "decripta", C_PSTR); //accedo all’array contenente i files

for(var i = 0; i<len(files);i++){

//seleziono solo i files in formato JPEG if(str_contains(files[i], ".jpg")){

var b = space(80000000); //API di Wikimedia Commons var myurl =

"https://commons.wikimedia.org/w/api.php?action=query&prop=imageinfo&format =json&&iiprop=url%7Cextmetadata&iilimit=10&titles="+files[i]+"&iiurlwidth=8 00";

//Ricavo i metadati e li aggiungo all’array result b = libreria.decripta(myurl); aadd(result, b); } } return result; }

81

 Dopo aver effettuato la HTTP GET Request, viene restituito un oggetto JSON che viene subito parsato in modo da accedere ai diversi nodi:

 Seguendo l’architettura dei metadati, il nodo figlio è un numero casuale che corrisponde all’identificativo della pagina; è necessario scorrere quindi i figli del nodo e acquisire il valore sconosciuto a priori per poter accedere ai metadati:

//metodo per convertire una std::string in std::wstring

std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; //wstrings relative ai metadati dell’opera

std::wstring wstrings; --> stringa finale std::wstring wUrl; --> stringa del collegamento std::wstring wArtist; --> stringa dell’artista std::wstring wTitle; --> stringa del titolo std::wstring wDate; --> stringa della data

std::wstring wDesc; --> stringa della descrizione

//converto l’oggetto JSON in un array di caratteri const char* json = readBuffer.c_str();

//Instanzio l’oggetto rapidjson Document document;

//parso l’oggetto JSON document.Parse(json); //accedo al nodo principale

const Value& a = document["query"]["pages"];

//scorro la lista dei figli

for (Value::ConstMemberIterator itr = a.MemberBegin(); itr != a.MemberEnd(); ++itr) {

const char* nameObject;

//acquisisco il numero casuale nameObject = itr->name.GetString(); //memorizzo il valore

pageId = nameObject; }

82

 Si passa adesso all’acquisizione dei metadati; mentre per il campo artista, tiolo e collegamento diretto c’è la certezza della presenza dei metadati, così non è per la data di creazione né per la descrizione, in quanto non tutti i metadati sono sempre inseriti dagli utenti:

 Prima di acquisire i metadati relativi all’artista è necessario effettuare una pulizia delle informazioni in quanto sono spesso presenti tracce di codice HTML; per pulire le stringhe c’è la funzione cleanMetadata() che si occupa di rimuovere tutti i tag descrittivi preservando i nomi e i titoli originali:

//accedo al nodo che contiene i metadati const Value& b = a[pageId]["imageinfo"]; //accedo al nodo dell’URL

url = b[0]["thumburl"].GetString(); //converto l’URL in una wstring wUrl = converter.from_bytes(url); ...

//verifico se c’è la presenza del nodo contenente la data if (c.HasMember("DateTimeOriginal")) {

date =

b[0]["extmetadata"]["DateTimeOriginal"]["value"].GetString(); wDate = converter.from_bytes(date);

}

//operazioni se il nodo non è presente else {

date = "No avaiable date"; wDate = none;

}

std::string cleanMetadata(std::string input) { std::string strings = input;

//pattern che riconosce i tag HTML std::regex reg("(<[^>]*>)"); std::smatch m;

if (std::regex_search(strings, m, reg)) { //rimozione del tag se presente

strings = std::regex_replace(strings, reg, ""); } else { strings = strings; } return strings; }

83

 Tutte le informazioni vengono concatenate in una stringa, la quale viene poi convertita in un array di caratteri e restituito al programma di XVR:

Con questo si conclude il paragrafo relativo al recupero delle informazioni da Wikimedia Commons. Nel paragrafo successivo si tratterà il recupero delle informazioni provenienti da Europeana.