Browse Source

Merge pull request #36 from ldleman/importExport

Oki doki :)
Idleman 8 years ago
parent
commit
72af7742b9
4 changed files with 110 additions and 95 deletions
  1. 3 1
      Feed.class.php
  2. 0 50
      Functions.class.php
  3. 69 14
      Opml.class.php
  4. 38 30
      action.php

+ 3 - 1
Feed.class.php

@@ -47,7 +47,9 @@ class Feed extends MysqlEntity{
 
 		$feed->set_useragent('Mozilla/4.0 Leed (LightFeed Agrgegator) '.VERSION_NAME.' by idleman http://projet.idleman.fr/leed');
 
-		$feed->init();
+		$feed->init(); // advice from xrogaan (https://github.com/ldleman/Leed/issues/4)
+		// You probably want to check if $feed->error; isn't NULL after https://github.com/ldleman/Leed/blob/master/Feed.class.php#L50
+
 		$feed->handle_content_type();
 		
 

+ 0 - 50
Functions.class.php

@@ -318,56 +318,6 @@ class Functions
 		return $allFiles;
 	}
 
-
-
-		public static function recursiveImportXmlOutline($level,$folderId){
-			$folderManager = new Folder();
-			$feedManager = new Feed();
-			$report= '';
-
-			
-			foreach($level as $item){
-                    // Cela varie selon les implémentations d'OPML.
-                    $feedName = ( $item['text'] ? 'text' : 'title' );
-					if(isset($item->outline[0])){
-						$folder = $folderManager->load(array('name'=>$item[$feedName]));
-						$folder = (!$folder?new Folder():$folder);
-						$folder->setName($item[$feedName]);
-						$folder->setParent(($folderId==1?-1:$folderId));
-						$folder->setIsopen(0);
-						if($folder->getId()== '') $folder->save();
-						$report.= '[DOSSIER] Creation '.$item[$feedName]."\n";
-						echo '<li>[DOSSIER] Creation '.$item[$feedName].'</li>';
-						echo str_pad('',4096)."\n";ob_flush();flush();
-						$report.= Functions::recursiveImportXmlOutline($item->outline,$folder->getId())."\n";
-					}else{
-					
-
-						$newFeed = $feedManager->load(array('url'=>$item[0]['xmlUrl']));
-						$newFeed = (!$newFeed?new Feed():$newFeed);
-
-						if($newFeed->getId()==''){
-							$newFeed->setName($item[0][$feedName]);
-							$newFeed->setUrl($item[0]['xmlUrl']);
-							$newFeed->setDescription($item[0]['description']);
-							$newFeed->setWebsite($item[0]['htmlUrl']);
-							$newFeed->setFolder($folderId);
-							$newFeed->save();
-
-							$report.= '[FLUX] Creation '.$item[0][$feedName]."... \n";
-							$parseResult = '[FLUX] Parsage du flux '.$newFeed->getName().': '.($newFeed->parse()?'OK':'NOK')."\n";
-							$report.= $parseResult;
-							echo '<li>'.$parseResult.'</li>';
-						}else{
-							$report.= '[FLUX] '.$item[0][$feedName].' deja existant, aucune action...'."\n";
-							echo '<li>Flux '.$item[0][$feedName].' deja existant, aucune action...</li>';
-						}
-						echo str_pad('',4096)."\n";ob_flush();flush();
-					}
-			}
-			return $report;
-		}
-
 		function stripAccents($string){
 			return strtr(html_entity_decode($string),'àáâãäçèéêëìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ',
 		'aaaaaceeeeiiiinooooouuuuyyAAAAACEEEEIIIINOOOOOUUUUY');

+ 69 - 14
Opml.class.php

@@ -10,10 +10,13 @@ require_once("common.php");
  
 class Opml  {
 
+	// liens déjà connus, déjà abonnés, au moment de l'importation
+	public $alreadyKnowns = array();
+
 	/**
 	 * Met à jour les données des flux.
 	 */
-	function _update() {
+	protected function update() {
 		global $feedManager, $folderManager;
 		$this->feeds = $feedManager->populate('name');
 		$this->folders = $folderManager->loadAll(array('parent'=>-1),'name');
@@ -22,30 +25,32 @@ class Opml  {
 	/**
 	 * Convertit les caractères qui interfèrent avec le XML
 	 */
-	function _pourXml($string) {
+	protected function escapeXml($string) {
 		return htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
 	}
 
 	/**
 	 * Exporte récursivement les flux.
 	 */
-	function _export($folders, $niveauIndent=0) {
-		$_ = ''; for($i=0;$i<$niveauIndent;$i++) $_.="\t";
+	protected function exportRecursive($folders, $identLevel=0) {
+		$_ = ''; for($i=0;$i<$identLevel;$i++) $_.="\t";
 		$xmlStream = '';
 		foreach($folders as $folder) {
 			// Pas utilisé, vu qu'il n'y a qu'un seul niveau de dossiers.
-  			$xmlStream .= $this->_export($folder->getFolders(), $niveauIndent+1);
+  			$xmlStream .= $this->exportRecursive(
+				$folder->getFolders(), $identLevel+1
+			);
 			$feeds = $folder->getFeeds();
 			if (empty($feeds)) continue;
-			$text = $this->_pourXml($folder->getName());
-			$title = $this->_pourXml($folder->getName());
+			$text = $this->escapeXml($folder->getName());
+			$title = $this->escapeXml($folder->getName());
 			$xmlStream .= "{$_}<outline text='$text' title='$title' icon=''>\n";
 			foreach($feeds as $feed){
-				$url = $this->_pourXml($feed->getUrl());
-				$website = $this->_pourXml($feed->getWebsite());
-				$title = $this->_pourXml($feed->getName());
+				$url = $this->escapeXml($feed->getUrl());
+				$website = $this->escapeXml($feed->getWebsite());
+				$title = $this->escapeXml($feed->getName());
 				$text = $title;
-				$description = $this->_pourXml($feed->getDescription());
+				$description = $this->escapeXml($feed->getDescription());
 				$xmlStream .= "{$_}{$_}<outline "
 				."xmlUrl='$url' "
 				."htmlUrl='$website' "
@@ -63,7 +68,7 @@ class Opml  {
 	 * Exporte l'ensemble des flux et sort les en-têtes.
 	 */
 	function export() {
-		$this->_update();
+		$this->update();
 		$date = date('D, d M Y H:i:s O');
 		$xmlStream = "<?xml version='1.0' encoding='utf-8'?>
 <opml version='2.0'>
@@ -74,16 +79,66 @@ class Opml  {
 		<dateCreated>$date</dateCreated>
 	</head>
 	<body>\n";
-		$xmlStream .= $this->_export($this->folders, 2);
+		$xmlStream .= $this->exportRecursive($this->folders, 2);
 		$xmlStream .= "\t</body>\n</opml>\n";
 		return $xmlStream;
 	}
 
+	protected function importRec($folder, $folderId=1){
+		$folderManager = new Folder();
+		$feedManager = new Feed();
+		foreach($folder as $item) {
+			// Cela varie selon les implémentations d'OPML.
+			$feedName = $item['text'] ? 'text' : 'title';
+			if (isset($item->outline[0])) { // un dossier
+				$folder = $folderManager->load(array('name'=>$item[$feedName]));
+				$folder = (!$folder?new Folder():$folder);
+				$folder->setName($item[$feedName]);
+				$folder->setParent(($folderId==1?-1:$folderId));
+				$folder->setIsopen(0);
+				if($folder->getId()=='') $folder->save();
+				$this->importRec($item->outline,$folder->getId());
+			} else { // un flux
+				$newFeed = $feedManager->load(array('url'=>$item[0]['xmlUrl']));
+				$newFeed = (!$newFeed?new Feed():$newFeed);
+				if($newFeed->getId()=='') {
+					/* Ne télécharge pas à nouveau le même lien, même s'il est
+					   dans un autre dossier. */
+					$newFeed->setName($item[0][$feedName]);
+					$newFeed->setUrl($item[0]['xmlUrl']);
+					$newFeed->setDescription($item[0]['description']);
+					$newFeed->setWebsite($item[0]['htmlUrl']);
+					$newFeed->setFolder($folderId);
+					$newFeed->save();
+					// $newFeed->parse();
+				} else {
+					$this->alreadyKnowns[]= (object) array(
+						'description' => $item[0]['description'],
+						'xmlUrl' => $item[0]['xmlUrl']
+					);
+				}
+			}
+		}
+	}
+	
 	/**
 	 * Importe les flux.
 	 */
 	function import() {
-		throw new Exception('À faire.');
+		require_once("SimplePie.class.php");
+		$file = $_FILES['newImport']['tmp_name'];
+		$internalErrors = libxml_use_internal_errors(true);
+		$xml = @simplexml_load_file($file);
+		$errorOutput = array();
+		foreach (libxml_get_errors() as $error) {
+			$errorOutput []= "{$error->message} (line {$error->line})";
+		}
+		libxml_clear_errors();
+		libxml_use_internal_errors($internalErrors);
+		if (!empty($xml) && empty($errorOutput)) {
+			$this->importRec($xml->body->outline);
+		}
+		return $errorOutput;
 	}
 
 }

+ 38 - 30
action.php

@@ -187,37 +187,45 @@ switch ($_['action']){
 	break;
 
 	case 'importFeed':
-				require_once("SimplePie.class.php");
-				if (ob_get_level() == 0) ob_start();
-				ignore_user_abort(true);
-			
-				echo '<link rel="stylesheet" href="templates/marigolds/css/style.css"><ul style="font-family:Verdana;">';
-				echo str_pad('',4096)."\n";ob_flush();flush();
-				
-
-				if($myUser==false) exit('Vous devez vous connecter pour cette action.');
-				if(isset($_POST['importButton'])){
-			
-				echo '<li>Lecture du fichier OPML...</li>';
-				echo str_pad('',4096)."\n";ob_flush();flush();
-				$xml = simplexml_load_file($_FILES['newImport']['tmp_name']);
-				$report = 'Import de flux depart : '.date('d/m/Y H:i:s')."\n";
-				echo '<li>Parsage recursif du fichier OPML...</li>';
-				echo str_pad('',4096)."\n";ob_flush();flush();
-				$report .= Functions::recursiveImportXmlOutline($xml->body->outline,1);
-				$report .= 'Import de flux fin : '.date('d/m/Y H:i:s')."\n";
-				echo '<li>Création des logs d\'imports....</li>';
-				echo str_pad('',4096)."\n";ob_flush();flush();
-				file_put_contents('./logs/Import du '.date('d-m-Y').'.log', $report ,FILE_APPEND);
-				echo '<li>Import des flux terminé ( '.number_format(microtime(true)-$start,3).' secondes ).</li>';
-				echo str_pad('',4096)."\n";ob_flush();flush();
-
-				echo '</ul>';
-				echo str_pad('',4096)."\n";ob_flush();flush();
-
-				ob_end_flush();
-				//header('location: ./settings.php');
+		if($myUser==false) exit('Vous devez vous connecter pour cette action.');
+		if(!isset($_POST['importButton'])) break;
+		$opml = new Opml();
+		echo "<h3>Importation</h3><p>En cours...</p>\n";
+		$errorOutput = $opml->import($_FILES['newImport']['tmp_name']);
+		if (empty($errorOutput)) {
+			echo "<p style='color:blue'>L'import s'est déroulé sans problème.</p>\n";
+		} else {
+			echo "<p style='color:red'>Erreurs à l'importation!</p>\n";
+			foreach($errorOutput as $line) {
+				echo "<p>$line</p>\n";
 			}
+		}
+		if (!empty($opml->alreadyKnowns)) {
+			echo "<h3>Certains flux étaient déjà connus, ils n'ont pas été "
+				."réimportés&nbsp;:</h3>\n<ul>\n";
+			foreach($opml->alreadyKnowns as $alreadyKnown) {
+				foreach($alreadyKnown as &$elt) $elt = htmlspecialchars($elt);
+				$maxLength = 80;
+				$delimiter = '...';
+				if (strlen($alreadyKnown->description)>$maxLength) {
+					$alreadyKnown->description =
+						substr($alreadyKnown->description, 0,
+							$maxLength-strlen($delimiter)
+						).$delimiter;
+				}
+				echo "<li><a target='_parent' href='{$alreadyKnown->xmlUrl}'>"
+					."{$alreadyKnown->description}</a></li>\n";
+			}
+			echo "</ul>\n";
+		}
+		$syncCode = $configurationManager->get('synchronisationCode');
+		assert('!empty($syncCode)');
+		$syncLink = "action.php?action=synchronize&format=html&code=$syncCode";
+		echo "<p>";
+		echo "<a href='$syncLink' style='text-decoration:none;font-size:3em'>"
+			."↺</a>";
+		echo "<a href='$syncLink'>Cliquez ici pour synchroniser vos flux importés.</a>";
+		echo "<p>\n";
 	break;