aboutsummaryrefslogtreecommitdiff
path: root/app/Controllers
diff options
context:
space:
mode:
authorGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2018-12-22 13:22:20 +0100
committerGravatar GitHub <noreply@github.com> 2018-12-22 13:22:20 +0100
commitf0a359619fa2936d66a2b96dd086d4686e7405fa (patch)
treeddad42a7f6813bd458f39d5203d083daad4cc1c5 /app/Controllers
parente04804d0f67dd43fd3f072b9a127768ee7b7b56c (diff)
parent4a1a852f457d52fa47191e3f7e3e9073e1324cd9 (diff)
Merge pull request #2186 from FreshRSS/dev1.13.0
FreshRSS 1.13.0
Diffstat (limited to 'app/Controllers')
-rwxr-xr-xapp/Controllers/configureController.php2
-rwxr-xr-xapp/Controllers/feedController.php12
-rw-r--r--app/Controllers/importExportController.php168
-rw-r--r--app/Controllers/subscriptionController.php2
4 files changed, 151 insertions, 33 deletions
diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php
index 20bcd2e76..9c3900f39 100755
--- a/app/Controllers/configureController.php
+++ b/app/Controllers/configureController.php
@@ -308,6 +308,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
* - user limit (default: 1)
* - user category limit (default: 16384)
* - user feed limit (default: 16384)
+ * - user login duration for form auth (default: 2592000)
*/
public function systemAction() {
if (!FreshRSS_Auth::hasAccess('admin')) {
@@ -318,6 +319,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
$limits['max_registrations'] = Minz_Request::param('max-registrations', 1);
$limits['max_feeds'] = Minz_Request::param('max-feeds', 16384);
$limits['max_categories'] = Minz_Request::param('max-categories', 16384);
+ $limits['cookie_duration'] = Minz_Request::param('cookie-duration', 2592000);
FreshRSS_Context::$system_conf->limits = $limits;
FreshRSS_Context::$system_conf->title = Minz_Request::param('instance-name', 'FreshRSS');
FreshRSS_Context::$system_conf->auto_update_url = Minz_Request::param('auto-update-url', false);
diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php
index f2b1b8960..74c9eacfa 100755
--- a/app/Controllers/feedController.php
+++ b/app/Controllers/feedController.php
@@ -266,7 +266,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
$nb_month_old = max(FreshRSS_Context::$user_conf->old_entries, 1);
$date_min = time() - (3600 * 24 * 30 * $nb_month_old);
- // PubSubHubbub support
+ // WebSub (PubSubHubbub) support
$pubsubhubbubEnabledGeneral = FreshRSS_Context::$system_conf->pubsubhubbub_enabled;
$pshbMinAge = time() - (3600 * 24); //TODO: Make a configuration.
@@ -437,13 +437,13 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
$entryDAO->commit();
}
- if ($feed->hubUrl() && $feed->selfUrl()) { //selfUrl has priority for PubSubHubbub
+ if ($feed->hubUrl() && $feed->selfUrl()) { //selfUrl has priority for WebSub
if ($feed->selfUrl() !== $url) { //https://code.google.com/p/pubsubhubbub/wiki/MovingFeedsOrChangingHubs
$selfUrl = checkUrl($feed->selfUrl());
if ($selfUrl) {
- Minz_Log::debug('PubSubHubbub unsubscribe ' . $feed->url(false));
+ Minz_Log::debug('WebSub unsubscribe ' . $feed->url(false));
if (!$feed->pubSubHubbubSubscribe(false)) { //Unsubscribe
- Minz_Log::warning('Error while PubSubHubbub unsubscribing from ' . $feed->url(false));
+ Minz_Log::warning('Error while WebSub unsubscribing from ' . $feed->url(false));
}
$feed->_url($selfUrl, false);
Minz_Log::notice('Feed ' . $url . ' canonical address moved to ' . $feed->url(false));
@@ -457,9 +457,9 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
$feed->faviconPrepare();
if ($pubsubhubbubEnabledGeneral && $feed->pubSubHubbubPrepare()) {
- Minz_Log::notice('PubSubHubbub subscribe ' . $feed->url(false));
+ Minz_Log::notice('WebSub subscribe ' . $feed->url(false));
if (!$feed->pubSubHubbubSubscribe(true)) { //Subscribe
- Minz_Log::warning('Error while PubSubHubbub subscribing to ' . $feed->url(false));
+ Minz_Log::warning('Error while WebSub subscribing to ' . $feed->url(false));
}
}
$feed->unlock();
diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php
index 0fb5ba651..2d8d4e01d 100644
--- a/app/Controllers/importExportController.php
+++ b/app/Controllers/importExportController.php
@@ -109,6 +109,17 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
}
}
}
+ foreach ($list_files['ttrss_starred'] as $article_file) {
+ $json = $this->ttrssXmlToJson($article_file);
+ if (!$this->importJson($json, true)) {
+ $ok = false;
+ if (FreshRSS_Context::$isCli) {
+ fwrite(STDERR, 'FreshRSS error during TT-RSS articles import' . "\n");
+ } else {
+ Minz_Log::warning('Error during TT-RSS articles import');
+ }
+ }
+ }
return $ok;
}
@@ -165,17 +176,22 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
private static function guessFileType($filename) {
if (substr_compare($filename, '.zip', -4) === 0) {
return 'zip';
- } elseif (substr_compare($filename, '.opml', -5) === 0 ||
- substr_compare($filename, '.xml', -4) === 0) {
+ } elseif (substr_compare($filename, '.opml', -5) === 0) {
return 'opml';
- } elseif (substr_compare($filename, '.json', -5) === 0 &&
- strpos($filename, 'starred') !== false) {
- return 'json_starred';
} elseif (substr_compare($filename, '.json', -5) === 0) {
- return 'json_feed';
- } else {
- return 'unknown';
+ if (strpos($filename, 'starred') !== false) {
+ return 'json_starred';
+ } else {
+ return 'json_feed';
+ }
+ } elseif (substr_compare($filename, '.xml', -4) === 0) {
+ if (preg_match('/Tiny|tt-?rss/i', $filename)) {
+ return 'ttrss_starred';
+ } else {
+ return 'opml';
+ }
}
+ return 'unknown';
}
/**
@@ -364,6 +380,43 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
return !$error;
}
+ private function ttrssXmlToJson($xml) {
+ $table = (array)simplexml_load_string($xml, null, LIBXML_NOCDATA);
+ $table['items'] = isset($table['article']) ? $table['article'] : array();
+ unset($table['article']);
+ for ($i = count($table['items']) - 1; $i >= 0; $i--) {
+ $item = (array)($table['items'][$i]);
+ $item['updated'] = isset($item['updated']) ? strtotime($item['updated']) : '';
+ $item['published'] = $item['updated'];
+ $item['content'] = array('content' => isset($item['content']) ? $item['content'] : '');
+ $item['categories'] = isset($item['tag_cache']) ? array($item['tag_cache']) : array();
+ if (!empty($item['marked'])) {
+ $item['categories'][] = 'user/-/state/com.google/starred';
+ }
+ if (!empty($item['published'])) {
+ $item['categories'][] = 'user/-/state/com.google/broadcast';
+ }
+ if (!empty($item['label_cache'])) {
+ $labels_cache = json_decode($item['label_cache'], true);
+ if (is_array($labels_cache)) {
+ foreach ($labels_cache as $label_cache) {
+ if (!empty($label_cache[1])) {
+ $item['categories'][] = 'user/-/label/' . trim($label_cache[1]);
+ }
+ }
+ }
+ }
+ $item['alternate'][0]['href'] = isset($item['link']) ? $item['link'] : '';
+ $item['origin'] = array(
+ 'title' => isset($item['feed_title']) ? $item['feed_title'] : '',
+ 'feedUrl' => isset($item['feed_url']) ? $item['feed_url'] : '',
+ );
+ $item['id'] = isset($item['guid']) ? $item['guid'] : (isset($item['feed_url']) ? $item['feed_url'] : $item['published']);
+ $table['items'][$i] = $item;
+ }
+ return json_encode($table);
+ }
+
/**
* This method import a JSON-based file (Google Reader format).
*
@@ -405,7 +458,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
// Oops, no more place!
Minz_Log::warning(_t('feedback.sub.feed.over_max', $limits['max_feeds']));
} else {
- $feed = $this->addFeedJson($item['origin'], $google_compliant);
+ $feed = $this->addFeedJson($item['origin']);
}
if ($feed == null) {
@@ -425,6 +478,15 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
}
}
+ $tagDAO = FreshRSS_Factory::createTagDao();
+ $labels = $tagDAO->listTags();
+ $knownLabels = array();
+ foreach ($labels as $label) {
+ $knownLabels[$label->name()]['id'] = $label->id();
+ $knownLabels[$label->name()]['articles'] = array();
+ }
+ unset($labels);
+
// For each feed, check existing GUIDs already in database.
$existingHashForGuids = array();
foreach ($newFeedGuids as $feedId => $newGuids) {
@@ -443,19 +505,36 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
$feed_id = $article_to_feed[$item['id']];
$author = isset($item['author']) ? $item['author'] : '';
- $key_content = ($google_compliant && !isset($item['content'])) ? 'summary' : 'content';
+ $is_starred = $starred;
$tags = $item['categories'];
- if ($google_compliant) {
- // Remove tags containing "/state/com.google" which are useless.
- $tags = array_filter($tags, function($var) {
- return strpos($var, '/state/com.google') !== false;
- });
+ $labels = array();
+ for ($i = count($tags) - 1; $i >= 0; $i --) {
+ $tag = trim($tags[$i]);
+ if (strpos($tag, 'user/-/') !== false) {
+ if ($tag === 'user/-/state/com.google/starred') {
+ $is_starred = true;
+ } elseif (strpos($tag, 'user/-/label/') === 0) {
+ $tag = trim(substr($tag, 13));
+ if ($tag != '') {
+ $labels[] = $tag;
+ }
+ }
+ unset($tags[$i]);
+ }
+ }
+
+ $url = $item['alternate'][0]['href'];
+ if (!empty($item['content']['content'])) {
+ $content = $item['content']['content'];
+ } elseif (!empty($item['summary']['content'])) {
+ $content = $item['summary']['content'];
}
+ $content = sanitizeHTML($content, $url);
$entry = new FreshRSS_Entry(
$feed_id, $item['id'], $item['title'], $author,
- $item[$key_content]['content'], $item['alternate'][0]['href'],
- $item['published'], $is_read, $starred
+ $content, $url,
+ $item['published'], $is_read, $is_starred
);
$entry->_id(min(time(), $entry->date(true)) . uSecString());
$entry->_tags($tags);
@@ -478,8 +557,21 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
} else {
$ok = $this->entryDAO->addEntry($values);
}
- $error |= ($ok === false);
+ foreach ($labels as $labelName) {
+ if (empty($knownLabels[$labelName]['id'])) {
+ $labelId = $tagDAO->addTag(array('name' => $labelName));
+ $knownLabels[$labelName]['id'] = $labelId;
+ $knownLabels[$labelName]['articles'] = array();
+ }
+ $knownLabels[$labelName]['articles'][] = array(
+ //'id' => $entry->id(), //ID changes after commitNewEntries()
+ 'id_feed' => $entry->feed(),
+ 'guid' => $entry->guid(),
+ );
+ }
+
+ $error |= ($ok === false);
}
$this->entryDAO->commit();
@@ -488,6 +580,20 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
$this->feedDAO->updateCachedValues();
$this->entryDAO->commit();
+ $this->entryDAO->beginTransaction();
+ foreach ($knownLabels as $labelName => $knownLabel) {
+ $labelId = $knownLabel['id'];
+ foreach ($knownLabel['articles'] as $article) {
+ $entryId = $this->entryDAO->searchIdByGuid($article['id_feed'], $article['guid']);
+ if ($entryId != null) {
+ $tagDAO->tagEntry($labelId, $entryId);
+ } else {
+ Minz_Log::warning('Could not add label "' . $labelName . '" to entry "' . $article['guid'] . '" in feed ' . $article['id_feed']);
+ }
+ }
+ }
+ $this->entryDAO->commit();
+
return !$error;
}
@@ -495,16 +601,24 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
* This method import a JSON-based feed (Google Reader format).
*
* @param array $origin represents a feed.
- * @param boolean $google_compliant takes care of some specific values if true.
* @return FreshRSS_Feed if feed is in database at the end of the process,
* else null.
*/
- private function addFeedJson($origin, $google_compliant) {
+ private function addFeedJson($origin) {
$return = null;
- $key = $google_compliant ? 'htmlUrl' : 'feedUrl';
- $url = $origin[$key];
- $name = $origin['title'];
- $website = $origin['htmlUrl'];
+ if (!empty($origin['feedUrl'])) {
+ $url = $origin['feedUrl'];
+ } elseif (!empty($origin['htmlUrl'])) {
+ $url = $origin['htmlUrl'];
+ } else {
+ return null;
+ }
+ if (!empty($origin['htmlUrl'])) {
+ $website = $origin['htmlUrl'];
+ } elseif (!empty($origin['feedUrl'])) {
+ $website = $origin['feedUrl'];
+ }
+ $name = empty($origin['title']) ? '' : $origin['title'];
try {
// Create a Feed object and add it in database.
@@ -585,7 +699,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
// Only one file? Guess its type and export it.
$filename = key($export_files);
$type = self::guessFileType($filename);
- $this->sendFile('freshrss_' . $filename, $export_files[$filename], $type);
+ $this->sendFile('freshrss_' . Minz_Session::param('currentUser', '_') . '_' . $filename, $export_files[$filename], $type);
}
return $nb_files;
}
@@ -683,7 +797,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
}
// From https://stackoverflow.com/questions/1061710/php-zip-files-on-the-fly
- $zip_file = tempnam('tmp', 'zip');
+ $zip_file = @tempnam('/tmp', 'zip');
$zip = new ZipArchive();
$zip->open($zip_file, ZipArchive::OVERWRITE);
@@ -696,7 +810,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
header('Content-Type: application/zip');
header('Content-Length: ' . filesize($zip_file));
$day = date('Y-m-d');
- header('Content-Disposition: attachment; filename="freshrss_' . $day . '_export.zip"');
+ header('Content-Disposition: attachment; filename="freshrss_' . Minz_Session::param('currentUser', '_') . '_' . $day . '_export.zip"');
readfile($zip_file);
unlink($zip_file);
}
diff --git a/app/Controllers/subscriptionController.php b/app/Controllers/subscriptionController.php
index 0b1439ba5..46503fc19 100644
--- a/app/Controllers/subscriptionController.php
+++ b/app/Controllers/subscriptionController.php
@@ -33,6 +33,8 @@ class FreshRSS_subscription_Controller extends Minz_ActionController {
@filemtime(PUBLIC_PATH . '/scripts/category.js')));
Minz_View::prependTitle(_t('sub.title') . ' ยท ');
+ $this->view->onlyFeedsWithError = Minz_Request::paramTernary('error');
+
$id = Minz_Request::param('id');
if ($id !== false) {
$feedDAO = FreshRSS_Factory::createFeedDao();