1
1
Fork 0
mirror of https://code.mensbeam.com/MensBeam/Arsse.git synced 2024-12-22 13:12:41 +00:00

Set marks for filtered articles on feed refresh

This commit is contained in:
J. King 2021-01-13 14:54:22 -05:00
parent 7a6186f2d7
commit 618fd67f80
2 changed files with 61 additions and 19 deletions

View file

@ -1118,8 +1118,9 @@ class Database {
$icon = $this->db->prepare("INSERT INTO arsse_icons(url, type, data) values(?, ?, ?)", "str", "str", "blob")->run($feed->iconUrl, $feed->iconType, $feed->iconData)->lastId();
}
}
// actually perform updates
foreach ($feed->newItems as $article) {
$articleMap = [];
// actually perform updates, starting with inserting new articles
foreach ($feed->newItems as $k => $article) {
$articleID = $qInsertArticle->run(
$article->url,
$article->title,
@ -1133,14 +1134,20 @@ class Database {
$article->titleContentHash,
$feedID
)->lastId();
// note the new ID for later use
$articleMap[$k] = $articleID;
// insert any enclosures
if ($article->enclosureUrl) {
$qInsertEnclosure->run($articleID, $article->enclosureUrl, $article->enclosureType);
}
// insert any categories
foreach ($article->categories as $c) {
$qInsertCategory->run($articleID, $c);
}
// assign a new edition ID to the article
$qInsertEdition->run($articleID);
}
// next update existing artricles which have been edited
foreach ($feed->changedItems as $articleID => $article) {
$qUpdateArticle->run(
$article->url,
@ -1155,6 +1162,7 @@ class Database {
$article->titleContentHash,
$articleID
);
// delete all enclosures and categories and re-insert them
$qDeleteEnclosures->run($articleID);
$qDeleteCategories->run($articleID);
if ($article->enclosureUrl) {
@ -1163,9 +1171,33 @@ class Database {
foreach ($article->categories as $c) {
$qInsertCategory->run($articleID, $c);
}
// assign a new edition ID to this version of the article
$qInsertEdition->run($articleID);
$qClearReadMarks->run($articleID);
}
// hide or unhide any filtered articles
foreach ($feed->filteredItems as $user => $filterData) {
$hide = [];
$unhide = [];
foreach ($filterData['new'] as $index => $keep) {
if (!$keep) {
$hide[] = $articleMap[$index];
}
}
foreach ($filterData['changed'] as $article => $keep) {
if (!$keep) {
$hide[] = $article;
} else {
$unhide[] = $article;
}
}
if ($hide) {
$this->articleMark($user, ['hidden' => true], (new Context)->articles($hide), false);
}
if ($unhide) {
$this->articleMark($user, ['hidden' => false], (new Context)->articles($unhide), false);
}
}
// lastly update the feed database itself with updated information.
$this->db->prepareArray(
"UPDATE arsse_feeds SET title = ?, source = ?, updated = CURRENT_TIMESTAMP, modified = ?, etag = ?, err_count = 0, err_msg = '', next_fetch = ?, size = ?, icon = ? WHERE id = ?",
@ -1693,8 +1725,9 @@ class Database {
* @param string $user The user who owns the articles to be modified
* @param array $data An associative array of properties to modify. Anything not specified will remain unchanged
* @param Context $context The query context to match articles against
* @param bool $updateTimestamp Whether to also update the timestamp. This should only be false if a mark is changed as a result of an automated action not taken by the user
*/
public function articleMark(string $user, array $data, Context $context = null): int {
public function articleMark(string $user, array $data, Context $context = null, bool $updateTimestamp = true): int {
$data = [
'read' => $data['read'] ?? null,
'starred' => $data['starred'] ?? null,
@ -1743,7 +1776,11 @@ class Database {
$this->db->prepare($q->getQuery(), $q->getTypes())->run($q->getValues());
}
// finally set the modification date for all touched marks and return the number of affected marks
$out = $this->db->query("UPDATE arsse_marks set modified = CURRENT_TIMESTAMP, touched = 0 where touched = 1")->changes();
if ($updateTimestamp) {
$out = $this->db->query("UPDATE arsse_marks set modified = CURRENT_TIMESTAMP, touched = 0 where touched = 1")->changes();
} else {
$out = $this->db->query("UPDATE arsse_marks set touched = 0 where touched = 1")->changes();
}
} else {
if (!isset($data['read']) && ($context->edition() || $context->editions())) {
// get the articles associated with the requested editions
@ -1763,7 +1800,10 @@ class Database {
return isset($v);
});
[$set, $setTypes, $setValues] = $this->generateSet($data, ['read' => "bool", 'starred' => "bool", 'hidden' => "bool", 'note' => "str"]);
$q->setBody("UPDATE arsse_marks set $set, modified = CURRENT_TIMESTAMP where article in(select article from target_articles) and subscription in(select distinct subscription from target_articles)", $setTypes, $setValues);
if ($updateTimestamp) {
$set .= ", modified = CURRENT_TIMESTAMP";
}
$q->setBody("UPDATE arsse_marks set $set where article in(select article from target_articles) and subscription in(select distinct subscription from target_articles)", $setTypes, $setValues);
$out = $this->db->prepare($q->getQuery(), $q->getTypes())->run($q->getValues())->changes();
}
$tr->commit();

View file

@ -80,7 +80,7 @@ trait SeriesFeed {
[3,'john.doe@example.com',3,'\w+',null],
[4,'john.doe@example.com',4,'\w+',"["], // invalid rule leads to both rules being ignored
[5,'john.doe@example.com',5,null,'and/or'],
[6,'jane.doe@example.com',1,'^(?i)[a-z]+','bluberry'],
[6,'jane.doe@example.com',1,'^(?i)[a-z]+','3|6'],
],
],
'arsse_articles' => [
@ -129,19 +129,20 @@ trait SeriesFeed {
'subscription' => "int",
'read' => "bool",
'starred' => "bool",
'hidden' => "bool",
'modified' => "datetime",
],
'rows' => [
// Jane's marks
[1,6,1,0,$past],
[2,6,1,0,$past],
[3,6,1,1,$past],
[4,6,1,0,$past],
[5,6,1,1,$past],
[1,6,1,0,0,$past],
[2,6,1,0,0,$past],
[3,6,1,1,0,$past],
[4,6,1,0,1,$past],
[5,6,1,1,0,$past],
// John's marks
[1,1,1,0,$past],
[3,1,1,0,$past],
[4,1,0,1,$past],
[1,1,1,0,0,$past],
[3,1,1,0,0,$past],
[4,1,0,1,0,$past],
],
],
'arsse_enclosures' => [
@ -210,7 +211,7 @@ trait SeriesFeed {
public function provideFilterRules(): iterable {
return [
[1, ['jane.doe@example.com' => ['keep' => "`^(?i)[a-z]+`u", 'block' => "`bluberry`u"], 'john.doe@example.com' => ['keep' => "", 'block' => "`^Sport$`u"]]],
[1, ['jane.doe@example.com' => ['keep' => "`^(?i)[a-z]+`u", 'block' => "`3|6`u"], 'john.doe@example.com' => ['keep' => "", 'block' => "`^Sport$`u"]]],
[2, []],
[3, ['john.doe@example.com' => ['keep' => '`\w+`u', 'block' => ""]]],
[4, []],
@ -225,7 +226,7 @@ trait SeriesFeed {
$state = $this->primeExpectations($this->data, [
'arsse_articles' => ["id", "feed","url","title","author","published","edited","content","guid","url_title_hash","url_content_hash","title_content_hash","modified"],
'arsse_editions' => ["id","article","modified"],
'arsse_marks' => ["subscription","article","read","starred","modified"],
'arsse_marks' => ["subscription","article","read","starred","hidden","modified"],
'arsse_feeds' => ["id","size"],
]);
$state['arsse_articles']['rows'][2] = [3,1,'http://example.com/3','Article title 3 (updated)','','2000-01-03 00:00:00','2000-01-03 00:00:00','<p>Article content 3</p>','31a6594500a48b59fcc8a075ce82b946c9c3c782460d088bd7b8ef3ede97ad92','6cc99be662ef3486fef35a890123f18d74c29a32d714802d743c5b4ef713315a','b278380e984cefe63f0e412b88ffc9cb0befdfa06fdc00bace1da99a8daff406','d5faccc13bf8267850a1e8e61f95950a0f34167df2c8c58011c0aaa6367026ac',$now];
@ -236,9 +237,10 @@ trait SeriesFeed {
[7,3,$now],
[8,4,$now],
]);
$state['arsse_marks']['rows'][2] = [6,3,0,1,$now];
$state['arsse_marks']['rows'][3] = [6,4,0,0,$now];
$state['arsse_marks']['rows'][6] = [1,3,0,0,$now];
$state['arsse_marks']['rows'][2] = [6,3,0,1,1,$now];
$state['arsse_marks']['rows'][3] = [6,4,0,0,0,$now];
$state['arsse_marks']['rows'][6] = [1,3,0,0,0,$now];
$state['arsse_marks']['rows'][] = [6,8,0,0,1,null];
$state['arsse_feeds']['rows'][0] = [1,6];
$this->compareExpectations(static::$drv, $state);
// update a valid feed which previously had an error