From bc863ae93595cb773dfef5bd3f90e63593f1205f Mon Sep 17 00:00:00 2001 From: Dustin Wilson Date: Thu, 30 Mar 2017 09:42:37 -0500 Subject: [PATCH] Updated Database->updateFeeds() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Added category updating in Database->updateFeeds() • Made Database->updateFeeds() fail quietly when exceptions are occurred, logging them in the database instead of failing. • Changed the categories table name from arsse_tags to arsse_categories. --- lib/Database.php | 45 +++++++++++++++++++++++++++++++++------------ locale/en.php | 10 +++++----- sql/SQLite3/0.sql | 4 ++-- 3 files changed, 40 insertions(+), 19 deletions(-) diff --git a/lib/Database.php b/lib/Database.php index 8371a2a1..19deb8fa 100644 --- a/lib/Database.php +++ b/lib/Database.php @@ -393,24 +393,43 @@ class Database { )->lastId(); // If the article has categories add them into the categories database. - $categories = $article->getTag('category'); - if (count($categories) > 0) { - foreach ($categories as $c) { - $this->db->prepare('INSERT INTO arsse_tags(article,name) values(?,?)', 'int', 'str')->run($articleId, $c); - } - } + $this->categoriesAdd($article, $articleID); $this->db->commit(); return 1; } + public function categoriesAdd(PicoFeed\Parser\Item $article, int $id): int { + $this->db->begin(); + + $categories = $article->getTag('category'); + if (count($categories) > 0) { + foreach ($categories as $c) { + $this->db->prepare('INSERT INTO arsse_categories(article,name) values(?,?)', 'int', 'str')->run($id, $c); + } + } + + $this->db->commit(); + } + public function updateFeeds(): int { $feeds = $this->db->query('SELECT id, url, username, password, DATEFORMAT("http", modified) AS lastmodified, etag FROM arsse_feeds')->getAll(); foreach ($feeds as $f) { - $feed = new Feed($f['url'], $f['lastmodified'], $f['etag'], $f['username'], $f['password']); - // FIXME: What to do if fails? It currently throws an exception which isn't ideal here. + // Feed object throws an exception when there are problems, but that isn't ideal + // here. When an exception is occurred it should update the database with the + // error instead of failing. + try { + $feed = new Feed($f['url'], $f['lastmodified'], $f['etag'], $f['username'], $f['password']); + } catch (Feed\Exception $e) { + $this->db->prepare('UPDATE arsse_feeds SET err_count = err_count + 1, err_msg = "" WHERE id is ?', 'str', 'int')->run( + $e->getMessage(), + $f['id'] + ); - // If the feed has been updated then + continue; + } + + // If the feed has been updated then update the database. if ($feed->resource->isModified()) { $feed->parse(); @@ -474,12 +493,14 @@ class Database { $match['id'] ); - // TODO: Update categories + // If the article has categories update them. + $this->db->prepare('DELETE FROM arsse_categories WHERE article is ?', 'int')->run($match['id']); + $this->categoriesAdd($i, $match['id']); } } // Lastly update the feed database itself with updated information. - $this->db->prepare('UPDATE arsse_feeds SET url = ?, title = ?, favicon = ?, source = ?, updated = ?, modified = ?, etag = ? WHERE id is ?', 'str', 'str', 'str', 'str', 'datetime', 'datetime', 'str', 'int')->run( + $this->db->prepare('UPDATE arsse_feeds SET url = ?, title = ?, favicon = ?, source = ?, updated = ?, modified = ?, etag = ?, err_count = 0, err_msg = "" WHERE id is ?', 'str', 'str', 'str', 'str', 'datetime', 'datetime', 'str', 'int')->run( $feed->feedUrl, $feed->title, $feed->favicon, @@ -502,7 +523,7 @@ class Database { $cte = "RECURSIVE folders(id) as (SELECT id from arsse_folders where owner is ? and id is ? union select arsse_folders.id from arsse_folders join folders on arsse_folders.parent=folders.id) "; $changes = 0; $this->db->begin(); - // first delete any feed subscriptions contained within the folder tree (this may not be necesary because of foreign keys) + // first delete any feed subscriptions contained within the folder tree (this may not be necessary because of foreign keys) $changes += $this->db->prepare("WITH $cte"."DELETE FROM arsse_subscriptions where folder in(select id from folders)", "str", "int")->run($user, $id)->changes(); // next delete the folders themselves $changes += $this->db->prepare("WITH $cte"."DELETE FROM arsse_folders where id in(select id from folders)", "str", "int")->run($user, $id)->changes(); diff --git a/locale/en.php b/locale/en.php index 2e081253..7a74c166 100644 --- a/locale/en.php +++ b/locale/en.php @@ -1,9 +1,9 @@ 'Internal', - - 'Driver.Db.SQLite3.Name' => 'SQLite 3', - + 'Driver.User.Internal.Name' => 'Internal', + + 'Driver.Db.SQLite3.Name' => 'SQLite 3', + // this should only be encountered in testing (because tests should cover all exceptions!) 'Exception.JKingWeb/Arsse/Exception.uncoded' => 'The specified exception symbol {0} has no code specified in AbstractException.php', // this should not usually be encountered @@ -62,7 +62,7 @@ return [ 'Exception.JKingWeb/Arsse/User/Exception.doesNotExist' => 'Could not perform action "{action}" because the user {user} does not exist', 'Exception.JKingWeb/Arsse/User/Exception.authMissing' => 'Please log in to proceed', 'Exception.JKingWeb/Arsse/User/Exception.authFailed' => 'Authentication failed', - 'Exception.JKingWeb/Arsse/User/ExceptionAuthz.notAuthorized' => + 'Exception.JKingWeb/Arsse/User/ExceptionAuthz.notAuthorized' => '{action, select, userList {{user, select, global {Authenticated user is not authorized to view the global user list} diff --git a/sql/SQLite3/0.sql b/sql/SQLite3/0.sql index caf3bdbe..0b5f64f7 100644 --- a/sql/SQLite3/0.sql +++ b/sql/SQLite3/0.sql @@ -101,8 +101,8 @@ create table arsse_labels( ); create index arsse_label_names on arsse_labels(name); --- author labels ("categories" in RSS/Atom parlance) associated with newsfeed entries -create table arsse_tags( +-- author categories associated with newsfeed entries +create table arsse_categories( article integer not null references arsse_articles(id) on delete cascade, name TEXT );