Merge pull request #4026 from wallabag/3760-ignorelist-db

Move Ignore Origin rules to database
This commit is contained in:
Kevin Decherf 2020-04-26 15:39:57 +02:00 committed by GitHub
commit 0e8a0f77d0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
54 changed files with 2384 additions and 80 deletions

View file

@ -0,0 +1,64 @@
<?php
declare(strict_types=1);
namespace Application\Migrations;
use Doctrine\DBAL\Schema\Schema;
use Wallabag\CoreBundle\Doctrine\WallabagMigration;
/**
* Add tables for the ignore origin rules.
*/
final class Version20190826204730 extends WallabagMigration
{
public function up(Schema $schema): void
{
if (false === $schema->hasTable($this->getTable('ignore_origin_user_rule'))) {
$userTable = $schema->createTable($this->getTable('ignore_origin_user_rule', true));
$userTable->addColumn('id', 'integer', ['autoincrement' => true]);
$userTable->addColumn('config_id', 'integer');
$userTable->addColumn('rule', 'string', ['length' => 255]);
$userTable->addIndex(['config_id'], 'idx_config');
$userTable->setPrimaryKey(['id']);
$userTable->addForeignKeyConstraint($this->getTable('config'), ['config_id'], ['id'], [], 'fk_config');
if ('postgresql' === $this->connection->getDatabasePlatform()->getName()) {
$schema->dropSequence('ignore_origin_user_rule_id_seq');
$schema->createSequence('ignore_origin_user_rule_id_seq');
}
}
if (false === $schema->hasTable($this->getTable('ignore_origin_instance_rule'))) {
$instanceTable = $schema->createTable($this->getTable('ignore_origin_instance_rule', true));
$instanceTable->addColumn('id', 'integer', ['autoincrement' => true]);
$instanceTable->addColumn('rule', 'string', ['length' => 255]);
$instanceTable->setPrimaryKey(['id']);
if ('postgresql' === $this->connection->getDatabasePlatform()->getName()) {
$schema->dropSequence('ignore_origin_instance_rule_id_seq');
$schema->createSequence('ignore_origin_instance_rule_id_seq');
}
}
}
public function postUp(Schema $schema): void
{
foreach ($this->container->getParameter('wallabag_core.default_ignore_origin_instance_rules') as $entity) {
$previous_rule = $this->container
->get('doctrine.orm.default_entity_manager')
->getConnection()
->fetchArray('SELECT * FROM ' . $this->getTable('ignore_origin_instance_rule') . " WHERE rule = '" . $entity['rule'] . "'");
if (false === $previous_rule) {
$this->addSql('INSERT INTO ' . $this->getTable('ignore_origin_instance_rule') . " (rule) VALUES ('" . $entity['rule'] . "');");
}
}
}
public function down(Schema $schema): void
{
$schema->dropTable($this->getTable('ignore_origin_user_rule'));
$schema->dropTable($this->getTable('ignore_origin_instance_rule'));
}
}

View file

@ -79,4 +79,5 @@ security:
- { path: ^/annotations, roles: ROLE_USER }
- { path: ^/2fa, role: IS_AUTHENTICATED_2FA_IN_PROGRESS }
- { path: ^/users, roles: ROLE_SUPER_ADMIN }
- { path: ^/ignore-origin-instance-rules, roles: ROLE_SUPER_ADMIN }
- { path: ^/, roles: ROLE_USER }

View file

@ -165,6 +165,14 @@ wallabag_core:
value: 0
section: entry
default_ignore_origin_instance_rules:
-
rule: host = "feedproxy.google.com"
-
rule: host = "feeds.reuters.com"
-
rule: _all ~ "https?://www\.lemonde\.fr/tiny.*"
wallabag_user:
registration_enabled: "%fosuser_registration%"

View file

@ -12,6 +12,7 @@ use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Style\SymfonyStyle;
use Wallabag\CoreBundle\Entity\IgnoreOriginInstanceRule;
use Wallabag\CoreBundle\Entity\InternalSetting;
class InstallCommand extends ContainerAwareCommand
@ -277,6 +278,7 @@ class InstallCommand extends ContainerAwareCommand
// cleanup before insert new stuff
$em->createQuery('DELETE FROM WallabagCoreBundle:InternalSetting')->execute();
$em->createQuery('DELETE FROM WallabagCoreBundle:IgnoreOriginInstanceRule')->execute();
foreach ($this->getContainer()->getParameter('wallabag_core.default_internal_settings') as $setting) {
$newSetting = new InternalSetting();
@ -286,6 +288,12 @@ class InstallCommand extends ContainerAwareCommand
$em->persist($newSetting);
}
foreach ($this->getContainer()->getParameter('wallabag_core.default_ignore_origin_instance_rules') as $ignore_origin_instance_rule) {
$newIgnoreOriginInstanceRule = new IgnoreOriginInstanceRule();
$newIgnoreOriginInstanceRule->setRule($ignore_origin_instance_rule['rule']);
$em->persist($newIgnoreOriginInstanceRule);
}
$em->flush();
$this->io->text('<info>Config successfully setup.</info>');

View file

@ -14,10 +14,13 @@ use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Validator\Constraints\Locale as LocaleConstraint;
use Wallabag\CoreBundle\Entity\Config;
use Wallabag\CoreBundle\Entity\IgnoreOriginUserRule;
use Wallabag\CoreBundle\Entity\RuleInterface;
use Wallabag\CoreBundle\Entity\TaggingRule;
use Wallabag\CoreBundle\Form\Type\ChangePasswordType;
use Wallabag\CoreBundle\Form\Type\ConfigType;
use Wallabag\CoreBundle\Form\Type\FeedType;
use Wallabag\CoreBundle\Form\Type\IgnoreOriginUserRuleType;
use Wallabag\CoreBundle\Form\Type\TaggingRuleImportType;
use Wallabag\CoreBundle\Form\Type\TaggingRuleType;
use Wallabag\CoreBundle\Form\Type\UserInformationType;
@ -173,6 +176,40 @@ class ConfigController extends Controller
return $this->redirect($this->generateUrl('config') . '#set5');
}
// handle ignore origin rules
$ignoreOriginUserRule = new IgnoreOriginUserRule();
$action = $this->generateUrl('config') . '#set6';
if ($request->query->has('ignore-origin-user-rule')) {
$ignoreOriginUserRule = $this->getDoctrine()
->getRepository('WallabagCoreBundle:IgnoreOriginUserRule')
->find($request->query->get('ignore-origin-user-rule'));
if ($this->getUser()->getId() !== $ignoreOriginUserRule->getConfig()->getUser()->getId()) {
return $this->redirect($action);
}
$action = $this->generateUrl('config', [
'ignore-origin-user-rule' => $ignoreOriginUserRule->getId(),
]) . '#set6';
}
$newIgnoreOriginUserRule = $this->createForm(IgnoreOriginUserRuleType::class, $ignoreOriginUserRule, ['action' => $action]);
$newIgnoreOriginUserRule->handleRequest($request);
if ($newIgnoreOriginUserRule->isSubmitted() && $newIgnoreOriginUserRule->isValid()) {
$ignoreOriginUserRule->setConfig($config);
$em->persist($ignoreOriginUserRule);
$em->flush();
$this->addFlash(
'notice',
'flashes.config.notice.ignore_origin_rules_updated'
);
return $this->redirect($this->generateUrl('config') . '#set6');
}
return $this->render('WallabagCoreBundle:Config:index.html.twig', [
'form' => [
'config' => $configForm->createView(),
@ -181,6 +218,7 @@ class ConfigController extends Controller
'user' => $userForm->createView(),
'new_tagging_rule' => $newTaggingRule->createView(),
'import_tagging_rule' => $taggingRulesImportform->createView(),
'new_ignore_origin_user_rule' => $newIgnoreOriginUserRule->createView(),
],
'feed' => [
'username' => $user->getUsername(),
@ -447,6 +485,43 @@ class ConfigController extends Controller
return $this->redirect($this->generateUrl('config') . '?tagging-rule=' . $rule->getId() . '#set5');
}
/**
* Deletes an ignore origin rule and redirect to the config homepage.
*
* @Route("/ignore-origin-user-rule/delete/{id}", requirements={"id" = "\d+"}, name="delete_ignore_origin_rule")
*
* @return RedirectResponse
*/
public function deleteIgnoreOriginRuleAction(IgnoreOriginUserRule $rule)
{
$this->validateRuleAction($rule);
$em = $this->getDoctrine()->getManager();
$em->remove($rule);
$em->flush();
$this->addFlash(
'notice',
'flashes.config.notice.ignore_origin_rules_deleted'
);
return $this->redirect($this->generateUrl('config') . '#set6');
}
/**
* Edit an ignore origin rule.
*
* @Route("/ignore-origin-user-rule/edit/{id}", requirements={"id" = "\d+"}, name="edit_ignore_origin_rule")
*
* @return RedirectResponse
*/
public function editIgnoreOriginRuleAction(IgnoreOriginUserRule $rule)
{
$this->validateRuleAction($rule);
return $this->redirect($this->generateUrl('config') . '?ignore-origin-user-rule=' . $rule->getId() . '#set6');
}
/**
* Remove all annotations OR tags OR entries for the current user.
*
@ -659,10 +734,10 @@ class ConfigController extends Controller
/**
* Validate that a rule can be edited/deleted by the current user.
*/
private function validateRuleAction(TaggingRule $rule)
private function validateRuleAction(RuleInterface $rule)
{
if ($this->getUser()->getId() !== $rule->getConfig()->getUser()->getId()) {
throw $this->createAccessDeniedException('You can not access this tagging rule.');
throw $this->createAccessDeniedException('You can not access this rule.');
}
}

View file

@ -0,0 +1,138 @@
<?php
namespace Wallabag\CoreBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Wallabag\CoreBundle\Entity\IgnoreOriginInstanceRule;
/**
* IgnoreOriginInstanceRuleController controller.
*
* @Route("/ignore-origin-instance-rules")
*/
class IgnoreOriginInstanceRuleController extends Controller
{
/**
* Lists all IgnoreOriginInstanceRule entities.
*
* @Route("/", name="ignore_origin_instance_rules_index", methods={"GET"})
*/
public function indexAction()
{
$rules = $this->get('wallabag_core.ignore_origin_instance_rule_repository')->findAll();
return $this->render('WallabagCoreBundle:IgnoreOriginInstanceRule:index.html.twig', [
'rules' => $rules,
]);
}
/**
* Creates a new ignore origin instance rule entity.
*
* @Route("/new", name="ignore_origin_instance_rules_new", methods={"GET", "POST"})
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function newAction(Request $request)
{
$ignoreOriginInstanceRule = new IgnoreOriginInstanceRule();
$form = $this->createForm('Wallabag\CoreBundle\Form\Type\IgnoreOriginInstanceRuleType', $ignoreOriginInstanceRule);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($ignoreOriginInstanceRule);
$em->flush();
$this->get('session')->getFlashBag()->add(
'notice',
$this->get('translator')->trans('flashes.ignore_origin_instance_rule.notice.added')
);
return $this->redirectToRoute('ignore_origin_instance_rules_index');
}
return $this->render('WallabagCoreBundle:IgnoreOriginInstanceRule:new.html.twig', [
'rule' => $ignoreOriginInstanceRule,
'form' => $form->createView(),
]);
}
/**
* Displays a form to edit an existing ignore origin instance rule entity.
*
* @Route("/{id}/edit", name="ignore_origin_instance_rules_edit", methods={"GET", "POST"})
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function editAction(Request $request, IgnoreOriginInstanceRule $ignoreOriginInstanceRule)
{
$deleteForm = $this->createDeleteForm($ignoreOriginInstanceRule);
$editForm = $this->createForm('Wallabag\CoreBundle\Form\Type\IgnoreOriginInstanceRuleType', $ignoreOriginInstanceRule);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($ignoreOriginInstanceRule);
$em->flush();
$this->get('session')->getFlashBag()->add(
'notice',
$this->get('translator')->trans('flashes.ignore_origin_instance_rule.notice.updated')
);
return $this->redirectToRoute('ignore_origin_instance_rules_index');
}
return $this->render('WallabagCoreBundle:IgnoreOriginInstanceRule:edit.html.twig', [
'rule' => $ignoreOriginInstanceRule,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
]);
}
/**
* Deletes a site credential entity.
*
* @Route("/{id}", name="ignore_origin_instance_rules_delete", methods={"DELETE"})
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse
*/
public function deleteAction(Request $request, IgnoreOriginInstanceRule $ignoreOriginInstanceRule)
{
$form = $this->createDeleteForm($ignoreOriginInstanceRule);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->get('session')->getFlashBag()->add(
'notice',
$this->get('translator')->trans('flashes.ignore_origin_instance_rule.notice.deleted')
);
$em = $this->getDoctrine()->getManager();
$em->remove($ignoreOriginInstanceRule);
$em->flush();
}
return $this->redirectToRoute('ignore_origin_instance_rules_index');
}
/**
* Creates a form to delete a ignore origin instance rule entity.
*
* @param IgnoreOriginInstanceRule $ignoreOriginInstanceRule The ignore origin instance rule entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createDeleteForm(IgnoreOriginInstanceRule $ignoreOriginInstanceRule)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('ignore_origin_instance_rules_delete', ['id' => $ignoreOriginInstanceRule->getId()]))
->setMethod('DELETE')
->getForm()
;
}
}

View file

@ -0,0 +1,36 @@
<?php
namespace Wallabag\CoreBundle\DataFixtures;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Wallabag\CoreBundle\Entity\IgnoreOriginInstanceRule;
class IgnoreOriginInstanceRuleFixtures extends Fixture implements ContainerAwareInterface
{
/**
* @var ContainerInterface
*/
private $container;
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
/**
* {@inheritdoc}
*/
public function load(ObjectManager $manager)
{
foreach ($this->container->getParameter('wallabag_core.default_ignore_origin_instance_rules') as $ignore_origin_instance_rule) {
$newIgnoreOriginInstanceRule = new IgnoreOriginInstanceRule();
$newIgnoreOriginInstanceRule->setRule($ignore_origin_instance_rule['rule']);
$manager->persist($newIgnoreOriginInstanceRule);
}
$manager->flush();
}
}

View file

@ -0,0 +1,36 @@
<?php
namespace Wallabag\CoreBundle\DataFixtures;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Wallabag\CoreBundle\Entity\IgnoreOriginUserRule;
use Wallabag\UserBundle\DataFixtures\UserFixtures;
class IgnoreOriginUserRuleFixtures extends Fixture implements DependentFixtureInterface
{
/**
* {@inheritdoc}
*/
public function load(ObjectManager $manager)
{
$rule = new IgnoreOriginUserRule();
$rule->setRule('host = "example.fr"');
$rule->setConfig($this->getReference('admin-user')->getConfig());
$manager->persist($rule);
$manager->flush();
}
/**
* {@inheritdoc}
*/
public function getDependencies()
{
return [
UserFixtures::class,
];
}
}

View file

@ -65,6 +65,13 @@ class Configuration implements ConfigurationInterface
->end()
->scalarNode('encryption_key_path')
->end()
->arrayNode('default_ignore_origin_instance_rules')
->prototype('array')
->children()
->scalarNode('rule')->end()
->end()
->end()
->end()
->end()
;

View file

@ -30,6 +30,7 @@ class WallabagCoreExtension extends Extension
$container->setParameter('wallabag_core.api_limit_mass_actions', $config['api_limit_mass_actions']);
$container->setParameter('wallabag_core.default_internal_settings', $config['default_internal_settings']);
$container->setParameter('wallabag_core.site_credentials.encryption_key_path', $config['encryption_key_path']);
$container->setParameter('wallabag_core.default_ignore_origin_instance_rules', $config['default_ignore_origin_instance_rules']);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
$loader->load('services.yml');

View file

@ -119,6 +119,12 @@ class Config
*/
private $taggingRules;
/**
* @ORM\OneToMany(targetEntity="Wallabag\CoreBundle\Entity\IgnoreOriginUserRule", mappedBy="config", cascade={"remove"})
* @ORM\OrderBy({"id" = "ASC"})
*/
private $ignoreOriginRules;
/*
* @param User $user
*/
@ -126,6 +132,7 @@ class Config
{
$this->user = $user;
$this->taggingRules = new ArrayCollection();
$this->ignoreOriginRules = new ArrayCollection();
}
/**
@ -387,4 +394,22 @@ class Config
{
return $this->taggingRules;
}
/**
* @return Config
*/
public function addIgnoreOriginRule(IgnoreOriginUserRule $rule)
{
$this->ignoreOriginRules[] = $rule;
return $this;
}
/**
* @return ArrayCollection<IgnoreOriginUserRule>
*/
public function getIgnoreOriginRules()
{
return $this->ignoreOriginRules;
}
}

View file

@ -0,0 +1,70 @@
<?php
namespace Wallabag\CoreBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\RulerZ\Validator\Constraints as RulerZAssert;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Ignore Origin rule.
*
* @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\IgnoreOriginInstanceRuleRepository")
* @ORM\Table(name="`ignore_origin_instance_rule`")
*/
class IgnoreOriginInstanceRule implements IgnoreOriginRuleInterface, RuleInterface
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @Assert\NotBlank()
* @Assert\Length(max=255)
* @RulerZAssert\ValidRule(
* allowed_variables={"host","_all"},
* allowed_operators={"=","~"}
* )
* @ORM\Column(name="rule", type="string", nullable=false)
*/
private $rule;
/**
* Get id.
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set rule.
*
* @return IgnoreOriginRuleInterface
*/
public function setRule(string $rule)
{
$this->rule = $rule;
return $this;
}
/**
* Get rule.
*
* @return string
*/
public function getRule()
{
return $this->rule;
}
}

View file

@ -0,0 +1,12 @@
<?php
namespace Wallabag\CoreBundle\Entity;
interface IgnoreOriginRuleInterface
{
public function getId();
public function setRule(string $rule);
public function getRule();
}

View file

@ -0,0 +1,97 @@
<?php
namespace Wallabag\CoreBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\RulerZ\Validator\Constraints as RulerZAssert;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Ignore Origin rule.
*
* @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\IgnoreOriginUserRuleRepository")
* @ORM\Table(name="`ignore_origin_user_rule`")
*/
class IgnoreOriginUserRule implements IgnoreOriginRuleInterface, RuleInterface
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @Assert\NotBlank()
* @Assert\Length(max=255)
* @RulerZAssert\ValidRule(
* allowed_variables={"host","_all"},
* allowed_operators={"=","~"}
* )
* @ORM\Column(name="rule", type="string", nullable=false)
*/
private $rule;
/**
* @ORM\ManyToOne(targetEntity="Wallabag\CoreBundle\Entity\Config", inversedBy="ignoreOriginRules")
*/
private $config;
/**
* Get id.
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set rule.
*
* @return IgnoreOriginRuleInterface
*/
public function setRule(string $rule)
{
$this->rule = $rule;
return $this;
}
/**
* Get rule.
*
* @return string
*/
public function getRule()
{
return $this->rule;
}
/**
* Set config.
*
* @return IgnoreOriginUserRule
*/
public function setConfig(Config $config)
{
$this->config = $config;
return $this;
}
/**
* Get config.
*
* @return Config
*/
public function getConfig()
{
return $this->config;
}
}

View file

@ -0,0 +1,7 @@
<?php
namespace Wallabag\CoreBundle\Entity;
interface RuleInterface
{
}

View file

@ -17,7 +17,7 @@ use Symfony\Component\Validator\Constraints as Assert;
* @ORM\Table(name="`tagging_rule`")
* @ORM\Entity
*/
class TaggingRule
class TaggingRule implements RuleInterface
{
/**
* @var int

View file

@ -0,0 +1,37 @@
<?php
namespace Wallabag\CoreBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class IgnoreOriginInstanceRuleType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('rule', TextType::class, [
'required' => true,
'label' => 'config.form_rules.rule_label',
])
->add('save', SubmitType::class, [
'label' => 'config.form.save',
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => 'Wallabag\CoreBundle\Entity\IgnoreOriginInstanceRule',
]);
}
public function getBlockPrefix()
{
return 'ignore_origin_instance_rule';
}
}

View file

@ -0,0 +1,37 @@
<?php
namespace Wallabag\CoreBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class IgnoreOriginUserRuleType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('rule', TextType::class, [
'required' => true,
'label' => 'config.form_rules.rule_label',
])
->add('save', SubmitType::class, [
'label' => 'config.form.save',
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => 'Wallabag\CoreBundle\Entity\IgnoreOriginUserRule',
]);
}
public function getBlockPrefix()
{
return 'ignore_origin_user_rule';
}
}

View file

@ -19,6 +19,7 @@ class ContentProxy
{
protected $graby;
protected $tagger;
protected $ignoreOriginProcessor;
protected $validator;
protected $logger;
protected $mimeGuesser;
@ -26,10 +27,11 @@ class ContentProxy
protected $eventDispatcher;
protected $storeArticleHeaders;
public function __construct(Graby $graby, RuleBasedTagger $tagger, ValidatorInterface $validator, LoggerInterface $logger, $fetchingErrorMessage, $storeArticleHeaders = false)
public function __construct(Graby $graby, RuleBasedTagger $tagger, RuleBasedIgnoreOriginProcessor $ignoreOriginProcessor, ValidatorInterface $validator, LoggerInterface $logger, $fetchingErrorMessage, $storeArticleHeaders = false)
{
$this->graby = $graby;
$this->tagger = $tagger;
$this->ignoreOriginProcessor = $ignoreOriginProcessor;
$this->validator = $validator;
$this->logger = $logger;
$this->mimeGuesser = new MimeTypeExtensionGuesser();
@ -356,7 +358,7 @@ class ContentProxy
$diff_keys = array_keys($diff);
sort($diff_keys);
if ($this->ignoreUrl($entry->getUrl())) {
if ($this->ignoreOriginProcessor->process($entry)) {
$entry->setUrl($url);
return false;
@ -395,41 +397,6 @@ class ContentProxy
}
}
/**
* Check entry url against an ignore list to replace with content url.
*
* XXX: move the ignore list in the database to let users handle it
*
* @param string $url url to test
*
* @return bool true if url matches ignore list otherwise false
*/
private function ignoreUrl($url)
{
$ignored_hosts = ['feedproxy.google.com', 'feeds.reuters.com'];
$ignored_patterns = ['https?://www\.lemonde\.fr/tiny.*'];
$parsed_url = parse_url($url);
$filtered = array_filter($ignored_hosts, function ($var) use ($parsed_url) {
return $var === $parsed_url['host'];
});
if ([] !== $filtered) {
return true;
}
$filtered = array_filter($ignored_patterns, function ($var) use ($url) {
return preg_match("`$var`i", $url);
});
if ([] !== $filtered) {
return true;
}
return false;
}
/**
* Validate that the given content has at least a title, an html and a url.
*

View file

@ -0,0 +1,50 @@
<?php
namespace Wallabag\CoreBundle\Helper;
use Psr\Log\LoggerInterface;
use RulerZ\RulerZ;
use Wallabag\CoreBundle\Entity\Entry;
use Wallabag\CoreBundle\Repository\IgnoreOriginInstanceRuleRepository;
class RuleBasedIgnoreOriginProcessor
{
protected $rulerz;
protected $logger;
protected $ignoreOriginInstanceRuleRepository;
public function __construct(RulerZ $rulerz, LoggerInterface $logger, IgnoreOriginInstanceRuleRepository $ignoreOriginInstanceRuleRepository)
{
$this->rulerz = $rulerz;
$this->logger = $logger;
$this->ignoreOriginInstanceRuleRepository = $ignoreOriginInstanceRuleRepository;
}
/**
* @param Entry $entry Entry to process
*
* @return bool
*/
public function process(Entry $entry)
{
$url = $entry->getUrl();
$userRules = $entry->getUser()->getConfig()->getIgnoreOriginRules()->toArray();
$rules = array_merge($this->ignoreOriginInstanceRuleRepository->findAll(), $userRules);
$parsed_url = parse_url($url);
// We add the former url as a new key _all for pattern matching
$parsed_url['_all'] = $url;
foreach ($rules as $rule) {
if ($this->rulerz->satisfies($parsed_url, $rule->getRule())) {
$this->logger->info('Origin url matching ignore rule.', [
'rule' => $rule->getRule(),
]);
return true;
}
}
return false;
}
}

View file

@ -0,0 +1,23 @@
<?php
namespace Wallabag\CoreBundle\Operator\PHP;
/**
* Provides a "~" operator used for ignore origin rules.
*
* It asserts that a subject matches a given regexp pattern, in a
* case-insensitive way.
*
* This operator will be used to compile ignore origin rules in PHP, usable
* directly on Entry objects for instance.
* It's registered in RulerZ using a service (wallabag.operator.array.pattern_matches);
*/
class PatternMatches
{
public function __invoke($subject, $pattern)
{
$count = preg_match("`$pattern`i", $subject);
return \is_int($count) && $count > 0;
}
}

View file

@ -0,0 +1,9 @@
<?php
namespace Wallabag\CoreBundle\Repository;
use Doctrine\ORM\EntityRepository;
class IgnoreOriginInstanceRuleRepository extends EntityRepository
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace Wallabag\CoreBundle\Repository;
use Doctrine\ORM\EntityRepository;
class IgnoreOriginUserRuleRepository extends EntityRepository
{
}

View file

@ -92,6 +92,7 @@ services:
arguments:
- "@wallabag_core.graby"
- "@wallabag_core.rule_based_tagger"
- "@wallabag_core.rule_based_ignore_origin_processor"
- "@validator"
- "@logger"
- '%wallabag_core.fetching_error_message%'
@ -110,6 +111,13 @@ services:
- "@wallabag_core.entry_repository"
- "@logger"
wallabag_core.rule_based_ignore_origin_processor:
class: Wallabag\CoreBundle\Helper\RuleBasedIgnoreOriginProcessor
arguments:
- "@rulerz"
- "@logger"
- "@wallabag_core.ignore_origin_instance_rule_repository"
# repository as a service
wallabag_core.entry_repository:
class: Wallabag\CoreBundle\Repository\EntryRepository
@ -131,6 +139,12 @@ services:
calls:
- [ setCrypto, [ "@wallabag_core.helper.crypto_proxy" ] ]
wallabag_core.ignore_origin_instance_rule_repository:
class: Wallabag\CoreBundle\Repository\IgnoreOriginInstanceRuleRepository
factory: [ "@doctrine.orm.default_entity_manager", getRepository ]
arguments:
- WallabagCoreBundle:IgnoreOriginInstanceRule
wallabag_core.helper.entries_export:
class: Wallabag\CoreBundle\Helper\EntriesExport
arguments:
@ -158,6 +172,11 @@ services:
tags:
- { name: rulerz.operator, target: doctrine, operator: notmatches, inline: true }
wallabag.operator.array.pattern_matches:
class: Wallabag\CoreBundle\Operator\PHP\PatternMatches
tags:
- { name: rulerz.operator, target: native, operator: "~" }
wallabag_core.helper.redirect:
class: Wallabag\CoreBundle\Helper\Redirect
arguments:

View file

@ -33,6 +33,7 @@ menu:
back_to_unread: 'Tilbage til de ulæste artikler'
# users_management: 'Users management'
# site_credentials: 'Site credentials'
# ignore_origin_instance_rules: 'Global ignore origin rules'
# quickstart: "Quickstart"
top:
add_new_entry: 'Tilføj ny artikel'
@ -59,6 +60,7 @@ config:
user_info: 'Brugeroplysninger'
password: 'Adgangskode'
# rules: 'Tagging rules'
# ignore_origin: 'Ignore origin rules'
new_user: 'Tilføj bruger'
# reset: 'Reset area'
form:
@ -177,6 +179,24 @@ config:
# and: 'One rule AND another'
# matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
# notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
form_ignore_origin_rules:
# faq:
# title: 'FAQ'
# ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
# ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
# how_to_use_them_title: 'How do I use them?'
# how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
# variables_available_title: 'Which variables and operators can I use to write rules?'
# variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
# meaning: 'Meaning'
# variable_description:
# label: 'Variable'
# host: 'Host of the address'
# _all: 'Full address, mainly for pattern matching'
# operator_description:
# label: 'Operator'
# equal_to: 'Equal to…'
# matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
otp:
# page_title: Two-factor authentication
# app:
@ -617,6 +637,8 @@ flashes:
# otp_disabled: Two-factor authentication disabled
# tagging_rules_imported: Tagging rules imported
# tagging_rules_not_imported: Error while importing tagging rules
# ignore_origin_rules_deleted: 'Ignore origin rule deleted'
# ignore_origin_rules_updated: 'Ignore origin rule updated'
entry:
notice:
# entry_already_saved: 'Entry already saved on %date%'
@ -658,3 +680,8 @@ flashes:
# added: 'Site credential for "%host%" added'
# updated: 'Site credential for "%host%" updated'
# deleted: 'Site credential for "%host%" deleted'
ignore_origin_instance_rule:
notice:
# added: 'Global ignore origin rule added'
# updated: 'Global ignore origin rule updated'
# deleted: 'Global ignore origin rule deleted'

View file

@ -33,6 +33,7 @@ menu:
back_to_unread: 'Zurück zu ungelesenen Artikeln'
users_management: 'Benutzerverwaltung'
site_credentials: 'Zugangsdaten'
# ignore_origin_instance_rules: 'Global ignore origin rules'
quickstart: "Schnelleinstieg"
top:
add_new_entry: 'Neuen Artikel hinzufügen'
@ -59,6 +60,7 @@ config:
user_info: 'Benutzerinformation'
password: 'Kennwort'
rules: 'Tagging-Regeln'
# ignore_origin: 'Ignore origin rules'
new_user: 'Benutzer hinzufügen'
reset: 'Zurücksetzen'
form:
@ -177,6 +179,24 @@ config:
and: 'Eine Regel UND eine andere'
matches: 'Testet, ob eine <i>Variable</i> auf eine <i>Suche</i> zutrifft (Groß- und Kleinschreibung wird nicht berücksichtigt).<br />Beispiel: <code>title matches "Fußball"</code>'
notmatches: 'Testet, ob ein <i>Titel</i> nicht auf eine <i>Suche</i> zutrifft (Groß- und Kleinschreibung wird nicht berücksichtigt).<br />Beispiel: <code>title notmatches "Fußball"</code>'
form_ignore_origin_rules:
# faq:
# title: 'FAQ'
# ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
# ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
# how_to_use_them_title: 'How do I use them?'
# how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
# variables_available_title: 'Which variables and operators can I use to write rules?'
# variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
# meaning: 'Meaning'
# variable_description:
# label: 'Variable'
# host: 'Host of the address'
# _all: 'Full address, mainly for pattern matching'
# operator_description:
# label: 'Operator'
# equal_to: 'Equal to…'
# matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
otp:
# page_title: Two-factor authentication
# app:
@ -617,6 +637,8 @@ flashes:
# otp_disabled: Two-factor authentication disabled
# tagging_rules_imported: Tagging rules imported
# tagging_rules_not_imported: Error while importing tagging rules
# ignore_origin_rules_deleted: 'Ignore origin rule deleted'
# ignore_origin_rules_updated: 'Ignore origin rule updated'
entry:
notice:
entry_already_saved: 'Eintrag bereits am %date% gespeichert'
@ -658,3 +680,8 @@ flashes:
added: 'Zugangsdaten für "%host%" hinzugefügt'
updated: 'Zugangsdaten für "%host%" aktualisiert'
deleted: 'Zugangsdaten für "%host%" gelöscht'
ignore_origin_instance_rule:
notice:
# added: 'Global ignore origin rule added'
# updated: 'Global ignore origin rule updated'
# deleted: 'Global ignore origin rule deleted'

View file

@ -33,6 +33,7 @@ menu:
back_to_unread: 'Back to unread articles'
users_management: 'Users management'
site_credentials: 'Site credentials'
ignore_origin_instance_rules: 'Global ignore origin rules'
quickstart: "Quickstart"
top:
add_new_entry: 'Add a new entry'
@ -59,6 +60,7 @@ config:
user_info: 'User information'
password: 'Password'
rules: 'Tagging rules'
ignore_origin: 'Ignore origin rules'
new_user: 'Add a user'
reset: 'Reset area'
form:
@ -177,6 +179,24 @@ config:
and: 'One rule AND another'
matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
form_ignore_origin_rules:
faq:
title: 'FAQ'
ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
how_to_use_them_title: 'How do I use them?'
how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
variables_available_title: 'Which variables and operators can I use to write rules?'
variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
meaning: 'Meaning'
variable_description:
label: 'Variable'
host: 'Host of the address'
_all: 'Full address, mainly for pattern matching'
operator_description:
label: 'Operator'
equal_to: 'Equal to…'
matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
otp:
page_title: Two-factor authentication
app:
@ -594,6 +614,24 @@ site_credential:
delete_confirm: Are you sure?
back_to_list: Back to list
ignore_origin_instance_rule:
page_title: Global ignore origin rules
new_ignore_origin_instance_rule: Create a global ignore origin rule
edit_ignore_origin_instance_rule: Edit an existing ignore origin rule
description: "Here you can manage the global ignore origin rules used to ignore some patterns of origin url."
list:
actions: Actions
edit_action: Edit
yes: Yes
no: No
create_new_one: Create a new global ignore origin rule
form:
rule_label: Rule
save: Save
delete: Delete
delete_confirm: Are you sure?
back_to_list: Back to list
error:
page_title: An error occurred
@ -617,6 +655,8 @@ flashes:
otp_disabled: Two-factor authentication disabled
tagging_rules_imported: Tagging rules imported
tagging_rules_not_imported: Error while importing tagging rules
ignore_origin_rules_deleted: 'Ignore origin rule deleted'
ignore_origin_rules_updated: 'Ignore origin rule updated'
entry:
notice:
entry_already_saved: 'Entry already saved on %date%'
@ -658,3 +698,8 @@ flashes:
added: 'Site credential for "%host%" added'
updated: 'Site credential for "%host%" updated'
deleted: 'Site credential for "%host%" deleted'
ignore_origin_instance_rule:
notice:
added: 'Global ignore origin rule added'
updated: 'Global ignore origin rule updated'
deleted: 'Global ignore origin rule deleted'

View file

@ -33,6 +33,7 @@ menu:
back_to_unread: 'Volver a los artículos sin leer'
users_management: 'Configuración de usuarios'
site_credentials: 'Credenciales del sitio'
# ignore_origin_instance_rules: 'Global ignore origin rules'
quickstart: "Inicio rápido"
top:
add_new_entry: 'Añadir un nuevo artículo'
@ -59,6 +60,7 @@ config:
user_info: 'Información de usuario'
password: 'Contraseña'
rules: 'Reglas de etiquetado automáticas'
# ignore_origin: 'Ignore origin rules'
new_user: 'Añadir un usuario'
reset: 'Reiniciar mi cuenta'
form:
@ -177,6 +179,24 @@ config:
and: 'Una regla Y la otra'
matches: 'Prueba si un <i>sujeto</i> corresponde a una <i>búsqueda</i> (insensible a mayúsculas).<br />Ejemplo : <code>title matches "fútbol"</code>'
notmatches: 'Prueba si <i>subject</i> no corresponde a una <i>búsqueda</i> (insensible a mayúsculas).<br />Example: <code>title notmatches "fútbol"</code>'
form_ignore_origin_rules:
# faq:
# title: 'FAQ'
# ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
# ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
# how_to_use_them_title: 'How do I use them?'
# how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
# variables_available_title: 'Which variables and operators can I use to write rules?'
# variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
# meaning: 'Meaning'
# variable_description:
# label: 'Variable'
# host: 'Host of the address'
# _all: 'Full address, mainly for pattern matching'
# operator_description:
# label: 'Operator'
# equal_to: 'Equal to…'
# matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
otp:
page_title: Autenticación de dos pasos
app:
@ -617,6 +637,8 @@ flashes:
# otp_disabled: Two-factor authentication disabled
tagging_rules_imported: Reglas de etiquetado importadas
tagging_rules_not_imported: Un error se ha producico en la importación de las reglas de etiquetado
# ignore_origin_rules_deleted: 'Ignore origin rule deleted'
# ignore_origin_rules_updated: 'Ignore origin rule updated'
entry:
notice:
entry_already_saved: 'Artículo ya guardado el %fecha%'
@ -658,3 +680,8 @@ flashes:
added: 'Credenciales del sitio añadidas para "%host%"'
updated: 'Credenciales del sitio actualizadas para "%host%"'
deleted: 'Credenciales del sitio eliminadas para "%host%"'
ignore_origin_instance_rule:
notice:
# added: 'Global ignore origin rule added'
# updated: 'Global ignore origin rule updated'
# deleted: 'Global ignore origin rule deleted'

View file

@ -33,6 +33,7 @@ menu:
back_to_unread: 'بازگشت به خوانده‌نشده‌ها'
# users_management: 'Users management'
# site_credentials: 'Site credentials'
# ignore_origin_instance_rules: 'Global ignore origin rules'
quickstart: "Quickstart"
top:
add_new_entry: 'افزودن مقالهٔ تازه'
@ -59,6 +60,7 @@ config:
user_info: 'اطلاعات کاربر'
password: 'رمز'
rules: 'برچسب‌گذاری خودکار'
# ignore_origin: 'Ignore origin rules'
new_user: 'افزودن کاربر'
# reset: 'Reset area'
form:
@ -177,6 +179,24 @@ config:
# and: 'One rule AND another'
# matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
# notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
form_ignore_origin_rules:
# faq:
# title: 'FAQ'
# ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
# ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
# how_to_use_them_title: 'How do I use them?'
# how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
# variables_available_title: 'Which variables and operators can I use to write rules?'
# variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
# meaning: 'Meaning'
# variable_description:
# label: 'Variable'
# host: 'Host of the address'
# _all: 'Full address, mainly for pattern matching'
# operator_description:
# label: 'Operator'
# equal_to: 'Equal to…'
# matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
otp:
# page_title: Two-factor authentication
# app:
@ -617,6 +637,8 @@ flashes:
# otp_disabled: Two-factor authentication disabled
# tagging_rules_imported: Tagging rules imported
# tagging_rules_not_imported: Error while importing tagging rules
# ignore_origin_rules_deleted: 'Ignore origin rule deleted'
# ignore_origin_rules_updated: 'Ignore origin rule updated'
entry:
notice:
entry_already_saved: 'این مقاله در تاریخ %date% ذخیره شده بود'
@ -658,3 +680,8 @@ flashes:
# added: 'Site credential for "%host%" added'
# updated: 'Site credential for "%host%" updated'
# deleted: 'Site credential for "%host%" deleted'
ignore_origin_instance_rule:
notice:
# added: 'Global ignore origin rule added'
# updated: 'Global ignore origin rule updated'
# deleted: 'Global ignore origin rule deleted'

View file

@ -33,6 +33,7 @@ menu:
back_to_unread: "Retour aux articles non lus"
users_management: "Gestion des utilisateurs"
site_credentials: 'Accès aux sites'
ignore_origin_instance_rules: "Règles globales d'omission d'origine"
quickstart: "Pour bien débuter"
top:
add_new_entry: "Sauvegarder un nouvel article"
@ -59,6 +60,7 @@ config:
user_info: "Mon compte"
password: "Mot de passe"
rules: "Règles de tag automatiques"
ignore_origin: "Règles d'omission d'origine"
new_user: "Créer un compte"
reset: "Réinitialisation"
form:
@ -177,6 +179,24 @@ config:
and: "Une règle ET lautre"
matches: "Teste si un <i>sujet</i> correspond à une <i>recherche</i> (non sensible à la casse).<br />Exemple : <code>title matches \"football\"</code>"
notmatches: "Teste si un <i>sujet</i> ne correspond pas à une <i>recherche</i> (non sensible à la casse).<br />Exemple : <code>title notmatches \"football\"</code>"
form_ignore_origin_rules:
faq:
title: "FAQ"
ignore_origin_rules_definition_title: "Que signifient les règles d'omission d'origine ?"
ignore_origin_rules_definition_description: "Ce sont des règles utilisées par wallabag pour omettre automatiquement l'adresse d'origine après une redirection.<br />Si une redirection intervient pendant la récupération d'un nouvel article, toutes les règles d'omission (<i>règles utilisateur et instance</i>) seront utilisées afin d'ignorer ou non l'adresse d'origine."
how_to_use_them_title: "Comment les utiliser ?"
how_to_use_them_description: "Imaginons que vous vouliez omettre l'origine d'un article provenant de « <i>rss.example.com</i> » (<i>sachant qu'après la redirection, l'adresse réelle est example.com</i>).<br />Dans ce cas, vous devriez mettre « host = \"rss.example.com\" » dans le champ <i>Règle</i>."
variables_available_title: "Quelles variables et opérateurs puis-je utiliser pour écrire des règles ?"
variables_available_description: "Les variables et opérateurs suivants peuvent être utilisés pour écrire des règles d'omission d'origine :"
meaning: "Signification"
variable_description:
label: "Variable"
host: "Hôte"
_all: "Adresse complète, utile pour les expressions régulières"
operator_description:
label: "Opérateur"
equal_to: "Égal à…"
matches: "Teste si un <i>sujet</i> correspond à une <i>recherche</i> (non sensible à la casse).<br />Exemple : <code>_all ~ \"https?://rss.example.com/foobar/.*\"</code>"
otp:
page_title: Authentification double-facteur
app:
@ -618,6 +638,8 @@ flashes:
otp_disabled: "Authentification à double-facteur désactivée"
tagging_rules_imported: Règles bien importées
tagging_rules_not_imported: Impossible d'importer les règles
ignore_origin_rules_deleted: "Règle d'omission d'origine supprimée"
ignore_origin_rules_updated: "Règle d'omission d'origine mise à jour"
entry:
notice:
entry_already_saved: "Article déjà sauvegardé le %date%"

View file

@ -33,6 +33,7 @@ menu:
back_to_unread: 'Torna ai contenuti non letti'
users_management: 'Gestione utenti'
site_credentials: 'Credenziali sito'
# ignore_origin_instance_rules: 'Global ignore origin rules'
quickstart: "Introduzione"
top:
add_new_entry: 'Aggiungi un nuovo contenuto'
@ -59,6 +60,7 @@ config:
user_info: 'Informazioni utente'
password: 'Password'
rules: 'Regole di etichettatura'
# ignore_origin: 'Ignore origin rules'
new_user: 'Aggiungi utente'
reset: 'Area di reset'
form:
@ -177,6 +179,24 @@ config:
and: "Una regola E un'altra"
matches: 'Verifica che un <i>oggetto</i> risulti in una <i>ricerca</i> (case-insensitive).<br />Esempio: <code>titolo contiene "football"</code>'
# notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
form_ignore_origin_rules:
# faq:
# title: 'FAQ'
# ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
# ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
# how_to_use_them_title: 'How do I use them?'
# how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
# variables_available_title: 'Which variables and operators can I use to write rules?'
# variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
# meaning: 'Meaning'
# variable_description:
# label: 'Variable'
# host: 'Host of the address'
# _all: 'Full address, mainly for pattern matching'
# operator_description:
# label: 'Operator'
# equal_to: 'Equal to…'
# matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
otp:
# page_title: Two-factor authentication
# app:
@ -617,6 +637,8 @@ flashes:
# otp_disabled: Two-factor authentication disabled
# tagging_rules_imported: Tagging rules imported
# tagging_rules_not_imported: Error while importing tagging rules
# ignore_origin_rules_deleted: 'Ignore origin rule deleted'
# ignore_origin_rules_updated: 'Ignore origin rule updated'
entry:
notice:
entry_already_saved: 'Contenuto già salvato in data %date%'
@ -658,3 +680,8 @@ flashes:
# added: 'Site credential for "%host%" added'
# updated: 'Site credential for "%host%" updated'
# deleted: 'Site credential for "%host%" deleted'
ignore_origin_instance_rule:
notice:
# added: 'Global ignore origin rule added'
# updated: 'Global ignore origin rule updated'
# deleted: 'Global ignore origin rule deleted'

View file

@ -33,6 +33,7 @@ menu:
back_to_unread: 'Tornar als articles pas legits'
users_management: 'Gestion dels utilizaires'
site_credentials: 'Identificants del site'
# ignore_origin_instance_rules: 'Global ignore origin rules'
quickstart: "Per ben començar"
top:
add_new_entry: 'Enregistrar un novèl article'
@ -59,6 +60,7 @@ config:
user_info: 'Mon compte'
password: 'Senhal'
rules: "Règlas d'etiquetas automaticas"
# ignore_origin: 'Ignore origin rules'
new_user: 'Crear un compte'
reset: 'Zòna de reïnicializacion'
form:
@ -177,6 +179,24 @@ config:
and: "Una règla E l'autra"
matches: 'Teste se un <i>subjècte</i> correspond a una <i>recèrca</i> (non sensibla a la cassa).<br />Exemple:<code>title matches \"football\"</code>'
notmatches: 'Teste se <i>subjècte</i> correspond pas a una <i>recèrca</i> (sensibla a la cassa).<br />Example:<code>title notmatches "football"</code>'
form_ignore_origin_rules:
# faq:
# title: 'FAQ'
# ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
# ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
# how_to_use_them_title: 'How do I use them?'
# how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
# variables_available_title: 'Which variables and operators can I use to write rules?'
# variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
# meaning: 'Meaning'
# variable_description:
# label: 'Variable'
# host: 'Host of the address'
# _all: 'Full address, mainly for pattern matching'
# operator_description:
# label: 'Operator'
# equal_to: 'Equal to…'
# matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
otp:
page_title: Autentificacion en dos temps
app:
@ -617,6 +637,8 @@ flashes:
# otp_disabled: Two-factor authentication disabled
tagging_rules_imported: Règlas detiquetatge importadas
tagging_rules_not_imported: Error en important las règlas detiquetatge
# ignore_origin_rules_deleted: 'Ignore origin rule deleted'
# ignore_origin_rules_updated: 'Ignore origin rule updated'
entry:
notice:
entry_already_saved: 'Article ja salvagardat lo %date%'
@ -658,3 +680,8 @@ flashes:
added: 'Identificant per "%host%" ajustat'
updated: 'Identificant per "%host%" mes a jorn'
deleted: 'Identificant per "%host%" suprimit'
ignore_origin_instance_rule:
notice:
# added: 'Global ignore origin rule added'
# updated: 'Global ignore origin rule updated'
# deleted: 'Global ignore origin rule deleted'

View file

@ -33,6 +33,7 @@ menu:
back_to_unread: 'Powrót do nieprzeczytanych artykułów'
users_management: 'Zarządzanie użytkownikami'
site_credentials: 'Poświadczenia strony'
# ignore_origin_instance_rules: 'Global ignore origin rules'
quickstart: "Szybki start"
top:
add_new_entry: 'Dodaj nowy wpis'
@ -59,6 +60,7 @@ config:
user_info: 'Informacje o użytkowniku'
password: 'Hasło'
rules: 'Zasady tagowania'
# ignore_origin: 'Ignore origin rules'
new_user: 'Dodaj użytkownika'
reset: 'Reset'
form:
@ -177,6 +179,24 @@ config:
and: 'Jedna reguła I inna'
matches: 'Sprawdź czy <i>temat</i> pasuje <i>szukaj</i> (duże lub małe litery).<br />Przykład: <code>tytuł zawiera "piłka nożna"</code>'
notmatches: 'Sprawdź czy <i>temat</i> nie zawiera <i>szukaj</i> (duże lub małe litery).<br />Przykład: <code>tytuł nie zawiera "piłka nożna"</code>'
form_ignore_origin_rules:
# faq:
# title: 'FAQ'
# ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
# ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
# how_to_use_them_title: 'How do I use them?'
# how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
# variables_available_title: 'Which variables and operators can I use to write rules?'
# variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
# meaning: 'Meaning'
# variable_description:
# label: 'Variable'
# host: 'Host of the address'
# _all: 'Full address, mainly for pattern matching'
# operator_description:
# label: 'Operator'
# equal_to: 'Equal to…'
# matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
otp:
# page_title: Two-factor authentication
# app:
@ -617,6 +637,8 @@ flashes:
# otp_disabled: Two-factor authentication disabled
# tagging_rules_imported: Tagging rules imported
# tagging_rules_not_imported: Error while importing tagging rules
# ignore_origin_rules_deleted: 'Ignore origin rule deleted'
# ignore_origin_rules_updated: 'Ignore origin rule updated'
entry:
notice:
entry_already_saved: 'Wpis już został dodany %date%'
@ -658,3 +680,8 @@ flashes:
added: 'Poświadczenie dla "%host%" dodane'
updated: 'Poświadczenie dla "%host%" zaktualizowane'
deleted: 'Poświadczenie dla "%host%" usuniętę'
ignore_origin_instance_rule:
notice:
# added: 'Global ignore origin rule added'
# updated: 'Global ignore origin rule updated'
# deleted: 'Global ignore origin rule deleted'

View file

@ -33,6 +33,7 @@ menu:
back_to_unread: 'Voltar para os artigos não lidos'
users_management: 'Gestão de Usuários'
site_credentials: 'Credenciais do site'
# ignore_origin_instance_rules: 'Global ignore origin rules'
quickstart: "Começo Rápido"
top:
add_new_entry: 'Adicionar um novo artigo'
@ -59,6 +60,7 @@ config:
user_info: 'Informação do Usuário'
password: 'Senha'
rules: 'Regras de tags'
# ignore_origin: 'Ignore origin rules'
new_user: 'Adicionar um usuário'
reset: 'Reiniciar minha conta'
form:
@ -177,6 +179,24 @@ config:
and: 'Uma regra E outra'
matches: 'Testa que um <i>assunto</i> corresponde a uma <i>pesquisa</i> (maiúscula ou minúscula).<br />Exemplo: <code>title matches "futebol"</code>'
notmatches: 'Testa que um <i>assunto</i> não corresponde a uma <i>search</i> (maiúscula ou minúscula).<br />Exemplo: <code>title notmatches "futebol"</code>'
form_ignore_origin_rules:
# faq:
# title: 'FAQ'
# ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
# ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
# how_to_use_them_title: 'How do I use them?'
# how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
# variables_available_title: 'Which variables and operators can I use to write rules?'
# variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
# meaning: 'Meaning'
# variable_description:
# label: 'Variable'
# host: 'Host of the address'
# _all: 'Full address, mainly for pattern matching'
# operator_description:
# label: 'Operator'
# equal_to: 'Equal to…'
# matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
otp:
page_title: Autenticação de dois fatores
app:
@ -657,3 +677,8 @@ flashes:
added: 'Credencial do site para "%host%" foi adicionada'
updated: 'Credencial do site pa "%host%" atualizada'
deleted: 'Credencial do site pa "%host%" removida'
ignore_origin_instance_rule:
notice:
# added: 'Global ignore origin rule added'
# updated: 'Global ignore origin rule updated'
# deleted: 'Global ignore origin rule deleted'

View file

@ -33,6 +33,7 @@ menu:
back_to_unread: 'Înapoi la articolele necitite'
# users_management: 'Users management'
# site_credentials: 'Site credentials'
# ignore_origin_instance_rules: 'Global ignore origin rules'
# quickstart: "Quickstart"
top:
add_new_entry: 'Introdu un nou articol'
@ -59,6 +60,7 @@ config:
user_info: 'Informații despre utilizator'
password: 'Parolă'
# rules: 'Tagging rules'
# ignore_origin: 'Ignore origin rules'
new_user: 'Crează un utilizator'
# reset: 'Reset area'
form:
@ -177,6 +179,24 @@ config:
# and: 'One rule AND another'
# matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
# notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
form_ignore_origin_rules:
# faq:
# title: 'FAQ'
# ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
# ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
# how_to_use_them_title: 'How do I use them?'
# how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
# variables_available_title: 'Which variables and operators can I use to write rules?'
# variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
# meaning: 'Meaning'
# variable_description:
# label: 'Variable'
# host: 'Host of the address'
# _all: 'Full address, mainly for pattern matching'
# operator_description:
# label: 'Operator'
# equal_to: 'Equal to…'
# matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
otp:
# page_title: Two-factor authentication
# app:
@ -616,6 +636,8 @@ flashes:
# otp_disabled: Two-factor authentication disabled
# tagging_rules_imported: Tagging rules imported
# tagging_rules_not_imported: Error while importing tagging rules
# ignore_origin_rules_deleted: 'Ignore origin rule deleted'
# ignore_origin_rules_updated: 'Ignore origin rule updated'
entry:
notice:
# entry_already_saved: 'Entry already saved on %date%'
@ -657,3 +679,8 @@ flashes:
# added: 'Site credential for "%host%" added'
# updated: 'Site credential for "%host%" updated'
# deleted: 'Site credential for "%host%" deleted'
ignore_origin_instance_rule:
notice:
# added: 'Global ignore origin rule added'
# updated: 'Global ignore origin rule updated'
# deleted: 'Global ignore origin rule deleted'

View file

@ -33,6 +33,7 @@ menu:
back_to_unread: 'Назад к непрочитанным записям'
users_management: 'Управление пользователями'
site_credentials: 'Site credentials'
# ignore_origin_instance_rules: 'Global ignore origin rules'
quickstart: "Быстрый старт"
top:
add_new_entry: 'Добавить новую запись'
@ -59,6 +60,7 @@ config:
user_info: 'Информация о пользователе'
password: 'Пароль'
rules: 'Правила настройки простановки тегов'
# ignore_origin: 'Ignore origin rules'
new_user: 'Добавить пользователя'
reset: 'Сброс данных'
form:
@ -177,6 +179,24 @@ config:
and: 'Одно правило И другое'
matches: 'Тесты, в которых <i> тема </i> соответствует <i> поиску </i> (без учета регистра). Пример: <code> title matches "футбол" </code>'
# notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
form_ignore_origin_rules:
# faq:
# title: 'FAQ'
# ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
# ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
# how_to_use_them_title: 'How do I use them?'
# how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
# variables_available_title: 'Which variables and operators can I use to write rules?'
# variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
# meaning: 'Meaning'
# variable_description:
# label: 'Variable'
# host: 'Host of the address'
# _all: 'Full address, mainly for pattern matching'
# operator_description:
# label: 'Operator'
# equal_to: 'Equal to…'
# matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
otp:
# page_title: Two-factor authentication
# app:
@ -616,6 +636,8 @@ flashes:
# otp_disabled: Two-factor authentication disabled
# tagging_rules_imported: Tagging rules imported
# tagging_rules_not_imported: Error while importing tagging rules
# ignore_origin_rules_deleted: 'Ignore origin rule deleted'
# ignore_origin_rules_updated: 'Ignore origin rule updated'
entry:
notice:
entry_already_saved: 'Запись была сохранена ранее %date%'
@ -657,3 +679,8 @@ flashes:
# added: 'Site credential for "%host%" added'
# updated: 'Site credential for "%host%" updated'
# deleted: 'Site credential for "%host%" deleted'
ignore_origin_instance_rule:
notice:
# added: 'Global ignore origin rule added'
# updated: 'Global ignore origin rule updated'
# deleted: 'Global ignore origin rule deleted'

View file

@ -33,6 +33,7 @@ menu:
back_to_unread: 'กลับไปยังรายการที่ไม่ได้อ่าน'
users_management: 'การจัดการผู้ใช้'
site_credentials: 'การรับรองไซต์'
# ignore_origin_instance_rules: 'Global ignore origin rules'
quickstart: "เริ่มแบบด่วน"
top:
add_new_entry: 'เพิ่มรายการใหม่'
@ -59,6 +60,7 @@ config:
user_info: 'ข้อมูลผู้ใช้'
password: 'รหัสผ่าน'
rules: 'การแท็กข้อบังคับ'
# ignore_origin: 'Ignore origin rules'
new_user: 'เพิ่มผู้ใช้'
reset: 'รีเซ็ตพื้นที่ '
form:
@ -177,6 +179,24 @@ config:
and: 'หนึ่งข้อบังคับและอื่นๆ'
matches: 'ทดสอบว่า <i>เรื่อง</i> นี้ตรงกับ <i>การต้นหา</i> (กรณีไม่ทราบ).<br />ตัวอย่าง: <code>หัวข้อที่ตรงกับ "football"</code>'
notmatches: 'ทดสอบว่า <i>เรื่อง</i> นี้ไม่ตรงกับ <i>การต้นหา</i> (กรณีไม่ทราบ).<br />ตัวอย่าง: <code>หัวข้อทีไม่ตรงกับ "football"</code>'
form_ignore_origin_rules:
# faq:
# title: 'FAQ'
# ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
# ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
# how_to_use_them_title: 'How do I use them?'
# how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
# variables_available_title: 'Which variables and operators can I use to write rules?'
# variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
# meaning: 'Meaning'
# variable_description:
# label: 'Variable'
# host: 'Host of the address'
# _all: 'Full address, mainly for pattern matching'
# operator_description:
# label: 'Operator'
# equal_to: 'Equal to…'
# matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
otp:
# page_title: Two-factor authentication
# app:
@ -616,6 +636,8 @@ flashes:
# otp_disabled: Two-factor authentication disabled
# tagging_rules_imported: Tagging rules imported
# tagging_rules_not_imported: Error while importing tagging rules
# ignore_origin_rules_deleted: 'Ignore origin rule deleted'
# ignore_origin_rules_updated: 'Ignore origin rule updated'
entry:
notice:
entry_already_saved: 'รายการพร้อมบันทึกที่ %date%'
@ -657,3 +679,8 @@ flashes:
added: 'ไซต์ข้อมูลประจำตัวสำหรับ "%host%" ที่ทำการเพิ่ม'
updated: 'ไซต์ข้อมูลประจำตัวสำหรับ "%host%" ที่ทำการอัปเดต'
deleted: 'ไซต์ข้อมูลประจำตัวสำหรับ "%host%" ที่ทำการลบ'
ignore_origin_instance_rule:
notice:
# added: 'Global ignore origin rule added'
# updated: 'Global ignore origin rule updated'
# deleted: 'Global ignore origin rule deleted'

View file

@ -33,6 +33,7 @@ menu:
back_to_unread: 'Okunmayan makalelere geri dön'
# users_management: 'Users management'
# site_credentials: 'Site credentials'
# ignore_origin_instance_rules: 'Global ignore origin rules'
quickstart: "Hızlı başlangıç"
top:
add_new_entry: 'Yeni bir makale ekle'
@ -59,6 +60,7 @@ config:
user_info: 'Kullanıcı bilgileri'
password: 'Şifre'
rules: 'Etiketleme kuralları'
# ignore_origin: 'Ignore origin rules'
new_user: 'Bir kullanıcı ekle'
# reset: 'Reset area'
form:
@ -177,6 +179,24 @@ config:
and: 'Bir kural ve diğeri'
# matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
# notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
form_ignore_origin_rules:
# faq:
# title: 'FAQ'
# ignore_origin_rules_definition_title: 'What does « ignore origin rules » mean?'
# ignore_origin_rules_definition_description: 'They are used by wallabag to automatically ignore an origin address after a redirect.<br />If a redirect occurs while fetching a new entry, all the ignore origin rules (<i>user defined and instance defined</i>) will be used to ignore the origin address.'
# how_to_use_them_title: 'How do I use them?'
# how_to_use_them_description: 'Let us assume you want to ignore the origin of an entry coming from « <i>rss.example.com</i> » (<i>knowing that after a redirect, the actual address is example.com</i>).<br />In that case, you should put « host = "rss.example.com" » in the <i>Rule</i> field.'
# variables_available_title: 'Which variables and operators can I use to write rules?'
# variables_available_description: 'The following variables and operators can be used to create ignore origin rules:'
# meaning: 'Meaning'
# variable_description:
# label: 'Variable'
# host: 'Host of the address'
# _all: 'Full address, mainly for pattern matching'
# operator_description:
# label: 'Operator'
# equal_to: 'Equal to…'
# matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>_all ~ "https?://rss.example.com/foobar/.*"</code>'
otp:
# page_title: Two-factor authentication
# app:
@ -616,6 +636,8 @@ flashes:
# otp_disabled: Two-factor authentication disabled
# tagging_rules_imported: Tagging rules imported
# tagging_rules_not_imported: Error while importing tagging rules
# ignore_origin_rules_deleted: 'Ignore origin rule deleted'
# ignore_origin_rules_updated: 'Ignore origin rule updated'
entry:
notice:
entry_already_saved: 'Entry already saved on %date%'
@ -657,3 +679,8 @@ flashes:
# added: 'Site credential for "%host%" added'
# updated: 'Site credential for "%host%" updated'
# deleted: 'Site credential for "%host%" deleted'
ignore_origin_instance_rule:
notice:
# added: 'Global ignore origin rule added'
# updated: 'Global ignore origin rule updated'
# deleted: 'Global ignore origin rule deleted'

View file

@ -404,6 +404,76 @@
</div>
</div>
<h2>{{ 'config.tab_menu.ignore_origin'|trans }}</h2>
<ul>
{% for ignore_origin_rule in app.user.config.ignoreOriginRules %}
<li>
{{ 'config.form_rules.if_label'|trans }}
« {{ ignore_origin_rule.rule }} »
<a href="{{ path('edit_ignore_origin_rule', {id: ignore_origin_rule.id}) }}" title="{{ 'config.form_rules.edit_rule_label'|trans }}" class="tool mode_edit">✎</a>
<a href="{{ path('delete_ignore_origin_rule', {id: ignore_origin_rule.id}) }}" title="{{ 'config.form_rules.delete_rule_label'|trans }}" class="tool delete icon-trash icon"></a>
</li>
{% endfor %}
</ul>
{{ form_start(form.new_ignore_origin_user_rule) }}
{{ form_errors(form.new_ignore_origin_user_rule) }}
<fieldset class="w500p inline">
<div class="row">
{{ form_label(form.new_ignore_origin_user_rule.rule) }}
{{ form_errors(form.new_ignore_origin_user_rule.rule) }}
{{ form_widget(form.new_ignore_origin_user_rule.rule) }}
</div>
</fieldset>
{{ form_rest(form.new_ignore_origin_user_rule) }}
</form>
<div class="row">
<div class="input-field col s12">
<h4>{{ 'config.form_ignore_origin_rules.faq.title'|trans }}</h4>
<h5>{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_title'|trans }}</h5>
<p class="help">{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_description'|trans|raw }}</p>
<h5>{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_title'|trans }}</h5>
<p class="help">{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_description'|trans|raw }}</p>
<h5>{{ 'config.form_ignore_origin_rules.faq.variables_available_title'|trans }}</h5>
<p class="help">
{{ 'config.form_ignore_origin_rules.faq.variables_available_description'|trans }}
</p>
<table class="bordered">
<thead>
<tr>
<th>{{ 'config.form_ignore_origin_rules.faq.variable_description.label'|trans }}</th>
<th>{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}</th>
<th>{{ 'config.form_ignore_origin_rules.faq.operator_description.label'|trans }}</th>
<th>{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}</th>
</tr>
</thead>
<tbody>
<tr>
<td>host</td>
<td>{{ 'config.form_ignore_origin_rules.faq.variable_description.host'|trans }}</td>
<td>=</td>
<td>{{ 'config.form_ignore_origin_rules.faq.operator_description.equal_to'|trans }}</td>
</tr>
<tr>
<td>_all</td>
<td>{{ 'config.form_ignore_origin_rules.faq.variable_description._all'|trans }}</td>
<td>~</td>
<td>{{ 'config.form_ignore_origin_rules.faq.operator_description.matches'|trans|raw }}</td>
</tr>
</tbody>
</table>
</div>
</div>
<h2>{{ 'config.reset.title'|trans }}</h2>
<fieldset class="w500p inline">
<p>{{ 'config.reset.description'|trans }}</p>

View file

@ -0,0 +1,87 @@
{% extends "WallabagCoreBundle::layout.html.twig" %}
{% block title %}{{ 'ignore_origin_instance_rule.page_title'|trans }}{% endblock %}
{% block content %}
<div class="row">
<div class="col s12">
<div class="card-panel">
<div class="row">
<div class="input-field col s12">
<h4>{{ 'ignore_origin_instance_rule.edit_ignore_origin_instance_rule'|trans }}</h4>
<div id="set6" class="col s12">
{{ form_start(edit_form) }}
{{ form_errors(edit_form) }}
<div class="row">
<div class="input-field col s12">
{{ form_label(edit_form.rule) }}
{{ form_errors(edit_form.rule) }}
{{ form_widget(edit_form.rule) }}
</div>
</div>
<br/>
{{ form_widget(edit_form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
{{ form_widget(edit_form._token) }}
</form>
<p>
{{ form_start(delete_form) }}
<button onclick="return confirm('{{ 'ignore_origin_instance_rule.form.delete_confirm'|trans|escape('js') }}')" type="submit" class="btn waves-effect waves-light red">{{ 'ignore_origin_instance_rule.form.delete'|trans }}</button>
{{ form_end(delete_form) }}
</p>
<p><a class="waves-effect waves-light btn blue-grey" href="{{ path('ignore_origin_instance_rules_index') }}">{{ 'ignore_origin_instance_rule.form.back_to_list'|trans }}</a></p>
</div>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<h4>{{ 'config.form_ignore_origin_rules.faq.title'|trans }}</h4>
<h5>{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_title'|trans }}</h5>
<p class="help">{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_description'|trans|raw }}</p>
<h5>{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_title'|trans }}</h5>
<p class="help">{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_description'|trans|raw }}</p>
<h5>{{ 'config.form_ignore_origin_rules.faq.variables_available_title'|trans }}</h5>
<p class="help">
{{ 'config.form_ignore_origin_rules.faq.variables_available_description'|trans }}
</p>
<table class="bordered">
<thead>
<tr>
<th>{{ 'config.form_ignore_origin_rules.faq.variable_description.label'|trans }}</th>
<th>{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}</th>
<th>{{ 'config.form_ignore_origin_rules.faq.operator_description.label'|trans }}</th>
<th>{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}</th>
</tr>
</thead>
<tbody>
<tr>
<td>host</td>
<td>{{ 'config.form_ignore_origin_rules.faq.variable_description.host'|trans }}</td>
<td>=</td>
<td>{{ 'config.form_ignore_origin_rules.faq.operator_description.equal_to'|trans }}</td>
</tr>
<tr>
<td>_all</td>
<td>{{ 'config.form_ignore_origin_rules.faq.variable_description._all'|trans }}</td>
<td>~</td>
<td>{{ 'config.form_ignore_origin_rules.faq.operator_description.matches'|trans|raw }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,42 @@
{% extends "WallabagCoreBundle::layout.html.twig" %}
{% block title %}{{ 'ignore_origin_instance_rule.page_title'|trans }}{% endblock %}
{% block content %}
<div class="row">
<div class="col s12">
<div class="card-panel">
<div class="row">
<div class="input-field col s12">
<p class="help">{{ 'ignore_origin_instance_rule.description'|trans|raw }}</p>
<table class="bordered">
<thead>
<tr>
<th>{{ 'ignore_origin_instance_rule.form.rule_label'|trans }}</th>
<th>{{ 'ignore_origin_instance_rule.list.actions'|trans }}</th>
</tr>
</thead>
<tbody>
{% for rule in rules %}
<tr>
<td>{{ rule.rule }}</td>
<td>
<a href="{{ path('ignore_origin_instance_rules_edit', { 'id': rule.id }) }}">{{ 'ignore_origin_instance_rule.list.edit_action'|trans }}</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<br />
<p>
<a href="{{ path('ignore_origin_instance_rules_new') }}" class="waves-effect waves-light btn">{{ 'ignore_origin_instance_rule.list.create_new_one'|trans }}</a>
</p>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,80 @@
{% extends "WallabagCoreBundle::layout.html.twig" %}
{% block title %}{{ 'ignore_origin_instance_rule.page_title'|trans }}{% endblock %}
{% block content %}
<div class="row">
<div class="col s12">
<div class="card-panel">
<div class="row">
<div class="input-field col s12">
<h4>{{ 'ignore_origin_instance_rule.new_ignore_origin_instance_rule'|trans }}</h4>
<div id="set6" class="col s12">
{{ form_start(form) }}
{{ form_errors(form) }}
<div class="row">
<div class="input-field col s12">
{{ form_label(form.rule) }}
{{ form_errors(form.rule) }}
{{ form_widget(form.rule) }}
</div>
</div>
{{ form_widget(form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
{{ form_rest(form) }}
</form>
<p><a class="waves-effect waves-light btn blue-grey" href="{{ path('ignore_origin_instance_rules_index') }}">{{ 'ignore_origin_instance_rule.form.back_to_list'|trans }}</a></p>
</div>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<h4>{{ 'config.form_ignore_origin_rules.faq.title'|trans }}</h4>
<h5>{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_title'|trans }}</h5>
<p class="help">{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_description'|trans|raw }}</p>
<h5>{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_title'|trans }}</h5>
<p class="help">{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_description'|trans|raw }}</p>
<h5>{{ 'config.form_ignore_origin_rules.faq.variables_available_title'|trans }}</h5>
<p class="help">
{{ 'config.form_ignore_origin_rules.faq.variables_available_description'|trans }}
</p>
<table class="bordered">
<thead>
<tr>
<th>{{ 'config.form_ignore_origin_rules.faq.variable_description.label'|trans }}</th>
<th>{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}</th>
<th>{{ 'config.form_ignore_origin_rules.faq.operator_description.label'|trans }}</th>
<th>{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}</th>
</tr>
</thead>
<tbody>
<tr>
<td>host</td>
<td>{{ 'config.form_ignore_origin_rules.faq.variable_description.host'|trans }}</td>
<td>=</td>
<td>{{ 'config.form_ignore_origin_rules.faq.operator_description.equal_to'|trans }}</td>
</tr>
<tr>
<td>_all</td>
<td>{{ 'config.form_ignore_origin_rules.faq.variable_description._all'|trans }}</td>
<td>~</td>
<td>{{ 'config.form_ignore_origin_rules.faq.operator_description.matches'|trans|raw }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -45,6 +45,7 @@
{% if is_granted('ROLE_SUPER_ADMIN') %}
<li class="menu users"><a href="{{ path('user_index') }}">{{ 'menu.left.users_management'|trans }}</a></li>
<li class="menu internal"><a href="{{ path('craue_config_settings_modify') }}">{{ 'menu.left.internal_settings'|trans }}</a></li>
<li class="menu ignore"><a href="{{ path('ignore_origin_instance_rules_index') }}">{{ 'menu.left.ignore_origin_instance_rules'|trans }}</a></li>
{% endif %}
<li class="menu import"><a href="{{ path('import') }}">{{ 'menu.left.import'|trans }}</a></li>
<li class="menu howto"><a href="{{ path('howto') }}">{{ 'menu.left.howto'|trans }}</a></li>

View file

@ -16,7 +16,8 @@
<li class="tab col s12 m6 l3"><a href="#set3">{{ 'config.tab_menu.user_info'|trans }}</a></li>
<li class="tab col s12 m6 l3"><a href="#set4">{{ 'config.tab_menu.password'|trans }}</a></li>
<li class="tab col s12 m6 l3"><a href="#set5">{{ 'config.tab_menu.rules'|trans }}</a></li>
<li class="tab col s12 m6 l3"><a href="#set6">{{ 'config.tab_menu.reset'|trans }}</a></li>
<li class="tab col s12 m6 l3"><a href="#set6">{{ 'config.tab_menu.ignore_origin'|trans }}</a></li>
<li class="tab col s12 m6 l3"><a href="#set7">{{ 'config.tab_menu.reset'|trans }}</a></li>
</ul>
</div>
@ -294,11 +295,11 @@
« {{ tagging_rule.rule }} »
{{ 'config.form_rules.then_tag_as_label'|trans }}
« {{ tagging_rule.tags|join(', ') }} »
<a href="{{ path('edit_tagging_rule', {id: tagging_rule.id}) }}" title="{{ 'config.form_rules.edit_rule_label'|trans }}">
<i class="tool grey-text mode_edit material-icons">mode_edit</i>
<a href="{{ path('edit_tagging_rule', {id: tagging_rule.id}) }}" title="{{ 'config.form_rules.edit_rule_label'|trans }}" class="mode_edit">
<i class="tool grey-text material-icons">mode_edit</i>
</a>
<a href="{{ path('delete_tagging_rule', {id: tagging_rule.id}) }}" title="{{ 'config.form_rules.delete_rule_label'|trans }}">
<i class="tool grey-text delete material-icons">delete</i>
<a href="{{ path('delete_tagging_rule', {id: tagging_rule.id}) }}" title="{{ 'config.form_rules.delete_rule_label'|trans }}" class="delete">
<i class="tool grey-text material-icons">delete</i>
</a>
</li>
{% endfor %}
@ -466,6 +467,89 @@
</div>
<div id="set6" class="col s12">
{% if app.user.config.ignoreOriginRules is not empty %}
<div class="row">
<div class="input-field col s12">
<ul>
{% for ignore_origin_rule in app.user.config.ignoreOriginRules %}
<li>
{{ 'config.form_rules.if_label'|trans }}
« {{ ignore_origin_rule.rule }} »
<a href="{{ path('edit_ignore_origin_rule', {id: ignore_origin_rule.id}) }}" title="{{ 'config.form_rules.edit_rule_label'|trans }}" class="mode_edit">
<i class="tool grey-text material-icons">mode_edit</i>
</a>
<a href="{{ path('delete_ignore_origin_rule', {id: ignore_origin_rule.id}) }}" title="{{ 'config.form_rules.delete_rule_label'|trans }}" class="delete">
<i class="tool grey-text material-icons">delete</i>
</a>
</li>
{% endfor %}
</ul>
</div>
</div>
{% endif %}
{{ form_start(form.new_ignore_origin_user_rule) }}
{{ form_errors(form.new_ignore_origin_user_rule) }}
<div class="row">
<div class="input-field col s12">
{{ form_label(form.new_ignore_origin_user_rule.rule) }}
{{ form_errors(form.new_ignore_origin_user_rule.rule) }}
{{ form_widget(form.new_ignore_origin_user_rule.rule) }}
</div>
</div>
{{ form_widget(form.new_ignore_origin_user_rule.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
{{ form_rest(form.new_ignore_origin_user_rule) }}
</form>
<div class="row">
<div class="input-field col s12">
<h4>{{ 'config.form_ignore_origin_rules.faq.title'|trans }}</h4>
<h5>{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_title'|trans }}</h5>
<p class="help">{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_description'|trans|raw }}</p>
<h5>{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_title'|trans }}</h5>
<p class="help">{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_description'|trans|raw }}</p>
<h5>{{ 'config.form_ignore_origin_rules.faq.variables_available_title'|trans }}</h5>
<p class="help">
{{ 'config.form_ignore_origin_rules.faq.variables_available_description'|trans }}
</p>
<table class="bordered">
<thead>
<tr>
<th>{{ 'config.form_ignore_origin_rules.faq.variable_description.label'|trans }}</th>
<th>{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}</th>
<th>{{ 'config.form_ignore_origin_rules.faq.operator_description.label'|trans }}</th>
<th>{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}</th>
</tr>
</thead>
<tbody>
<tr>
<td>host</td>
<td>{{ 'config.form_ignore_origin_rules.faq.variable_description.host'|trans }}</td>
<td>=</td>
<td>{{ 'config.form_ignore_origin_rules.faq.operator_description.equal_to'|trans }}</td>
</tr>
<tr>
<td>_all</td>
<td>{{ 'config.form_ignore_origin_rules.faq.variable_description._all'|trans }}</td>
<td>~</td>
<td>{{ 'config.form_ignore_origin_rules.faq.operator_description.matches'|trans|raw }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div id="set7" class="col s12">
<div class="row">
<h5>{{ 'config.reset.title'|trans }}</h5>
<p>{{ 'config.reset.description'|trans }}</p>

View file

@ -0,0 +1,87 @@
{% extends "WallabagCoreBundle::layout.html.twig" %}
{% block title %}{{ 'ignore_origin_instance_rule.page_title'|trans }}{% endblock %}
{% block content %}
<div class="row">
<div class="col s12">
<div class="card-panel">
<div class="row">
<div class="input-field col s12">
<h4>{{ 'ignore_origin_instance_rule.edit_ignore_origin_instance_rule'|trans }}</h4>
<div id="set6" class="col s12">
{{ form_start(edit_form) }}
{{ form_errors(edit_form) }}
<div class="row">
<div class="input-field col s12">
{{ form_label(edit_form.rule) }}
{{ form_errors(edit_form.rule) }}
{{ form_widget(edit_form.rule) }}
</div>
</div>
<br/>
{{ form_widget(edit_form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
{{ form_widget(edit_form._token) }}
</form>
<p>
{{ form_start(delete_form) }}
<button onclick="return confirm('{{ 'ignore_origin_instance_rule.form.delete_confirm'|trans|escape('js') }}')" type="submit" class="btn waves-effect waves-light red">{{ 'ignore_origin_instance_rule.form.delete'|trans }}</button>
{{ form_end(delete_form) }}
</p>
<p><a class="waves-effect waves-light btn blue-grey" href="{{ path('ignore_origin_instance_rules_index') }}">{{ 'ignore_origin_instance_rule.form.back_to_list'|trans }}</a></p>
</div>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<h4>{{ 'config.form_ignore_origin_rules.faq.title'|trans }}</h4>
<h5>{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_title'|trans }}</h5>
<p class="help">{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_description'|trans|raw }}</p>
<h5>{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_title'|trans }}</h5>
<p class="help">{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_description'|trans|raw }}</p>
<h5>{{ 'config.form_ignore_origin_rules.faq.variables_available_title'|trans }}</h5>
<p class="help">
{{ 'config.form_ignore_origin_rules.faq.variables_available_description'|trans }}
</p>
<table class="bordered">
<thead>
<tr>
<th>{{ 'config.form_ignore_origin_rules.faq.variable_description.label'|trans }}</th>
<th>{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}</th>
<th>{{ 'config.form_ignore_origin_rules.faq.operator_description.label'|trans }}</th>
<th>{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}</th>
</tr>
</thead>
<tbody>
<tr>
<td>host</td>
<td>{{ 'config.form_ignore_origin_rules.faq.variable_description.host'|trans }}</td>
<td>=</td>
<td>{{ 'config.form_ignore_origin_rules.faq.operator_description.equal_to'|trans }}</td>
</tr>
<tr>
<td>_all</td>
<td>{{ 'config.form_ignore_origin_rules.faq.variable_description._all'|trans }}</td>
<td>~</td>
<td>{{ 'config.form_ignore_origin_rules.faq.operator_description.matches'|trans|raw }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,42 @@
{% extends "WallabagCoreBundle::layout.html.twig" %}
{% block title %}{{ 'ignore_origin_instance_rule.page_title'|trans }}{% endblock %}
{% block content %}
<div class="row">
<div class="col s12">
<div class="card-panel">
<div class="row">
<div class="input-field col s12">
<p class="help">{{ 'ignore_origin_instance_rule.description'|trans|raw }}</p>
<table class="bordered">
<thead>
<tr>
<th>{{ 'ignore_origin_instance_rule.form.rule_label'|trans }}</th>
<th>{{ 'ignore_origin_instance_rule.list.actions'|trans }}</th>
</tr>
</thead>
<tbody>
{% for rule in rules %}
<tr>
<td>{{ rule.rule }}</td>
<td>
<a href="{{ path('ignore_origin_instance_rules_edit', { 'id': rule.id }) }}">{{ 'ignore_origin_instance_rule.list.edit_action'|trans }}</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<br />
<p>
<a href="{{ path('ignore_origin_instance_rules_new') }}" class="waves-effect waves-light btn">{{ 'ignore_origin_instance_rule.list.create_new_one'|trans }}</a>
</p>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,80 @@
{% extends "WallabagCoreBundle::layout.html.twig" %}
{% block title %}{{ 'ignore_origin_instance_rule.page_title'|trans }}{% endblock %}
{% block content %}
<div class="row">
<div class="col s12">
<div class="card-panel">
<div class="row">
<div class="input-field col s12">
<h4>{{ 'ignore_origin_instance_rule.new_ignore_origin_instance_rule'|trans }}</h4>
<div id="set6" class="col s12">
{{ form_start(form) }}
{{ form_errors(form) }}
<div class="row">
<div class="input-field col s12">
{{ form_label(form.rule) }}
{{ form_errors(form.rule) }}
{{ form_widget(form.rule) }}
</div>
</div>
{{ form_widget(form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
{{ form_rest(form) }}
</form>
<p><a class="waves-effect waves-light btn blue-grey" href="{{ path('ignore_origin_instance_rules_index') }}">{{ 'ignore_origin_instance_rule.form.back_to_list'|trans }}</a></p>
</div>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<h4>{{ 'config.form_ignore_origin_rules.faq.title'|trans }}</h4>
<h5>{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_title'|trans }}</h5>
<p class="help">{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_description'|trans|raw }}</p>
<h5>{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_title'|trans }}</h5>
<p class="help">{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_description'|trans|raw }}</p>
<h5>{{ 'config.form_ignore_origin_rules.faq.variables_available_title'|trans }}</h5>
<p class="help">
{{ 'config.form_ignore_origin_rules.faq.variables_available_description'|trans }}
</p>
<table class="bordered">
<thead>
<tr>
<th>{{ 'config.form_ignore_origin_rules.faq.variable_description.label'|trans }}</th>
<th>{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}</th>
<th>{{ 'config.form_ignore_origin_rules.faq.operator_description.label'|trans }}</th>
<th>{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}</th>
</tr>
</thead>
<tbody>
<tr>
<td>host</td>
<td>{{ 'config.form_ignore_origin_rules.faq.variable_description.host'|trans }}</td>
<td>=</td>
<td>{{ 'config.form_ignore_origin_rules.faq.operator_description.equal_to'|trans }}</td>
</tr>
<tr>
<td>_all</td>
<td>{{ 'config.form_ignore_origin_rules.faq.variable_description._all'|trans }}</td>
<td>~</td>
<td>{{ 'config.form_ignore_origin_rules.faq.operator_description.matches'|trans|raw }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -78,9 +78,13 @@
<a class="waves-effect" href="{{ path('user_index') }}">{{ 'menu.left.users_management'|trans }}</a>
</li>
<li class="bold border-bottom {% if currentRoute == 'craue_config_settings_modify' %}active{% endif %}">
<li class="bold {% if currentRoute == 'craue_config_settings_modify' %}active{% endif %}">
<a class="waves-effect" href="{{ path('craue_config_settings_modify') }}">{{ 'menu.left.internal_settings'|trans }}</a>
</li>
<li class="bold border-bottom {% if currentRoute == 'ignore_origin_instance_rules_index' %}active{% endif %}">
<a class="waves-effect" href="{{ path('ignore_origin_instance_rules_index') }}">{{ 'menu.left.ignore_origin_instance_rules'|trans }}</a>
</li>
{% endif %}
<li class="bold {% if currentRoute == 'import' %}active{% endif %}">
<a class="waves-effect" href="{{ path('import') }}">{{ 'menu.left.import'|trans }}</a>

View file

@ -45,6 +45,9 @@ class ReloadEntryCommandTest extends WallabagCoreTestCase
$this->getEntityManager()->flush();
}
/**
* @group NetworkCalls
*/
public function testRunReloadEntryCommand()
{
$application = new Application($this->getClient()->getKernel());
@ -70,6 +73,9 @@ class ReloadEntryCommandTest extends WallabagCoreTestCase
$this->assertContains('Done', $tester->getDisplay());
}
/**
* @group NetworkCalls
*/
public function testRunReloadEntryWithUsernameCommand()
{
$application = new Application($this->getClient()->getKernel());

View file

@ -435,7 +435,6 @@ class ConfigControllerTest extends WallabagCoreTestCase
public function testTaggingRuleCreation()
{
$this->logInAs('admin');
$this->useTheme('baggy');
$client = $this->getClient();
$crawler = $client->request('GET', '/config');
@ -457,7 +456,7 @@ class ConfigControllerTest extends WallabagCoreTestCase
$this->assertContains('flashes.config.notice.tagging_rules_updated', $crawler->filter('body')->extract(['_text'])[0]);
$editLink = $crawler->filter('.mode_edit')->last()->link();
$editLink = $crawler->filter('div[id=set5] a.mode_edit')->last()->link();
$crawler = $client->click($editLink);
$this->assertSame(302, $client->getResponse()->getStatusCode());
@ -482,7 +481,7 @@ class ConfigControllerTest extends WallabagCoreTestCase
$this->assertContains('readingTime <= 30', $crawler->filter('body')->extract(['_text'])[0]);
$deleteLink = $crawler->filter('.delete')->last()->link();
$deleteLink = $crawler->filter('div[id=set5] a.delete')->last()->link();
$crawler = $client->click($deleteLink);
$this->assertSame(302, $client->getResponse()->getStatusCode());
@ -574,11 +573,11 @@ class ConfigControllerTest extends WallabagCoreTestCase
->getRepository('WallabagCoreBundle:TaggingRule')
->findAll()[0];
$crawler = $client->request('GET', '/tagging-rule/edit/' . $rule->getId());
$crawler = $client->request('GET', '/tagging-rule/delete/' . $rule->getId());
$this->assertSame(403, $client->getResponse()->getStatusCode());
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
$this->assertContains('You can not access this tagging rule', $body[0]);
$this->assertContains('You can not access this rule', $body[0]);
}
public function testEditingTaggingRuleFromAnOtherUser()
@ -594,7 +593,144 @@ class ConfigControllerTest extends WallabagCoreTestCase
$this->assertSame(403, $client->getResponse()->getStatusCode());
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
$this->assertContains('You can not access this tagging rule', $body[0]);
$this->assertContains('You can not access this rule', $body[0]);
}
public function testIgnoreOriginRuleCreation()
{
$this->logInAs('admin');
$client = $this->getClient();
$crawler = $client->request('GET', '/config');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$form = $crawler->filter('button[id=ignore_origin_user_rule_save]')->form();
$data = [
'ignore_origin_user_rule[rule]' => 'host = "example.com"',
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$this->assertContains('flashes.config.notice.ignore_origin_rules_updated', $crawler->filter('body')->extract(['_text'])[0]);
$editLink = $crawler->filter('div[id=set6] a.mode_edit')->last()->link();
$crawler = $client->click($editLink);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$this->assertContains('?ignore-origin-user-rule=', $client->getResponse()->headers->get('location'));
$crawler = $client->followRedirect();
$form = $crawler->filter('button[id=ignore_origin_user_rule_save]')->form();
$data = [
'ignore_origin_user_rule[rule]' => 'host = "example.org"',
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$this->assertContains('flashes.config.notice.ignore_origin_rules_updated', $crawler->filter('body')->extract(['_text'])[0]);
$this->assertContains('host = "example.org"', $crawler->filter('body')->extract(['_text'])[0]);
$deleteLink = $crawler->filter('div[id=set6] a.delete')->last()->link();
$crawler = $client->click($deleteLink);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$this->assertContains('flashes.config.notice.ignore_origin_rules_deleted', $crawler->filter('body')->extract(['_text'])[0]);
}
public function dataForIgnoreOriginRuleCreationFail()
{
return [
[
[
'ignore_origin_user_rule[rule]' => 'foo = "bar"',
],
[
'The variable',
'does not exist.',
],
],
[
[
'ignore_origin_user_rule[rule]' => '_all != "none"',
],
[
'The operator',
'does not exist.',
],
],
];
}
/**
* @dataProvider dataForIgnoreOriginRuleCreationFail
*/
public function testIgnoreOriginRuleCreationFail($data, $messages)
{
$this->logInAs('admin');
$client = $this->getClient();
$crawler = $client->request('GET', '/config');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$form = $crawler->filter('button[id=ignore_origin_user_rule_save]')->form();
$crawler = $client->submit($form, $data);
$this->assertSame(200, $client->getResponse()->getStatusCode());
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
foreach ($messages as $message) {
$this->assertContains($message, $body[0]);
}
}
public function testDeletingIgnoreOriginRuleFromAnOtherUser()
{
$this->logInAs('bob');
$client = $this->getClient();
$rule = $client->getContainer()->get('doctrine.orm.entity_manager')
->getRepository('WallabagCoreBundle:IgnoreOriginUserRule')
->findAll()[0];
$crawler = $client->request('GET', '/ignore-origin-user-rule/edit/' . $rule->getId());
$this->assertSame(403, $client->getResponse()->getStatusCode());
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
$this->assertContains('You can not access this rule', $body[0]);
}
public function testEditingIgnoreOriginRuleFromAnOtherUser()
{
$this->logInAs('bob');
$client = $this->getClient();
$rule = $client->getContainer()->get('doctrine.orm.entity_manager')
->getRepository('WallabagCoreBundle:IgnoreOriginUserRule')
->findAll()[0];
$crawler = $client->request('GET', '/ignore-origin-user-rule/edit/' . $rule->getId());
$this->assertSame(403, $client->getResponse()->getStatusCode());
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
$this->assertContains('You can not access this rule', $body[0]);
}
public function testDemoMode()
@ -676,6 +812,9 @@ class ConfigControllerTest extends WallabagCoreTestCase
$em->flush();
}
/**
* @group NetworkCalls
*/
public function testDeleteAccount()
{
$client = $this->getClient();

View file

@ -40,6 +40,9 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->assertContains('login', $client->getResponse()->headers->get('location'));
}
/**
* @group NetworkCalls
*/
public function testQuickstart()
{
$this->logInAs('empty');
@ -87,6 +90,9 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->assertCount(1, $crawler->filter('form[name=entry]'));
}
/**
* @group NetworkCalls
*/
public function testPostNewViaBookmarklet()
{
$this->logInAs('admin');
@ -131,7 +137,7 @@ class EntryControllerTest extends WallabagCoreTestCase
}
/**
* This test will require an internet connection.
* @group NetworkCalls
*/
public function testPostNewOk()
{
@ -169,6 +175,9 @@ class EntryControllerTest extends WallabagCoreTestCase
$client->getContainer()->get('craue_config')->set('store_article_headers', 0);
}
/**
* @group NetworkCalls
*/
public function testPostWithMultipleAuthors()
{
$url = 'https://www.liberation.fr/planete/2017/04/05/donald-trump-et-xi-jinping-tentative-de-flirt-en-floride_1560768';
@ -229,6 +238,9 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->assertContains('/view/', $client->getResponse()->getTargetUrl());
}
/**
* @group NetworkCalls
*/
public function testPostNewOkUrlExistWithAccent()
{
$this->logInAs('admin');
@ -265,7 +277,7 @@ class EntryControllerTest extends WallabagCoreTestCase
}
/**
* This test will require an internet connection.
* @group NetworkCalls
*/
public function testPostNewOkUrlExistWithRedirection()
{
@ -303,7 +315,7 @@ class EntryControllerTest extends WallabagCoreTestCase
}
/**
* This test will require an internet connection.
* @group NetworkCalls
*/
public function testPostNewThatWillBeTagged()
{
@ -430,7 +442,7 @@ class EntryControllerTest extends WallabagCoreTestCase
}
/**
* This test will require an internet connection.
* @group NetworkCalls
*/
public function testReload()
{
@ -1056,6 +1068,9 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->assertSame(404, $client->getResponse()->getStatusCode());
}
/**
* @group NetworkCalls
*/
public function testNewEntryWithDownloadImagesEnabled()
{
$this->downloadImagesEnabled = true;
@ -1383,6 +1398,7 @@ class EntryControllerTest extends WallabagCoreTestCase
/**
* @dataProvider dataForLanguage
* @group NetworkCalls
*/
public function testLanguageValidation($url, $expectedLanguage)
{
@ -1414,7 +1430,7 @@ class EntryControllerTest extends WallabagCoreTestCase
}
/**
* This test will require an internet connection.
* @group NetworkCalls
*/
public function testRestrictedArticle()
{

View file

@ -0,0 +1,148 @@
<?php
namespace Tests\Wallabag\CoreBundle\Controller;
use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
class IgnoreOriginInstanceRuleControllerTest extends WallabagCoreTestCase
{
public function testListIgnoreOriginInstanceRule()
{
$this->logInAs('admin');
$client = $this->getClient();
$crawler = $client->request('GET', '/ignore-origin-instance-rules/');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$body = $crawler->filter('body')->extract(['_text'])[0];
$this->assertContains('ignore_origin_instance_rule.description', $body);
$this->assertContains('ignore_origin_instance_rule.list.create_new_one', $body);
}
public function testIgnoreOriginInstanceRuleCreationEditionDeletion()
{
$this->logInAs('admin');
$client = $this->getClient();
// Creation
$crawler = $client->request('GET', '/ignore-origin-instance-rules/new');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$body = $crawler->filter('body')->extract(['_text'])[0];
$this->assertContains('ignore_origin_instance_rule.new_ignore_origin_instance_rule', $body);
$this->assertContains('ignore_origin_instance_rule.form.back_to_list', $body);
$form = $crawler->filter('button[id=ignore_origin_instance_rule_save]')->form();
$data = [
'ignore_origin_instance_rule[rule]' => 'host = "foo.example.com"',
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$this->assertContains('flashes.ignore_origin_instance_rule.notice.added', $crawler->filter('body')->extract(['_text'])[0]);
// Edition
$editLink = $crawler->filter('div[id=content] table a')->last()->link();
$crawler = $client->click($editLink);
$this->assertSame(200, $client->getResponse()->getStatusCode());
$this->assertContains('foo.example.com', $crawler->filter('form[name=ignore_origin_instance_rule] input[type=text]')->extract(['value'])[0]);
$body = $crawler->filter('body')->extract(['_text'])[0];
$this->assertContains('ignore_origin_instance_rule.edit_ignore_origin_instance_rule', $body);
$this->assertContains('ignore_origin_instance_rule.form.back_to_list', $body);
$form = $crawler->filter('button[id=ignore_origin_instance_rule_save]')->form();
$data = [
'ignore_origin_instance_rule[rule]' => 'host = "bar.example.com"',
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$this->assertContains('flashes.ignore_origin_instance_rule.notice.updated', $crawler->filter('body')->extract(['_text'])[0]);
$editLink = $crawler->filter('div[id=content] table a')->last()->link();
$crawler = $client->click($editLink);
$this->assertSame(200, $client->getResponse()->getStatusCode());
$this->assertContains('bar.example.com', $crawler->filter('form[name=ignore_origin_instance_rule] input[type=text]')->extract(['value'])[0]);
$deleteForm = $crawler->filter('body')->selectButton('ignore_origin_instance_rule.form.delete')->form();
$client->submit($deleteForm, []);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$this->assertContains('flashes.ignore_origin_instance_rule.notice.deleted', $crawler->filter('body')->extract(['_text'])[0]);
}
public function dataForIgnoreOriginInstanceRuleCreationFail()
{
return [
[
[
'ignore_origin_instance_rule[rule]' => 'foo = "bar"',
],
[
'The variable',
'does not exist.',
],
],
[
[
'ignore_origin_instance_rule[rule]' => '_all != "none"',
],
[
'The operator',
'does not exist.',
],
],
];
}
/**
* @dataProvider dataForIgnoreOriginInstanceRuleCreationFail
*/
public function testIgnoreOriginInstanceRuleCreationFail($data, $messages)
{
$this->logInAs('admin');
$client = $this->getClient();
$crawler = $client->request('GET', '/ignore-origin-instance-rules/new');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$form = $crawler->filter('button[id=ignore_origin_instance_rule_save]')->form();
$crawler = $client->submit($form, $data);
$this->assertSame(200, $client->getResponse()->getStatusCode());
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
foreach ($messages as $message) {
$this->assertContains($message, $body[0]);
}
}
}

View file

@ -12,6 +12,7 @@ use Symfony\Component\Validator\ConstraintViolationList;
use Symfony\Component\Validator\Validator\RecursiveValidator;
use Wallabag\CoreBundle\Entity\Entry;
use Wallabag\CoreBundle\Helper\ContentProxy;
use Wallabag\CoreBundle\Helper\RuleBasedIgnoreOriginProcessor;
use Wallabag\CoreBundle\Helper\RuleBasedTagger;
use Wallabag\UserBundle\Entity\User;
@ -25,6 +26,8 @@ class ContentProxyTest extends TestCase
$tagger->expects($this->once())
->method('tag');
$ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
@ -42,7 +45,7 @@ class ContentProxyTest extends TestCase
'language' => '',
]);
$proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$entry = new Entry(new User());
$proxy->updateEntry($entry, 'http://user@:80');
@ -62,6 +65,8 @@ class ContentProxyTest extends TestCase
$tagger->expects($this->once())
->method('tag');
$ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
@ -79,7 +84,7 @@ class ContentProxyTest extends TestCase
'language' => '',
]);
$proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$entry = new Entry(new User());
$proxy->updateEntry($entry, 'http://0.0.0.0');
@ -99,6 +104,8 @@ class ContentProxyTest extends TestCase
$tagger->expects($this->once())
->method('tag');
$ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
@ -118,7 +125,7 @@ class ContentProxyTest extends TestCase
'description' => 'desc',
]);
$proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$entry = new Entry(new User());
$proxy->updateEntry($entry, 'http://domain.io');
@ -139,6 +146,10 @@ class ContentProxyTest extends TestCase
$tagger->expects($this->once())
->method('tag');
$ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
$ruleBasedIgnoreOriginProcessor->expects($this->once())
->method('process');
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
@ -159,7 +170,7 @@ class ContentProxyTest extends TestCase
],
]);
$proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$entry = new Entry(new User());
$proxy->updateEntry($entry, 'http://0.0.0.0');
@ -180,6 +191,10 @@ class ContentProxyTest extends TestCase
$tagger->expects($this->once())
->method('tag');
$ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
$ruleBasedIgnoreOriginProcessor->expects($this->once())
->method('process');
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
@ -200,7 +215,7 @@ class ContentProxyTest extends TestCase
],
]);
$proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$entry = new Entry(new User());
$proxy->updateEntry($entry, 'http://0.0.0.0');
@ -221,6 +236,10 @@ class ContentProxyTest extends TestCase
$tagger->expects($this->once())
->method('tag');
$ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
$ruleBasedIgnoreOriginProcessor->expects($this->once())
->method('process');
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
@ -240,7 +259,7 @@ class ContentProxyTest extends TestCase
'image' => null,
]);
$proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$entry = new Entry(new User());
$proxy->updateEntry($entry, 'http://0.0.0.0');
@ -261,6 +280,10 @@ class ContentProxyTest extends TestCase
$tagger->expects($this->once())
->method('tag');
$ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
$ruleBasedIgnoreOriginProcessor->expects($this->once())
->method('process');
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
@ -280,7 +303,7 @@ class ContentProxyTest extends TestCase
'image' => 'http://3.3.3.3/cover.jpg',
]);
$proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$entry = new Entry(new User());
$proxy->updateEntry($entry, 'http://0.0.0.0');
@ -301,6 +324,10 @@ class ContentProxyTest extends TestCase
$tagger->expects($this->once())
->method('tag');
$ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
$ruleBasedIgnoreOriginProcessor->expects($this->once())
->method('process');
$validator = $this->getValidator(false);
$validator->expects($this->once())
->method('validate')
@ -324,7 +351,7 @@ class ContentProxyTest extends TestCase
],
]);
$proxy = new ContentProxy($graby, $tagger, $validator, $this->getLogger(), $this->fetchingErrorMessage);
$proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $validator, $this->getLogger(), $this->fetchingErrorMessage);
$entry = new Entry(new User());
$proxy->updateEntry($entry, 'http://0.0.0.0');
@ -344,6 +371,10 @@ class ContentProxyTest extends TestCase
$tagger->expects($this->once())
->method('tag');
$ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
$ruleBasedIgnoreOriginProcessor->expects($this->once())
->method('process');
$validator = $this->getValidator(false);
$validator->expects($this->exactly(2))
->method('validate')
@ -372,7 +403,7 @@ class ContentProxyTest extends TestCase
'image' => 'https://',
]);
$proxy = new ContentProxy($graby, $tagger, $validator, $this->getLogger(), $this->fetchingErrorMessage);
$proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $validator, $this->getLogger(), $this->fetchingErrorMessage);
$entry = new Entry(new User());
$proxy->updateEntry($entry, 'http://0.0.0.0');
@ -393,7 +424,11 @@ class ContentProxyTest extends TestCase
$tagger->expects($this->once())
->method('tag');
$proxy = new ContentProxy((new Graby()), $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage, true);
$ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
$ruleBasedIgnoreOriginProcessor->expects($this->once())
->method('process');
$proxy = new ContentProxy((new Graby()), $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage, true);
$entry = new Entry(new User());
$proxy->updateEntry(
$entry,
@ -433,10 +468,12 @@ class ContentProxyTest extends TestCase
$tagger->expects($this->once())
->method('tag');
$ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
$logHandler = new TestHandler();
$logger = new Logger('test', [$logHandler]);
$proxy = new ContentProxy((new Graby()), $tagger, $this->getValidator(), $logger, $this->fetchingErrorMessage);
$proxy = new ContentProxy((new Graby()), $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $logger, $this->fetchingErrorMessage);
$entry = new Entry(new User());
$proxy->updateEntry(
$entry,
@ -469,11 +506,13 @@ class ContentProxyTest extends TestCase
$tagger->expects($this->once())
->method('tag');
$ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
$logger = new Logger('foo');
$handler = new TestHandler();
$logger->pushHandler($handler);
$proxy = new ContentProxy((new Graby()), $tagger, $this->getValidator(), $logger, $this->fetchingErrorMessage);
$proxy = new ContentProxy((new Graby()), $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $logger, $this->fetchingErrorMessage);
$entry = new Entry(new User());
$proxy->updateEntry(
$entry,
@ -512,7 +551,9 @@ class ContentProxyTest extends TestCase
->method('tag')
->will($this->throwException(new \Exception()));
$proxy = new ContentProxy((new Graby()), $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
$proxy = new ContentProxy((new Graby()), $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$entry = new Entry(new User());
$proxy->updateEntry(
$entry,
@ -554,7 +595,9 @@ class ContentProxyTest extends TestCase
$tagger->expects($this->once())
->method('tag');
$proxy = new ContentProxy((new Graby()), $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
$proxy = new ContentProxy((new Graby()), $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$entry = new Entry(new User());
$proxy->updateEntry(
$entry,
@ -590,6 +633,8 @@ class ContentProxyTest extends TestCase
$tagger->expects($this->once())
->method('tag');
$ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
@ -607,7 +652,7 @@ class ContentProxyTest extends TestCase
],
]);
$proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$entry = new Entry(new User());
$proxy->updateEntry($entry, 'http://0.0.0.0');
@ -631,6 +676,8 @@ class ContentProxyTest extends TestCase
$tagger->expects($this->once())
->method('tag');
$ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
@ -648,7 +695,7 @@ class ContentProxyTest extends TestCase
'language' => '',
]);
$proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$entry = new Entry(new User());
$proxy->updateEntry($entry, 'http://0.0.0.0');
@ -668,6 +715,8 @@ class ContentProxyTest extends TestCase
$tagger->expects($this->once())
->method('tag');
$ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
@ -685,7 +734,7 @@ class ContentProxyTest extends TestCase
'language' => '',
]);
$proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$entry = new Entry(new User());
$proxy->updateEntry($entry, 'http://0.0.0.0');
@ -704,6 +753,8 @@ class ContentProxyTest extends TestCase
$tagger->expects($this->once())
->method('tag');
$ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
@ -721,7 +772,7 @@ class ContentProxyTest extends TestCase
'language' => '',
]);
$proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$entry = new Entry(new User());
$proxy->updateEntry($entry, 'http://0.0.0.0');
@ -740,6 +791,8 @@ class ContentProxyTest extends TestCase
$tagger->expects($this->once())
->method('tag');
$ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
@ -757,7 +810,7 @@ class ContentProxyTest extends TestCase
'language' => '',
]);
$proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$entry = new Entry(new User());
$proxy->updateEntry($entry, 'http://0.0.0.0');
@ -776,6 +829,8 @@ class ContentProxyTest extends TestCase
$tagger->expects($this->once())
->method('tag');
$ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
@ -793,7 +848,7 @@ class ContentProxyTest extends TestCase
'language' => '',
]);
$proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$entry = new Entry(new User());
$proxy->updateEntry($entry, 'http://0.0.0.0');
@ -813,6 +868,8 @@ class ContentProxyTest extends TestCase
$tagger->expects($this->once())
->method('tag');
$ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
$graby = $this->getMockBuilder('Graby\Graby')
->setMethods(['fetchContent'])
->disableOriginalConstructor()
@ -830,7 +887,7 @@ class ContentProxyTest extends TestCase
'language' => '',
]);
$proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
$entry = new Entry(new User());
$proxy->updateEntry($entry, 'http://0.0.0.0');
@ -850,6 +907,7 @@ class ContentProxyTest extends TestCase
* $expected_entry_url
* $expected_origin_url
* $expected_domain
* $processor_result
*/
public function dataForChangedUrl()
{
@ -861,6 +919,7 @@ class ContentProxyTest extends TestCase
'http://1.1.1.1',
'http://0.0.0.0',
'1.1.1.1',
false,
],
'origin already set' => [
'http://0.0.0.0',
@ -869,6 +928,7 @@ class ContentProxyTest extends TestCase
'http://1.1.1.1',
'http://hello',
'1.1.1.1',
false,
],
'trailing slash' => [
'https://example.com/hello-world',
@ -877,6 +937,7 @@ class ContentProxyTest extends TestCase
'https://example.com/hello-world/',
null,
'example.com',
false,
],
'query string in fetched content' => [
'https://example.org/hello',
@ -885,6 +946,7 @@ class ContentProxyTest extends TestCase
'https://example.org/hello?world=1',
'https://example.org/hello',
'example.org',
false,
],
'fragment in fetched content' => [
'https://example.org/hello',
@ -893,6 +955,7 @@ class ContentProxyTest extends TestCase
'https://example.org/hello',
null,
'example.org',
false,
],
'fragment and query string in fetched content' => [
'https://example.org/hello',
@ -901,6 +964,7 @@ class ContentProxyTest extends TestCase
'https://example.org/hello?foo#world',
'https://example.org/hello',
'example.org',
false,
],
'different path and query string in fetch content' => [
'https://example.org/hello',
@ -909,6 +973,7 @@ class ContentProxyTest extends TestCase
'https://example.org/world?foo',
'https://example.org/hello',
'example.org',
false,
],
'feedproxy ignore list test' => [
'http://feedproxy.google.com/~r/Wallabag/~3/helloworld',
@ -917,6 +982,7 @@ class ContentProxyTest extends TestCase
'https://example.org/hello-wallabag',
null,
'example.org',
true,
],
'feedproxy ignore list test with origin url already set' => [
'http://feedproxy.google.com/~r/Wallabag/~3/helloworld',
@ -925,6 +991,7 @@ class ContentProxyTest extends TestCase
'https://example.org/hello-wallabag',
'https://example.org/this-is-source',
'example.org',
true,
],
'lemonde ignore pattern test' => [
'http://www.lemonde.fr/tiny/url',
@ -933,6 +1000,7 @@ class ContentProxyTest extends TestCase
'http://example.com/hello-world',
null,
'example.com',
true,
],
];
}
@ -940,13 +1008,18 @@ class ContentProxyTest extends TestCase
/**
* @dataProvider dataForChangedUrl
*/
public function testWithChangedUrl($entry_url, $origin_url, $content_url, $expected_entry_url, $expected_origin_url, $expected_domain)
public function testWithChangedUrl($entry_url, $origin_url, $content_url, $expected_entry_url, $expected_origin_url, $expected_domain, $processor_result)
{
$tagger = $this->getTaggerMock();
$tagger->expects($this->once())
->method('tag');
$proxy = new ContentProxy((new Graby()), $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage, true);
$ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock();
$ruleBasedIgnoreOriginProcessor->expects($this->once())
->method('process')
->willReturn($processor_result);
$proxy = new ContentProxy((new Graby()), $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage, true);
$entry = new Entry(new User());
$entry->setOriginUrl($origin_url);
$proxy->updateEntry(
@ -1015,6 +1088,14 @@ class ContentProxyTest extends TestCase
->getMock();
}
private function getRuleBasedIgnoreOriginProcessorMock()
{
return $this->getMockBuilder(RuleBasedIgnoreOriginProcessor::class)
->setMethods(['process'])
->disableOriginalConstructor()
->getMock();
}
private function getLogger()
{
return new NullLogger();

View file

@ -0,0 +1,212 @@
<?php
namespace Tests\Wallabag\CoreBundle\Helper;
use Monolog\Handler\TestHandler;
use Monolog\Logger;
use PHPUnit\Framework\TestCase;
use Wallabag\CoreBundle\Entity\Config;
use Wallabag\CoreBundle\Entity\Entry;
use Wallabag\CoreBundle\Entity\IgnoreOriginInstanceRule;
use Wallabag\CoreBundle\Entity\IgnoreOriginUserRule;
use Wallabag\CoreBundle\Helper\RuleBasedIgnoreOriginProcessor;
use Wallabag\UserBundle\Entity\User;
class RuleBasedIgnoreOriginProcessorTest extends TestCase
{
private $rulerz;
private $processor;
private $ignoreOriginInstanceRuleRepository;
private $logger;
private $handler;
public function setUp()
{
$this->rulerz = $this->getRulerZMock();
$this->logger = $this->getLogger();
$this->ignoreOriginInstanceRuleRepository = $this->getIgnoreOriginInstanceRuleRepositoryMock();
$this->handler = new TestHandler();
$this->logger->pushHandler($this->handler);
$this->processor = new RuleBasedIgnoreOriginProcessor($this->rulerz, $this->logger, $this->ignoreOriginInstanceRuleRepository);
}
public function testProcessWithNoRule()
{
$user = $this->getUser();
$entry = new Entry($user);
$entry->setUrl('http://example.com/hello-world');
$this->ignoreOriginInstanceRuleRepository
->expects($this->once())
->method('findAll')
->willReturn([]);
$this->rulerz
->expects($this->never())
->method('satisfies');
$result = $this->processor->process($entry);
$this->assertFalse($result);
}
public function testProcessWithNoMatchingRule()
{
$userRule = $this->getIgnoreOriginUserRule('rule as string');
$user = $this->getUser([$userRule]);
$entry = new Entry($user);
$entry->setUrl('http://example.com/hello-world');
$this->ignoreOriginInstanceRuleRepository
->expects($this->once())
->method('findAll')
->willReturn([]);
$this->rulerz
->expects($this->once())
->method('satisfies')
->willReturn(false);
$result = $this->processor->process($entry);
$this->assertFalse($result);
}
public function testProcessWithAMatchingRule()
{
$userRule = $this->getIgnoreOriginUserRule('rule as string');
$user = $this->getUser([$userRule]);
$entry = new Entry($user);
$entry->setUrl('http://example.com/hello-world');
$this->ignoreOriginInstanceRuleRepository
->expects($this->once())
->method('findAll')
->willReturn([]);
$this->rulerz
->expects($this->once())
->method('satisfies')
->willReturn(true);
$result = $this->processor->process($entry);
$this->assertTrue($result);
}
public function testProcessWithAMixOfMatchingRules()
{
$userRule = $this->getIgnoreOriginUserRule('rule as string');
$anotherUserRule = $this->getIgnoreOriginUserRule('another rule as string');
$user = $this->getUser([$userRule, $anotherUserRule]);
$entry = new Entry($user);
$entry->setUrl('http://example.com/hello-world');
$this->ignoreOriginInstanceRuleRepository
->expects($this->once())
->method('findAll')
->willReturn([]);
$this->rulerz
->method('satisfies')
->will($this->onConsecutiveCalls(false, true));
$result = $this->processor->process($entry);
$this->assertTrue($result);
}
public function testProcessWithInstanceRules()
{
$user = $this->getUser();
$entry = new Entry($user);
$entry->setUrl('http://example.com/hello-world');
$instanceRule = $this->getIgnoreOriginInstanceRule('rule as string');
$this->ignoreOriginInstanceRuleRepository
->expects($this->once())
->method('findAll')
->willReturn([$instanceRule]);
$this->rulerz
->expects($this->once())
->method('satisfies')
->willReturn(true);
$result = $this->processor->process($entry);
$this->assertTrue($result);
}
public function testProcessWithMixedRules()
{
$userRule = $this->getIgnoreOriginUserRule('rule as string');
$user = $this->getUser([$userRule]);
$entry = new Entry($user);
$entry->setUrl('http://example.com/hello-world');
$instanceRule = $this->getIgnoreOriginInstanceRule('rule as string');
$this->ignoreOriginInstanceRuleRepository
->expects($this->once())
->method('findAll')
->willReturn([$instanceRule]);
$this->rulerz
->method('satisfies')
->will($this->onConsecutiveCalls(false, true));
$result = $this->processor->process($entry);
$this->assertTrue($result);
}
private function getUser(array $ignoreOriginRules = [])
{
$user = new User();
$config = new Config($user);
$user->setConfig($config);
foreach ($ignoreOriginRules as $rule) {
$config->addIgnoreOriginRule($rule);
}
return $user;
}
private function getIgnoreOriginUserRule($rule)
{
$ignoreOriginUserRule = new IgnoreOriginUserRule();
$ignoreOriginUserRule->setRule($rule);
return $ignoreOriginUserRule;
}
private function getIgnoreOriginInstanceRule($rule)
{
$ignoreOriginInstanceRule = new IgnoreOriginInstanceRule();
$ignoreOriginInstanceRule->setRule($rule);
return $ignoreOriginInstanceRule;
}
private function getRulerZMock()
{
return $this->getMockBuilder('RulerZ\RulerZ')
->disableOriginalConstructor()
->getMock();
}
private function getIgnoreOriginInstanceRuleRepositoryMock()
{
return $this->getMockBuilder('Wallabag\CoreBundle\Repository\IgnoreOriginInstanceRuleRepository')
->disableOriginalConstructor()
->getMock();
}
private function getLogger()
{
return new Logger('foo');
}
}