Pubblicato il Pubblicato in Applicazioni, Playlist

Play List Prima Parte.

Inizio con una delle ultime attività di sviluppo che mi sono servite a rinverdire la programmazione. Si tratta di una applicazione che mi ritorna utile, magari anche a voi. La creazione di una play list.

In questi giorni privi di ogni attività concreta, mi sono ritrovato a riaccendere la TV senza trovare riscontro di argomenti interessanti. Non che non ce ne siano, ma la televisione non ne parla o almeno non ne parla in modo da poter essere credibile. Per cui ho iniziato a riordinare i dischi pieni di roba che ho accumulato nel tempo. Ma nel frattempo volevo avere un sottofondo che non fossero sirene di ambulanze, grida di esauriti per strada, il parlare del vicino che, viste le mura di carta velina, si sentiva come se fosse dentro casa (provate ad immaginare cosa possa essere poi lo squillo del suo telefonino o la presenza di una sua ospite il cui tono della voce è tipicamente alto…), l’insopportabile rumore del traffico urbano. Quindi, ho cercato le “mie” musiche e i films che avevo sparsi a destra e a manca in modo da usarli come sottofondo. Proprio la ricerca ed il tempo necessario mi ha dato l’idea iniziale. Mi sono scritto quattro righe di codice in PHP (le altre le ho copiate da qui e da la) per la scansione dei dischi alla ricerca dei file in argomento. Certo a quel punto, visto che c’ero in attività, mi sono fatto anche le tabelle su MySQL.

Prima di tutto ho avviato Il WampServer (che avevo installato tempo fa) ed iniziato a memorizzare su DB i dati dei file: percorso, titolo, dimensione, e data. Inizia così un’intesa sfida tra la quantità di spazio sui dischi, quantità dei dischi ed il tempo disponibile, oltre che della mia pazienza…

La torre di Hanoi può essere anche un gioco rilassante, ma quando lo fai con i dati, con lo spazio sui dischi, con i cavi dei dischi, con lo spazio di casa (poco così come quello dei dischi) e col tempo a disposizione,  diventa un esercizio degno un di monaco tibetano .

torre di hanoiDopo tante tribolazioni e smadonnamenti, sono riuscito ad avere tutti i film in una cartella di un solo disco e tutti i brani musicali in un’altra cartella dello stesso disco, ma visto gli sviluppi, perché non farlo anche per le ISO, i siti, le applicazioni e le foto?… in tutto questo, vuoi che non mi venga il tarlo del guasto hardware e addio ai film, ai brani musicali ed al tempo perduto e all’anima dei ….? Dimentico forzatamente la possibile evenienza.

 

Ricapitolando:

1) scan delle periferiche. PHP ha, di default, dei tempi di esecuzione ragionevolmente bassi, visto che di uno script o linguaggio (vedete un pò voi come definirlo) interpretato si tratta. A me interessava avere un’interfaccia web dell’applicazione. Quindi devo alzare i tempi di esecuzione in modo tale che, leggendo le periferiche anche via USB, non vada in time-out e fallisca miseramente lo scan.

 

Aumento e ripristino del tempo di esecuzione

// imposto valore massimo tempo di esecuzione alto in modo da permettere l'eventuale lunga scansione 
$valiniz = ini_get('max_execution_time'); // salvo il valore attuale per successivo recupero 
ini_set('max_execution_time',374000); // imposto nuovo valore del tempo di esecuzione (altissimo) 
.... 
.... // qua in mezzo ci va il codice che segue 
.... 

ini_set('max_execution_time',$valiniz); // reimposto al valore precedente il tempo di esecuzione 

 

Lo scan della periferica

Lancio la funzione di scan ricorsiva delle cartelle. Questa funzione non l’ho scritta io, ma in parte l’ho modificata per le mie necessità.


....
....
....
// qui ho messo un percorso di comodo, ma potrebbe essere qualsiasi
// sotto windows ho riscontrato un malfunzionamento nell'uso dello Backslash 
// anche usato doppio come indicano quelli di PHP
// Mentre col (Forward) Slash non ho avuto problemi di sorta anche sotto windzoz
// ($path potrebbe essere uguale a "/root" o $path="c:/", $path = "f:/musica/", $path = "H:/")
$path = "/home/"; 

// scansione della cartella prescelta (anche intero disco)
// a$ e' un vettore con l'elenco dei file che interessano
// vedremo nella funzione come sceglie
$a=dirInfoReGet($path);

// ciclo principale per l'inserimento di ogni titolo
foreach($a as $file){
	
        // estrapolo dal file i suoi dati
        // il percorso, il nome poi definito titolo
        // la dimensione e la data che viene convertita
        // nel formato gestibile dal MySQL
	$percorso = dirname($file);
	$titolo = basename($file);
	$dimensione = abs(round(filesize($file)/1024));
	$data = date("Y/m/d H:i:s", filemtime($file));
		
        // sel al variabile $crc è impostata ad "on"	
	// calcolo il crc32b (richiede molto tempo per ogni file)
        // diversamente lo lascio vuoto
	if($crc == "on") $calccrc = hash_file('crc32b', $file); else $calccrc = "";
			
	// aggiorno base dati
        // Qui le variabili passate come argomenti della
        // funzione sono auto esplicative tranne $calccrcr che 
        // in definitiva è il crc32b calcolato o vuoto
        // (*) vedi il N.B. in fondo al riquadro
	$inseriti = basedati($titolo, $percorso, $dimensione, $durata, $data, $calccrc);

}

....
....
....

////////////////////// ATTENZIONE!! //////////////////////////
// le funzioni che seguono non ha bisogno di di stare      //
// all'interno della ridefinizione del tempo di esecuzione //
////////////////////////////////////////////////////////////

//////////// dirInfoReGet() ///////////////////////////////////////////////
// questa e' la funzione che effettivamente fa lo scan della periferica (glob_recursive())
// Lei si occupa di distinguere quali file mi interessano e quali no
// lo fa distinguendo le estensioni dei file
function dirInfoReGet($path){
	// forked from http://php.net/manual/en/function.glob.php
	// di sharshun.aliaksandr@gmail.com
        // come vedete dall'URL è presa dagli esempi del manuale on line di PHP
        // ma ho aggiunto del mio
	
    // richiamo della funzione di scan fisico della periferica
    $a=glob_recursive($path."*.*");
    $ar=glob_recursive($path."**/**");

    // creo vettore unico dell'elenco dei files
    $arr=array_unique(array_merge($a, $ar));
    $trovati = array();
	// la versione iniziale prevedeva di usare un vettore fisso per le estensioni
        // io l'ho modificato in modo che prendesse le estensioni da una tabella 
        // che viene letta e restituita dalla funzione estensioni()

	// $include = array("avi", "mkv", "mp4", "mpg", "ifo", "vob", "mpeg", "m4v");

	$include = estensioni(); // la vedremo piu' avanti

    // una volta ottenuti l'intera lista dei file e le estensioni che mi ritornano utili
    // inizio il ciclo di sfoltimento, filtro l'elenco con le estensioni che mi servono
    foreach ($arr as $v) {
        if (!is_dir($v)) { // considero solo i file non le cartelle che comunque vengono restituite 
            // estrapolo l'estensione del file
	    $ext = substr($v, strrpos($v,'.', 0)+1,(strlen($v) - strrpos($v,'.', 0)) );	
            // qui, dopo aver tolto gli spazi eccedenti e ridotto in minuscolo l'estensione del file, 
            // la confronto con l'elenco che ho nella tabella
	    if (in_array(trim(strtolower($ext)),$include){  
              // se trovo una corrispondenza, popolo il vettore $trovati
	      $trovati[] = $v;
	    } else { // lo uso per debuggare
              // diversamente metto gli esclusi in un vettore di comodo, ma potrei anche non farlo
	      // $arra['esclusi'][]=$v;
	    }
        }
    }

    // ordino il vettore
    sort($trovati);
    // mando l'elenco
    return $trovati;
}

//////////////// glob_recursive() ///////////////////////////////////////////
// questa funzione e' ricorsiva (dal nome si evince facilmente)
// ovvero richiama se stessa per eseguire un uguale procedimento
// questa legge le periferiche con la funzione nativa di PHP glob()
// $pattern è cio' che gli viene richiesto di cercare
// $flag ha la funzione di determinare il livello di ricorsività
// $files è un vettore con i file ritrovati secondo la richiesta del $pattern
function glob_recursive($pattern, $flags = 0){
// forked from https://github.com/rodurma/PHP-Functions/
// blob/master/glob_recursive.php

  $files = glob($pattern, $flags);
       
  foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir){
    $files = array_merge($files, glob_recursive($dir.'/'.basename($pattern), $flags));
  }
  return $files;
}

N.B.: la funzione basedati() è presente nella seconda parte di questo articolo.

Il “retrieve” delle estensioni

Adesso tocca alle funzioni che interagiscono col DB, insomma lettura e scrittura sulle tabelle. La lettura, in questo caso, è per le estensioni in modo che siamo noi a decidere, dall’interfaccia utente, quale estensione considerare. Consultare la tabella dei titoli dei files, in modo da controllare l’eventuale presenza di un inserimento precedente del titolo. La scrittura è per l’inserimento del nuovo titolo. Io lo indico come titolo perché lo associo al titolo di un brano musicale o di un video, ma di fatto lo si può utilizzare per altri scopi (archivio documenti, fogli di calcolo e chi più ne ha, più ne metta). Qui di seguito la funzione di lettura delle estensioni.

/////////////// estensioni() //////////////////////////////////////////////
// ritorna l'elenco delle estensioni in archivio da 
// considerare per l'inserimento in lista (titoli)
function estensioni(){
	$estensioni = array();
        // faccio l'include del file che contiene i dati di accesso 
        // al DB (databse, utente, password, host)
	require "config.php"; 
        // definisco la query di ricerca in SQL 
        // la tabella ext ha solo tre campi oltre al suo id
        // tipo, descr e genere
        // in tipo scrivo l'estensione senza il punto (tipo di estensione)
        // in descr la relativa descrizione (non obbligatoria)
        // genere è n campo che associa un'altra tabella
        // ovvero quella che specifica che genere di estensione sia
        // avi = video, mp3 = audio, doc = documento, xls = foglio di calcolo, ...
	$query = 'SELECT * FROM ext ORDER BY tipo';
        // eseguo la query
	if ($result = $mysqli->;query($query)) {
                // ciclo sulla tabella
		while ($row = $result->fetch_row()) {
                        // popolo il vettore estensioni con valori privati da spazi e minuscoli
			$estensioni[] = trim(strtolower($row[1]));
		}
		/* libero il result set */
		$result->close();
	}	
	/* chiudo la connessione col DB */
	$mysqli->close();

        // ritorno il vettore popolato o meno
	return $estensioni;
}

 

Fine della prima parte

Siamo giunti alla fine della prima parte di questa Play List. Credo che al di la del titolo, abbia affrontato diversi argomenti riguardanti la programmazione in PHP. L’argomento è risultato più lungo di quanto pensassi. Spero che sia altrettanto chiaro e fruibile. Qualunque aspetto vogliate affrontare in merito, commentate e l’affronteremo assieme. Adesso vi rimando alla seconda parte.

Prima Parte | Seconda Parte | Terza Parte | Quarta Parte | Quinta Parte | Sesta Parte | Settima Parte | Ottava Parte | Nona Parte

Rispondi