Fix tagging rule match when user a custom reading speed

By default, we assume the reading speed is 200 word per minute (WPM) when we save an entry.
User can change that value in the config and the rendering is properly performed with the user reading speed.
BUT, when the matching rule is applied, it uses the default reading time defined in the entry without applying the custom reading speed of the user.
This should fix that bug.

Also update the `wallabag:tag:all` to fix the bug when tagging all entries.
This commit is contained in:
Jeremy Benoist 2022-03-02 19:11:32 +01:00
parent 32aa8e8fd6
commit 5c4993832e
No known key found for this signature in database
GPG Key ID: BCA73962457ACC3C
5 changed files with 82 additions and 9 deletions

View File

@ -41,7 +41,7 @@ class TagAllCommand extends ContainerAwareCommand
$entries = $tagger->tagAllForUser($user); $entries = $tagger->tagAllForUser($user);
$io->text('Persist entries... '); $io->text('Persist ' . \count($entries) . ' entries... ');
$em = $this->getDoctrine()->getManager(); $em = $this->getDoctrine()->getManager();
foreach ($entries as $entry) { foreach ($entries as $entry) {

View File

@ -45,7 +45,7 @@ class ConfigFixtures extends Fixture implements DependentFixtureInterface
$emptyConfig = new Config($this->getReference('empty-user')); $emptyConfig = new Config($this->getReference('empty-user'));
$emptyConfig->setTheme('material'); $emptyConfig->setTheme('material');
$emptyConfig->setItemsPerPage(10); $emptyConfig->setItemsPerPage(10);
$emptyConfig->setReadingSpeed(200); $emptyConfig->setReadingSpeed(100);
$emptyConfig->setLanguage('en'); $emptyConfig->setLanguage('en');
$emptyConfig->setPocketConsumerKey(null); $emptyConfig->setPocketConsumerKey(null);
$emptyConfig->setActionMarkAsRead(0); $emptyConfig->setActionMarkAsRead(0);

View File

@ -43,6 +43,20 @@ class TaggingRuleFixtures extends Fixture implements DependentFixtureInterface
$manager->persist($tr4); $manager->persist($tr4);
$tr5 = new TaggingRule();
$tr5->setRule('readingTime <= 5');
$tr5->setTags(['shortread']);
$tr5->setConfig($this->getReference('empty-config'));
$manager->persist($tr5);
$tr6 = new TaggingRule();
$tr6->setRule('readingTime > 5');
$tr6->setTags(['longread']);
$tr6->setConfig($this->getReference('empty-config'));
$manager->persist($tr6);
$manager->flush(); $manager->flush();
} }

View File

@ -35,8 +35,10 @@ class RuleBasedTagger
{ {
$rules = $this->getRulesForUser($entry->getUser()); $rules = $this->getRulesForUser($entry->getUser());
$clonedEntry = $this->fixEntry($entry);
foreach ($rules as $rule) { foreach ($rules as $rule) {
if (!$this->rulerz->satisfies($entry, $rule->getRule())) { if (!$this->rulerz->satisfies($clonedEntry, $rule->getRule())) {
continue; continue;
} }
@ -61,14 +63,22 @@ class RuleBasedTagger
public function tagAllForUser(User $user) public function tagAllForUser(User $user)
{ {
$rules = $this->getRulesForUser($user); $rules = $this->getRulesForUser($user);
$entries = []; $entriesToUpdate = [];
$tagsCache = []; $tagsCache = [];
foreach ($rules as $rule) { $entries = $this->entryRepository
$qb = $this->entryRepository->getBuilderForAllByUser($user->getId()); ->getBuilderForAllByUser($user->getId())
$entries = $this->rulerz->filter($qb, $rule->getRule()); ->getQuery()
->getResult();
foreach ($entries as $entry) {
$clonedEntry = $this->fixEntry($entry);
foreach ($rules as $rule) {
if (!$this->rulerz->satisfies($clonedEntry, $rule->getRule())) {
continue;
}
foreach ($entries as $entry) {
foreach ($rule->getTags() as $label) { foreach ($rule->getTags() as $label) {
// avoid new tag duplicate by manually caching them // avoid new tag duplicate by manually caching them
if (!isset($tagsCache[$label])) { if (!isset($tagsCache[$label])) {
@ -78,11 +88,13 @@ class RuleBasedTagger
$tag = $tagsCache[$label]; $tag = $tagsCache[$label];
$entry->addTag($tag); $entry->addTag($tag);
$entriesToUpdate[] = $entry;
} }
} }
} }
return $entries; return $entriesToUpdate;
} }
/** /**
@ -114,4 +126,15 @@ class RuleBasedTagger
{ {
return $user->getConfig()->getTaggingRules(); return $user->getConfig()->getTaggingRules();
} }
/**
* Update reading time on the fly to match the proper words per minute from the user.
*/
private function fixEntry(Entry $entry)
{
$clonedEntry = clone $entry;
$clonedEntry->setReadingTime($entry->getReadingTime() / $entry->getUser()->getConfig()->getReadingSpeed() * 200);
return $clonedEntry;
}
} }

View File

@ -175,6 +175,42 @@ class EntryControllerTest extends WallabagCoreTestCase
$client->getContainer()->get('craue_config')->set('store_article_headers', 0); $client->getContainer()->get('craue_config')->set('store_article_headers', 0);
} }
/**
* @group NetworkCalls
*/
public function testPostNewOkWithTaggingRules()
{
$this->logInAs('empty');
$client = $this->getClient();
$crawler = $client->request('GET', '/new');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$form = $crawler->filter('form[name=entry]')->form();
$data = [
'entry[url]' => $this->url,
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$content = $client->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('WallabagCoreBundle:Entry')
->findByUrlAndUserId($this->url, $this->getLoggedInUserId());
$tags = $content->getTagsLabel();
/*
* Without the custom reading speed of `empty` user, it'll be inversed
*/
$this->assertContains('longread', $tags);
$this->assertNotContains('shortread', $tags);
}
/** /**
* @group NetworkCalls * @group NetworkCalls
*/ */