diff options
| author | 2021-03-24 19:04:51 +0100 | |
|---|---|---|
| committer | 2021-03-24 19:04:51 +0100 | |
| commit | de40f3ad56b99b6128e8d9d207f5c5304ae97393 (patch) | |
| tree | 7755eac081f32ba87445ec82a2a740ea4a1865eb | |
| parent | 06fa51448336d8ad95d70e7cd96e4c3f4e30907a (diff) | |
Fix TT-RSS import (#3553)
| -rw-r--r-- | app/Controllers/importExportController.php | 28 | ||||
| -rw-r--r-- | app/Models/DatabaseDAO.php | 5 | ||||
| -rw-r--r-- | app/Models/EntryDAO.php | 11 | ||||
| -rw-r--r-- | app/Services/ImportService.php | 6 |
4 files changed, 37 insertions, 13 deletions
diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php index 3550ba0dd..f3b898df4 100644 --- a/app/Controllers/importExportController.php +++ b/app/Controllers/importExportController.php @@ -189,7 +189,7 @@ 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) { + } elseif (stripos($filename, 'opml') !== false) { return 'opml'; } elseif (substr_compare($filename, '.json', -5) === 0) { if (strpos($filename, 'starred') !== false) { @@ -208,11 +208,15 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { } private function ttrssXmlToJson($xml) { - $table = (array)simplexml_load_string($xml, null, LIBXML_NOCDATA); + $table = (array)simplexml_load_string($xml, null, LIBXML_NOBLANKS | 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 = array_filter($item, function ($v) { + // Filter out empty properties, potentially reported as empty objects + return (is_string($v) && trim($v) !== '') || !empty($v); + }); $item['updated'] = isset($item['updated']) ? strtotime($item['updated']) : ''; $item['published'] = $item['updated']; $item['content'] = array('content' => isset($item['content']) ? $item['content'] : ''); @@ -274,8 +278,14 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { // First, we check feeds of articles are in DB (and add them if needed). foreach ($items as $item) { - if (!isset($item['origin'])) { - $item['origin'] = array('title' => 'Import'); + if (empty($item['id'])) { + continue; + } + if (empty($item['origin'])) { + $item['origin'] = []; + } + if (empty($item['origin']['title']) || trim($item['origin']['title']) === '') { + $item['origin']['title'] = 'Import'; } if (!empty($item['origin']['feedUrl'])) { $feedUrl = $item['origin']['feedUrl']; @@ -338,7 +348,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { $newGuids = array(); $this->entryDAO->beginTransaction(); foreach ($items as $item) { - if (empty($article_to_feed[$item['id']])) { + if (empty($item['id']) || empty($article_to_feed[$item['id']])) { // Related feed does not exist for this entry, do nothing. continue; } @@ -349,7 +359,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { $is_read = null; $tags = empty($item['categories']) ? array() : $item['categories']; $labels = array(); - for ($i = count($tags) - 1; $i >= 0; $i --) { + for ($i = count($tags) - 1; $i >= 0; $i--) { $tag = trim($tags[$i]); if (strpos($tag, 'user/-/') !== false) { if ($tag === 'user/-/state/com.google/starred') { @@ -383,6 +393,8 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { $url = ''; } + $title = empty($item['title']) ? $url : $item['title']; + if (!empty($item['content']['content'])) { $content = $item['content']['content']; } elseif (!empty($item['summary']['content'])) { @@ -408,7 +420,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { } $entry = new FreshRSS_Entry( - $feed_id, $item['id'], $item['title'], $author, + $feed_id, $item['id'], $title, $author, $content, $url, $published, $is_read, $is_starred ); $entry->_id(uTimeString()); @@ -493,7 +505,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { } elseif (!empty($origin['feedUrl'])) { $website = $origin['feedUrl']; } - $name = empty($origin['title']) ? '' : $origin['title']; + $name = empty($origin['title']) ? $website : $origin['title']; try { // Create a Feed object and add it in database. diff --git a/app/Models/DatabaseDAO.php b/app/Models/DatabaseDAO.php index 4bda44268..86f72b14c 100644 --- a/app/Models/DatabaseDAO.php +++ b/app/Models/DatabaseDAO.php @@ -10,6 +10,11 @@ class FreshRSS_DatabaseDAO extends Minz_ModelPdo { const ER_BAD_TABLE_ERROR = '42S02'; const ER_DATA_TOO_LONG = '1406'; + /** + * Based on SQLite SQLITE_MAX_VARIABLE_NUMBER + */ + const MAX_VARIABLE_NUMBER = 998; + //MySQL InnoDB maximum index length for UTF8MB4 //https://dev.mysql.com/doc/refman/8.0/en/innodb-restrictions.html const LENGTH_INDEX_UNICODE = 191; diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php index c641878ad..9ed1d564d 100644 --- a/app/Models/EntryDAO.php +++ b/app/Models/EntryDAO.php @@ -989,8 +989,16 @@ SQL; } public function listHashForFeedGuids($id_feed, $guids) { + $result = []; if (count($guids) < 1) { - return array(); + return $result; + } elseif (count($guids) > FreshRSS_DatabaseDAO::MAX_VARIABLE_NUMBER) { + // Split a query with too many variables parameters + $guidsChunks = array_chunk($guids, FreshRSS_DatabaseDAO::MAX_VARIABLE_NUMBER, true); + foreach ($guidsChunks as $guidsChunk) { + $result += $this->listHashForFeedGuids($id_feed, $guidsChunk); + } + return $result; } $guids = array_unique($guids); $sql = 'SELECT guid, ' . $this->sqlHexEncode('hash') . @@ -999,7 +1007,6 @@ SQL; $values = array($id_feed); $values = array_merge($values, $guids); if ($stm && $stm->execute($values)) { - $result = array(); $rows = $stm->fetchAll(PDO::FETCH_ASSOC); foreach ($rows as $row) { $result[$row['guid']] = $row['hex_hash']; diff --git a/app/Services/ImportService.php b/app/Services/ImportService.php index 973cd7825..635613475 100644 --- a/app/Services/ImportService.php +++ b/app/Services/ImportService.php @@ -67,8 +67,8 @@ class FreshRSS_Import_Service { //Sort with categories first usort($opml_elements, function ($a, $b) { return strcmp( - (isset($a['xmlUrl']) ? 'Z' : 'A') . $a['text'], - (isset($b['xmlUrl']) ? 'Z' : 'A') . $b['text']); + (isset($a['xmlUrl']) ? 'Z' : 'A') . (isset($a['text']) ? $a['text'] : ''), + (isset($b['xmlUrl']) ? 'Z' : 'A') . (isset($b['text']) ? $b['text'] : '')); }); foreach ($opml_elements as $elt) { @@ -86,7 +86,7 @@ class FreshRSS_Import_Service { } else { $ok = false; } - } else { + } elseif (!empty($elt['text'])) { // No xmlUrl? It should be a category! $limit_reached = ($nb_cats >= $limits['max_categories']); if (!FreshRSS_Context::$isCli && $limit_reached) { |
