Bookmarklet'; $column_width='width:47%'; if ($public){$bookmarklet='';$column_width='width:97%';} if (!creer_dossier($GLOBALS['data_folder'], TRUE)) { die('Cant create '.$GLOBALS['data_folder'].' folder.'); } if (!creer_dossier($GLOBALS['private_data_folder'], TRUE)) { die('Cant create '.$GLOBALS['private_data_folder'].' folder.'); } if (!creer_dossier($GLOBALS['public_data_folder'], TRUE)) { die('Cant create '.$GLOBALS['public_data_folder'].' folder.'); } // // BEGIN SCRIPT // #TODO /* - remplacer les liens relatifs par les liens absolus (ne chercher que les liens relatifs, uri) - gestion des pages DL (classement ?) - gestion de la taille max des fichiers à télélcharger */ // init // url not yet retrieved $GLOBALS['done']['d'] = FALSE; if (!$public){ // Get URL to save. if (!empty($_GET['q'])) { $url = htmlspecialchars($_GET['q']); if (strpos($url, '://') === false) { $url = 'http://'.$url; } $GLOBALS['url'] = $url; $url_p = url_parts(); // retrieve the file main HTML file $GLOBALS['main_page_data'] = get_external_file($GLOBALS['url'], 6); if ($GLOBALS['main_page_data'] === FALSE) { die('error retrieving external main page'); } else { // crée le nouveau dossier basé sur le TS. $new_folder = date('Y-m-d-H-i-s'); if (!creer_dossier($GLOBALS['default_data_folder'].'/'.$new_folder) === TRUE ) { die('error creating data folder'); } else { $GLOBALS['target_folder'] = $GLOBALS['default_data_folder'].'/'.$new_folder; } $liste_css = array(); // parse le fichier principal à la recherche de données à télécharger $files = list_retrievable_data($GLOBALS['url'], $GLOBALS['main_page_data']); // les récupère et les enregistre. //echo '
';print_r($files);die();
			foreach ($files as $i => $file) {
				if ($data = get_external_file($file['url_fichier'], 3) and ($data !== FALSE) ) {
					// CSS files need to be parsed aswell
					if ($file['type'] == 'css') {
						$liste_css[] = $file;
					}
					else {
						file_put_contents($GLOBALS['target_folder'].'/'.$file['nom_destination'], $data);
					}
				}
			}
			// remplace juste les liens  relatifs vers des liens absolus
			absolutes_links($GLOBALS['main_page_data']);

			// enregistre le fichier HTML principal
			file_put_contents($GLOBALS['target_folder'].'/'.'index.html', $GLOBALS['main_page_data']);

			// récupère le titre de la page
			// cherche le charset spécifié dans le code HTML.
			// récupère la balise méta tout entière, dans $meta
			preg_match('##Usi', $GLOBALS['main_page_data'], $meta);

			// si la balise a été trouvée, on tente d’isoler l’encodage.
			if (!empty($meta[0])) {
				// récupère juste l’encodage utilisé, dans $enc
				preg_match('#charset="?(.*)"#si', $meta[0], $enc);
				// regarde si le charset a été trouvé, sinon le fixe à UTF-8
				$html_charset = (!empty($enc[1])) ? strtolower($enc[1]) : 'utf-8';
			} else { $html_charset = 'utf-8'; }
			// récupère le titre, dans le tableau $titles, rempli par preg_match()
			preg_match('#(.*)#Usi', $GLOBALS['main_page_data'], $titles);
			if (!empty($titles[1])) {
				$html_title = trim($titles[1]);
				// ré-encode le titre en UTF-8 en fonction de son encodage.
				$title = ($html_charset == 'iso-8859-1') ? utf8_encode($html_title) : $html_title;
			// si pas de titre : on utilise l’URL.
			} else {
				$title = $url;
			}


			// récupère, parse, modifie & enregistre les fichier CSS (et les fichiés liés)
			$n = 0;
			$count = count($liste_css);
			while ( $n < $count ) {
				$i = $n;
				$file = $liste_css[$i];
				if ($data = get_external_file($file['url_fichier'], 3) and ($data !== FALSE) ) {
					if (preg_match('#(css|php|txt|html|xml|js)#', $file['url_fichier']) ) {

						$matches_url = array();
						preg_match_all('#url\s*\(("|\')?([^\'")]*)(\'|")?\)#i', $data, $matches_url, PREG_SET_ORDER);
						$matches_url2 = array();
						preg_match_all('#@import\s*(url\()?["\']?([^\'"\(\);]*)["\']?\)?([^;]*);#i', $data, $matches_url2, PREG_SET_ORDER);

						$matches_url = array_merge($matches_url2, $matches_url);
				
						// pour chaque URL/URI
						foreach ($matches_url as $j => $valuej) {

							if (preg_match('#^data:#', $matches_url[$j][2])) break; // if BASE64 data, dont download.

							// get the filenam (basename)
							$nom_fichier = (preg_match('#^(ht|f)tps?://#', $matches_url[$j][2])) ? pathinfo(parse_url($matches_url[$j][2], PHP_URL_PATH), PATHINFO_BASENAME) : pathinfo($matches_url[$j][2], PATHINFO_BASENAME);

							// get the URL. For URIs, uses the GLOBALS[url] tu make the URL
							// the files in CSS are relative to the CSS !
							if (preg_match('#^https?://#', $matches_url[$j][2])) {
								$url_fichier = $matches_url[$j][2];
							}
							elseif (preg_match('#^/#', $matches_url[$j][2])) {
								$url_fichier = $url_p['s'].'://'.$url_p['h'].$matches_url[$j][2];
							}
							else {
								$url_fichier = substr($file['url_fichier'], 0, -strlen($file['nom_fich_origine'])).$matches_url[$j][2];
							}
							// new rand name, for local storage.
							$nouveau_nom = rand_new_name($nom_fichier);
							$add = TRUE;

							// avoids downloading the same file twice. (yes, we re-use the same $retrievable ($files), why not ?)
							foreach ($files as $key => $item) {
								if ($item['url_fichier'] == $url_fichier) {
									$nouveau_nom = $item['nom_destination'];
									$add = FALSE;
									break;
								}
							}

							// if we do download, add it to the array.
							if ($add === TRUE) {
								$files_n = array(
									'url_origine' => $matches_url[$j][2],
									'url_fichier' => $url_fichier,
									'nom_fich_origine' => $nom_fichier,
									'nom_destination' => $nouveau_nom
									);
								$files[] = $files_n;
								$liste_css[] = $files_n;
							}

							// replace url in CSS $data
							$data = str_replace($matches_url[$j][2], $nouveau_nom, $data);
							// echo $nouveau_nom."
\n"; if (!preg_match('#(css|php|txt|html)#', $file['url_fichier']) ) { if (FALSE !== ($f = get_external_file($url_fichier, 3)) ) { file_put_contents($GLOBALS['target_folder'].'/'.$nouveau_nom, $f); } } } } // don't forget to save data file_put_contents($GLOBALS['target_folder'].'/'.$file['nom_destination'], $data); } $n++; $count = count($liste_css); } // enregistre un fichier d’informations concernant la page (date, url, titre) $info = ''; $info .= 'URL="'.$GLOBALS['url'].'"'."\n"; $info .= 'TITLE="'.$title.'"'."\n"; $info .= 'DATE="'.time().'"'."\n"; file_put_contents($GLOBALS['target_folder'].'/'.'index.ini', $info); // $GLOBALS['done']['d'] = 'ajout'; $GLOBALS['done']['lien'] = $GLOBALS['target_folder'].'/'; } } // in case of delete an entry if (isset($_GET['suppr']) and $torem = $_GET['suppr'] and $torem != '') { $torem = htmlspecialchars($_GET['suppr']); /* $liste = scandir($GLOBALS['data_folder']); // listage des dossiers de data. $nb_fichier = count($liste); for ($i = 0 ; $i < $nb_fichier ; $i++) { if ($liste[$i] == $torem and !($liste[$i] == '..' or $liste[$i] == '.')) {*/ // the folder exists and can be removed: // included files first (noway doing it like "rmdir -R" :/) if (is_dir($_GET['suppr'])){ $sousliste = scandir($_GET['suppr']); // listage des dossiers de data. $nb_sousfichier = count($sousliste); for ($j = 0 ; $j < $nb_sousfichier ; $j++) { if (!($sousliste[$j] == '..' or $sousliste[$j] == '.')) { unlink($_GET['suppr'].'/'.$sousliste[$j]); } } // then the folder itself. if (TRUE === rmdir($_GET['suppr'])) { $GLOBALS['done']['d'] = 'remove'; } } header("location: index.php"); } // to private if (isset($_GET['toprivate']) and $torem = $_GET['toprivate'] and $torem != '') { $torem = htmlspecialchars($_GET['toprivate']); if (is_dir($GLOBALS['public_data_folder'].'/'.$_GET['toprivate'])){ rename ($GLOBALS['public_data_folder'].'/'.$_GET['toprivate'],$GLOBALS['private_data_folder'].'/'.$_GET['toprivate']); header("location: index.php"); } } // to public if (isset($_GET['topublic']) and $torem = $_GET['topublic'] and $torem != '') { $torem = htmlspecialchars($_GET['topublic']); if (is_dir($GLOBALS['private_data_folder'].'/'.$_GET['topublic'])){ rename ($GLOBALS['private_data_folder'].'/'.$_GET['topublic'],$GLOBALS['public_data_folder'].'/'.$_GET['topublic']); header("location: index.php"); } } } // end of private admin acces function url_parts() { $url_p['s'] = parse_url($GLOBALS['url'], PHP_URL_SCHEME); $url_p['s'] = (is_null($url_p['s'])) ? '' : $url_p['s']; $url_p['h'] = parse_url($GLOBALS['url'], PHP_URL_HOST); $url_p['h'] = (is_null($url_p['h'])) ? '' : $url_p['h']; $url_p['p'] = parse_url($GLOBALS['url'], PHP_URL_PORT); $url_p['p'] = (is_null($url_p['p'])) ? '' : ':'.$url_p['p']; $url_p['pat'] = parse_url($GLOBALS['url'], PHP_URL_PATH); $url_p['pat'] = (is_null($url_p['pat'])) ? '' : $url_p['pat']; $url_p['file'] = pathinfo($url_p['pat'], PATHINFO_BASENAME); return $url_p; } // // Gets external file by URL. // Make a stream context (better). // function get_external_file($url, $timeout) { $context = stream_context_create(array('http'=>array('timeout' => $timeout))); // Timeout : time until we stop waiting for the response. $data = @file_get_contents($url, false, $context, -1, 4000000); // We download at most 4 Mb from source. if (isset($data) and isset($http_response_header) and isset($http_response_header[0]) and (strpos($http_response_header[0], '200 OK') !== FALSE) ) { return $data; } else { return FALSE; } } // // CREATE FOLDER // function creer_dossier($dossier, $indexfile = FALSE) { if ( !is_dir($dossier) ) { if (mkdir($dossier, 0777, TRUE) === TRUE) { chmod($dossier, 0777); if ($indexfile == TRUE) touch($dossier.'/index.html'); // make a index.html file : avoid the possibility of listing folder's content return TRUE; } else { return FALSE; } } return TRUE; // if folder already exists } // // PARSE TAGS AND LISTE DOWNLOADABLE CONTENT IN ARRAY // Also modify html source code to replace absolutes URLs with local URIs. // function list_retrievable_data($url, &$data) { $url_p = url_parts(); $retrievable = array(); // cherche les balises 'link' qui contiennent un rel="(icon|favicon|stylesheet)" et un href="" // (on ne cherche pas uniquement le "href" sinon on se retrouve avec les flux RSS aussi) $matches = array(); preg_match_all('#<\s*link[^>]+rel=["\'][^"\']*(icon|favicon|stylesheet)[^"\']*["\'][^>]*>#Si', $data, $matches, PREG_SET_ORDER); // dans les link avec une icone, stylesheet, etc récupère l’url. foreach($matches as $i => $key) { $type = (strpos($key[1], 'stylesheet') !== FALSE) ? 'css' : 'other'; if ( (preg_match_all('#(href|src)=["\']([^"\']*)["\']#i', $matches[$i][0], $matches_attr, PREG_SET_ORDER) === 1) ) { $retrievable = add_table_and_replace($data, $retrievable, $matches[$i][0], $matches_attr[0][2], $url_p, $type); } } // recherche les images, scripts, audio & videos HTML5. // dans les balises, récupère l’url/uri contenue dans les src="". // le fichier sera téléchargé. // Le nom du fichier sera modifié pour être unique, et sera aussi modifié dans le code source. $matches = array(); preg_match_all('#<\s*(source|audio|img|script|video)[^>]+src="([^"]*)"[^>]*>#Si', $data, $matches, PREG_SET_ORDER); foreach($matches as $i => $key) { if (preg_match('#^data:#', $matches[$i][2])) break; $retrievable = add_table_and_replace($data, $retrievable, $matches[$i][0], $matches[$i][2], $url_p, 'other'); } // Dans les balises