From f0684d701862d103fce834bad9e139f97544bc62 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Thu, 24 Jan 2019 19:54:34 +0100 Subject: Fix import labels (#2225) All labelled articles were wrongly marked as starred. --- app/Controllers/importExportController.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'app/Controllers') diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php index 3f2947c7a..96c5e42c2 100644 --- a/app/Controllers/importExportController.php +++ b/app/Controllers/importExportController.php @@ -41,7 +41,8 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { $list_files = array( 'opml' => array(), 'json_starred' => array(), - 'json_feed' => array() + 'json_feed' => array(), + 'ttrss_starred' => array(), ); // We try to list all files according to their type @@ -505,7 +506,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { $feed_id = $article_to_feed[$item['id']]; $author = isset($item['author']) ? $item['author'] : ''; - $is_starred = $starred; + $is_starred = false; $tags = $item['categories']; $labels = array(); for ($i = count($tags) - 1; $i >= 0; $i --) { @@ -522,6 +523,10 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { unset($tags[$i]); } } + if ($starred && !$is_starred) { + //If the article has no label, mark it as starred (old format) + $is_starred = empty($labels); + } $url = $item['alternate'][0]['href']; if (!empty($item['content']['content'])) { -- cgit v1.2.3 From f1ac6dd5509c6aa9e1d99401c5e1a0b894d4e7b0 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Thu, 24 Jan 2019 20:44:45 +0100 Subject: Export/import articles read/unread state (#2226) --- CHANGELOG.md | 1 + app/Controllers/importExportController.php | 10 +++++++++- app/views/helpers/export/articles.phtml | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) (limited to 'app/Controllers') diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a0188431..3e3dfc302 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Features * Include articles with custom labels during export [#2196](https://github.com/FreshRSS/FreshRSS/issues/2196) + * Export/import articles read/unread state [#2226](https://github.com/FreshRSS/FreshRSS/pull/2226) * Bug fixing * Fix missing HTTP `X-Forwarded-Prefix` in cookie path behind a reverse-proxy [#2201](https://github.com/FreshRSS/FreshRSS/pull/2201) * Deployment diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php index 96c5e42c2..e11221610 100644 --- a/app/Controllers/importExportController.php +++ b/app/Controllers/importExportController.php @@ -436,7 +436,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { return false; } - $is_read = FreshRSS_Context::$user_conf->mark_when['reception'] ? 1 : 0; + $mark_as_read = FreshRSS_Context::$user_conf->mark_when['reception'] ? 1 : 0; $google_compliant = strpos($article_object['id'], 'com.google') !== false; @@ -507,6 +507,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { $feed_id = $article_to_feed[$item['id']]; $author = isset($item['author']) ? $item['author'] : ''; $is_starred = false; + $is_read = null; $tags = $item['categories']; $labels = array(); for ($i = count($tags) - 1; $i >= 0; $i --) { @@ -514,6 +515,10 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { if (strpos($tag, 'user/-/') !== false) { if ($tag === 'user/-/state/com.google/starred') { $is_starred = true; + } elseif ($tag === 'user/-/state/com.google/read') { + $is_read = true; + } elseif ($tag === 'user/-/state/com.google/unread') { + $is_read = false; } elseif (strpos($tag, 'user/-/label/') === 0) { $tag = trim(substr($tag, 13)); if ($tag != '') { @@ -527,6 +532,9 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { //If the article has no label, mark it as starred (old format) $is_starred = empty($labels); } + if ($is_read === null) { + $is_read = $mark_as_read; + } $url = $item['alternate'][0]['href']; if (!empty($item['content']['content'])) { diff --git a/app/views/helpers/export/articles.phtml b/app/views/helpers/export/articles.phtml index eb2cb0924..2d1fcd133 100644 --- a/app/views/helpers/export/articles.phtml +++ b/app/views/helpers/export/articles.phtml @@ -56,6 +56,7 @@ foreach ($this->entriesRaw as $entryRaw) { 'feedUrl' => $feed == null ? '' : $feed->url(), ) ); + $article['categories'][] = $entry->isRead() ? 'user/-/state/com.google/read' : 'user/-/state/com.google/unread'; if ($entry->isFavorite()) { $article['categories'][] = 'user/-/state/com.google/starred'; } -- cgit v1.2.3 From 7902d10b3adee3788d770b9a75ac63b910140b0c Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 26 Jan 2019 12:55:12 +0100 Subject: Import FeedBin (#2228) * Import FeedBin https://github.com/FreshRSS/FreshRSS/issues/2227 And more tolerant import * Mute import fake feed + Changelog * strtotime for published dates in string --- CHANGELOG.md | 1 + app/Controllers/importExportController.php | 59 +++++++++++++++++++++++++----- app/Models/FeedDAO.php | 5 ++- 3 files changed, 54 insertions(+), 11 deletions(-) (limited to 'app/Controllers') diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e3dfc302..a32a1d43e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * Features * Include articles with custom labels during export [#2196](https://github.com/FreshRSS/FreshRSS/issues/2196) * Export/import articles read/unread state [#2226](https://github.com/FreshRSS/FreshRSS/pull/2226) + * Import FeedBin, and more robust general import [#2228](https://github.com/FreshRSS/FreshRSS/pull/2228) * Bug fixing * Fix missing HTTP `X-Forwarded-Prefix` in cookie path behind a reverse-proxy [#2201](https://github.com/FreshRSS/FreshRSS/pull/2201) * Deployment diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php index e11221610..80b9868ec 100644 --- a/app/Controllers/importExportController.php +++ b/app/Controllers/importExportController.php @@ -435,11 +435,10 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { } return false; } + $items = isset($article_object['items']) ? $article_object['items'] : $article_object; $mark_as_read = FreshRSS_Context::$user_conf->mark_when['reception'] ? 1 : 0; - $google_compliant = strpos($article_object['id'], 'com.google') !== false; - $error = false; $article_to_feed = array(); @@ -448,9 +447,23 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { $limits = FreshRSS_Context::$system_conf->limits; // First, we check feeds of articles are in DB (and add them if needed). - foreach ($article_object['items'] as $item) { - $key = $google_compliant ? 'htmlUrl' : 'feedUrl'; - $feed = new FreshRSS_Feed($item['origin'][$key]); + foreach ($items as $item) { + if (!isset($item['origin'])) { + $item['origin'] = array('title' => 'Import'); + } + if (!empty($item['origin']['feedUrl'])) { + $feedUrl = $item['origin']['feedUrl']; + } elseif (!empty($item['origin']['streamId']) && strpos($item['origin']['streamId'], 'feed/') === 0) { + $feedUrl = substr($item['origin']['streamId'], 5); //Google Reader + $item['origin']['feedUrl'] = $feedUrl; + } elseif (!empty($item['origin']['htmlUrl'])) { + $feedUrl = $item['origin']['htmlUrl']; + } else { + $feedUrl = 'http://import.localhost/import.xml'; + $item['origin']['feedUrl'] = $feedUrl; + $item['origin']['disable'] = true; + } + $feed = new FreshRSS_Feed($feedUrl); $feed = $this->feedDAO->searchByUrl($feed->url()); if ($feed == null) { @@ -498,7 +511,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { // Then, articles are imported. $newGuids = array(); $this->entryDAO->beginTransaction(); - foreach ($article_object['items'] as $item) { + foreach ($items as $item) { if (empty($article_to_feed[$item['id']])) { // Related feed does not exist for this entry, do nothing. continue; @@ -508,7 +521,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { $author = isset($item['author']) ? $item['author'] : ''; $is_starred = false; $is_read = null; - $tags = $item['categories']; + $tags = empty($item['categories']) ? array() : $item['categories']; $labels = array(); for ($i = count($tags) - 1; $i >= 0; $i --) { $tag = trim($tags[$i]); @@ -536,18 +549,41 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { $is_read = $mark_as_read; } - $url = $item['alternate'][0]['href']; + if (isset($item['alternate'][0]['href'])) { + $url = $item['alternate'][0]['href']; + } elseif (isset($item['url'])) { + $url = $item['url']; //FeedBin + } else { + $url = ''; + } + if (!empty($item['content']['content'])) { $content = $item['content']['content']; } elseif (!empty($item['summary']['content'])) { $content = $item['summary']['content']; + } elseif (!empty($item['content'])) { + $content = $item['content']; //FeedBin + } else { + $content = ''; } $content = sanitizeHTML($content, $url); + if (!empty($item['published'])) { + $published = $item['published']; + } elseif (!empty($item['timestampUsec'])) { + $published = substr($item['timestampUsec'], 0, -6); + } elseif (!empty($item['updated'])) { + $published = $item['updated']; + } else { + $published = 0; + } + if (!ctype_digit('' . $published)) { + $published = strtotime($published); + } + $entry = new FreshRSS_Entry( $feed_id, $item['id'], $item['title'], $author, - $content, $url, - $item['published'], $is_read, $is_starred + $content, $url, $published, $is_read, $is_starred ); $entry->_id(min(time(), $entry->date(true)) . uSecString()); $entry->_tags($tags); @@ -639,6 +675,9 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { $feed->_category(FreshRSS_CategoryDAO::DEFAULTCATEGORYID); $feed->_name($name); $feed->_website($website); + if (!empty($origin['disable'])) { + $feed->_ttl(-1 * FreshRSS_Context::$user_conf->ttl_default); + } // Call the extension hook $feed = Minz_ExtensionManager::callHook('feed_before_insert', $feed); diff --git a/app/Models/FeedDAO.php b/app/Models/FeedDAO.php index 7f00642f4..c9c9f6301 100644 --- a/app/Models/FeedDAO.php +++ b/app/Models/FeedDAO.php @@ -61,7 +61,7 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo implements FreshRSS_Searchable { $valuesTmp['lastUpdate'], base64_encode($valuesTmp['httpAuth']), FreshRSS_Feed::KEEP_HISTORY_DEFAULT, - FreshRSS_Feed::TTL_DEFAULT, + isset($valuesTmp['ttl']) ? intval($valuesTmp['ttl']) : FreshRSS_Feed::TTL_DEFAULT, isset($valuesTmp['attributes']) ? json_encode($valuesTmp['attributes']) : '', ); @@ -95,6 +95,9 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo implements FreshRSS_Searchable { 'httpAuth' => $feed->httpAuth(), 'attributes' => $feed->attributes(), ); + if ($feed->mute() || $feed->ttl() != FreshRSS_Context::$user_conf->ttl_default) { + $values['ttl'] = $feed->ttl() * ($feed->mute() ? -1 : 1); + } $id = $this->addFeed($values); if ($id) { -- cgit v1.2.3