Przeglądaj źródła

CLI export

ZIP export, OPML export.
Corrected height of feeds select in Pafat theme.
https://github.com/FreshRSS/FreshRSS/pull/1338
https://github.com/FreshRSS/FreshRSS/issues/1039
https://github.com/FreshRSS/FreshRSS/issues/1277
Alexandre Alapetite 9 lat temu
rodzic
commit
fcb9280fc8

+ 55 - 29
app/Controllers/importExportController.php

@@ -522,26 +522,21 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
 		return $return;
 	}
 
-	/**
-	 * This action handles export action.
-	 *
-	 * This action must be reached by a POST request.
-	 *
-	 * Parameters are:
-	 *   - export_opml (default: false)
-	 *   - export_starred (default: false)
-	 *   - export_feeds (default: array()) a list of feed ids
-	 */
-	public function exportAction() {
-		if (!Minz_Request::isPost()) {
-			Minz_Request::forward(array('c' => 'importExport', 'a' => 'index'), true);
-		}
+	public function exportFile($export_opml = true, $export_starred = false, $export_feeds = array(), $maxFeedEntries = 50, $username = null) {
+		require_once(LIB_PATH . '/lib_opml.php');
 
-		$this->view->_useLayout(false);
+		$this->catDAO = new FreshRSS_CategoryDAO($username);
+		$this->entryDAO = FreshRSS_Factory::createEntryDao($username);
+		$this->feedDAO = FreshRSS_Factory::createFeedDao($username);
+
+		if ($export_feeds === true) {
+			//All feeds
+			$export_feeds = $this->feedDAO->listFeedsIds();
+		}
+		if (!is_array($export_feeds)) {
+			$export_feeds = array();
+		}
 
-		$export_opml = Minz_Request::param('export_opml', false);
-		$export_starred = Minz_Request::param('export_starred', false);
-		$export_feeds = Minz_Request::param('export_feeds', array());
 		$day = date('Y-m-d');
 
 		$export_files = array();
@@ -558,7 +553,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
 			if ($feed) {
 				$filename = "feed_${day}_" . $feed->category() . '_'
 				          . $feed->id() . '.json';
-				$export_files[$filename] = $this->generateEntries('feed', $feed);
+				$export_files[$filename] = $this->generateEntries('feed', $feed, $maxFeedEntries);
 			}
 		}
 
@@ -566,18 +561,49 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
 		if ($nb_files > 1) {
 			// If there are more than 1 file to export, we need a ZIP archive.
 			try {
-				$this->exportZip($export_files);
+				$this->sendZip($export_files);
 			} catch (Exception $e) {
-				# Oops, there is no ZIP extension!
-				Minz_Request::bad(_t('feedback.import_export.export_no_zip_extension'),
-				                  array('c' => 'importExport', 'a' => 'index'));
+				throw new FreshRSS_ZipMissing_Exception($e);
 			}
 		} elseif ($nb_files === 1) {
 			// Only one file? Guess its type and export it.
 			$filename = key($export_files);
 			$type = self::guessFileType($filename);
-			$this->exportFile('freshrss_' . $filename, $export_files[$filename], $type);
-		} else {
+			$this->sendFile('freshrss_' . $filename, $export_files[$filename], $type);
+		}
+		return $nb_files;
+	}
+
+	/**
+	 * This action handles export action.
+	 *
+	 * This action must be reached by a POST request.
+	 *
+	 * Parameters are:
+	 *   - export_opml (default: false)
+	 *   - export_starred (default: false)
+	 *   - export_feeds (default: array()) a list of feed ids
+	 */
+	public function exportAction() {
+		if (!Minz_Request::isPost()) {
+			Minz_Request::forward(array('c' => 'importExport', 'a' => 'index'), true);
+		}
+		$this->view->_useLayout(false);
+
+		$nb_files = 0;
+		try {
+			$nb_files = $this->exportFile(
+					Minz_Request::param('export_opml', false),
+					Minz_Request::param('export_starred', false),
+					Minz_Request::param('export_feeds', array())
+				);
+		} catch (FreshRSS_ZipMissing_Exception $zme) {
+			# Oops, there is no ZIP extension!
+			Minz_Request::bad(_t('feedback.import_export.export_no_zip_extension'),
+			                  array('c' => 'importExport', 'a' => 'index'));
+		}
+
+		if ($nb_files < 1) {
 			// Nothing to do...
 			Minz_Request::forward(array('c' => 'importExport', 'a' => 'index'), true);
 		}
@@ -606,7 +632,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
 	 * @param FreshRSS_Feed $feed feed of which we want to get entries.
 	 * @return string the JSON file content.
 	 */
-	private function generateEntries($type, $feed = NULL) {
+	private function generateEntries($type, $feed = NULL, $maxFeedEntries = 50) {
 		$this->view->categories = $this->catDAO->listCategories();
 
 		if ($type == 'starred') {
@@ -621,7 +647,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
 			$this->view->type = 'feed/' . $feed->id();
 			$this->view->entries = $this->entryDAO->listWhere(
 				'f', $feed->id(), FreshRSS_Entry::STATE_ALL, 'ASC',
-				FreshRSS_Context::$user_conf->posts_per_page
+				$maxFeedEntries
 			);
 			$this->view->feed = $feed;
 		}
@@ -635,7 +661,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
 	 * @param array $files list of files where key is filename and value the content.
 	 * @throws Exception if Zip extension is not loaded.
 	 */
-	private function exportZip($files) {
+	private function sendZip($files) {
 		if (!extension_loaded('zip')) {
 			throw new Exception();
 		}
@@ -667,7 +693,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
 	 * @param string $type the file type (opml, json_feed or json_starred).
 	 *                     If equals to unknown, nothing happens.
 	 */
-	private function exportFile($filename, $content, $type) {
+	private function sendFile($filename, $content, $type) {
 		if ($type === 'unknown') {
 			return;
 		}

+ 7 - 0
app/Models/FeedDAO.php

@@ -212,6 +212,13 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
 		}
 	}
 
+	public function listFeedsIds() {
+		$sql = 'SELECT id FROM `' . $this->prefix . 'feed`';
+		$stm = $this->bd->prepare($sql);
+		$stm->execute();
+		return $stm->fetchAll(PDO::FETCH_COLUMN, 0);
+	}
+
 	public function listFeeds() {
 		$sql = 'SELECT * FROM `' . $this->prefix . 'feed` ORDER BY name';
 		$stm = $this->bd->prepare($sql);

+ 1 - 1
app/views/importExport/index.phtml

@@ -44,7 +44,7 @@
 						$select_args = ' size="' . min(10, count($this->feeds)) .'" multiple="multiple"';
 					}
 				?>
-				<select name="export_feeds[]"<?php echo $select_args; ?>>
+				<select name="export_feeds[]"<?php echo $select_args; ?> size="10">
 					<?php echo extension_loaded('zip') ? '' : '<option></option>'; ?>
 					<?php foreach ($this->feeds as $feed) { ?>
 					<option value="<?php echo $feed->id(); ?>"><?php echo $feed->name(); ?></option>

+ 2 - 2
cli/_cli.php

@@ -10,7 +10,7 @@ Minz_Configuration::register('system',
 	DATA_PATH . '/config.php',
 	DATA_PATH . '/config.default.php');
 FreshRSS_Context::$system_conf = Minz_Configuration::get('system');
-Minz_Translate::init();
+Minz_Translate::init('en');
 
 FreshRSS_Context::$isCli = true;
 
@@ -39,6 +39,6 @@ function cliInitUser($username) {
 }
 
 function done($ok) {
-	echo 'Result: ', ($ok ? 'success' : 'fail'), ".\n";
+	fwrite(STDERR, 'Result: ' . ($ok ? 'success' : 'fail') . "\n");
 	exit($ok ? 0 : 1);
 }

+ 7 - 7
cli/create-user.php

@@ -4,16 +4,16 @@ require('_cli.php');
 
 $options = getopt('', array(
 		'user:',
-		'password::',
-		'api-password::',
-		'language::',
-		'email::',
-		'token::',
+		'password:',
+		'api-password:',
+		'language:',
+		'email:',
+		'token:',
 	));
 
 if (empty($options['user'])) {
-	fail('Usage: ' . basename(__FILE__) . " --user=username --password='password' --api-password='api_password'" .
-		" --language=en --email=user@example.net --token='longRandomString'");
+	fail('Usage: ' . basename(__FILE__) . " --user username --password 'password' --api-password 'api_password'" .
+		" --language en --email user@example.net --token 'longRandomString'");
 }
 $username = $options['user'];
 if (!ctype_alnum($username)) {

+ 1 - 1
cli/delete-user.php

@@ -7,7 +7,7 @@ $options = getopt('', array(
 	));
 
 if (empty($options['user'])) {
-	fail('Usage: ' . basename(__FILE__) . " --user=username");
+	fail('Usage: ' . basename(__FILE__) . " --user username");
 }
 $username = $options['user'];
 if (!ctype_alnum($username)) {

+ 24 - 0
cli/export-opml-for-user.php

@@ -0,0 +1,24 @@
+#!/usr/bin/php
+<?php
+require('_cli.php');
+
+$options = getopt('', array(
+		'user:',
+	));
+
+if (empty($options['user'])) {
+	fail('Usage: ' . basename(__FILE__) . " --user username > /path/to/file.opml.xml'");
+}
+
+$username = cliInitUser($options['user']);
+
+fwrite(STDERR, 'FreshRSS exporting OPML for user “' . $username . "”…\n");
+
+$importController = new FreshRSS_importExport_Controller();
+
+$ok = false;
+$ok = $importController->exportFile(true, false, array(), 0, $username);
+
+invalidateHttpCache($username);
+
+done($ok);

+ 30 - 0
cli/export-zip-for-user.php

@@ -0,0 +1,30 @@
+#!/usr/bin/php
+<?php
+require('_cli.php');
+
+$options = getopt('', array(
+		'user:',
+		'max-feed-entries:',
+	));
+
+if (empty($options['user'])) {
+	fail('Usage: ' . basename(__FILE__) . " --user username --max-feed-entries 100 > /path/to/file.zip'");
+}
+
+$username = cliInitUser($options['user']);
+
+fwrite(STDERR, 'FreshRSS exporting ZIP for user “' . $username . "”…\n");
+
+$importController = new FreshRSS_importExport_Controller();
+
+$ok = false;
+try {
+	$ok = $importController->exportFile(true, true, true,
+	empty($options['max-feed-entries']) ? 100 : intval($options['max-feed-entries']),
+	$username);
+} catch (FreshRSS_ZipMissing_Exception $zme) {
+	fail('FreshRSS error: Lacking php-zip extension!');
+}
+invalidateHttpCache($username);
+
+done($ok);

+ 1 - 2
cli/import-for-user.php

@@ -5,11 +5,10 @@ require('_cli.php');
 $options = getopt('', array(
 		'user:',
 		'filename:',
-		'clear-existing',
 	));
 
 if (empty($options['user']) || empty($options['filename'])) {
-	fail('Usage: ' . basename(__FILE__) . " --user=username --filename='/path/to/file.ext' --clear-existing");
+	fail('Usage: ' . basename(__FILE__) . " --user username --filename /path/to/file.ext");
 }
 
 $username = cliInitUser($options['user']);

+ 0 - 3
p/themes/Pafat/pafat.css

@@ -48,9 +48,6 @@ input, select, textarea {
 	vertical-align: middle;
 }
 
-select{
-	height:29px;
-}
 option {
 	padding: 0 .5em;
 }