Edgewall Software

Changeset 17738

Timestamp:
Oct 30, 2023, 12:40:56 PM (9 months ago)
Author:
Dirk Stöcker
Message:

fix #13480 - cache of BadIP and BadContent

Location:
plugins/trunk/spam-filter/tracspamfilter/filters
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • plugins/trunk/spam-filter/tracspamfilter/filters/ip_regex.py

    r17729 r17738  
    2020import re
    2121
     22
    2223from trac.config import BoolOption, IntOption, Option
    23 from trac.core import Component, implements
     24from trac.core import Component, TracError, implements
     25from trac.util.html import tag
     26from trac.util.text import exception_to_unicode
    2427from trac.wiki.api import IWikiChangeListener
    2528from trac.wiki.model import WikiPage
    2629
    27 from tracspamfilter.api import IFilterStrategy, N_
     30from tracspamfilter.api import IFilterStrategy, N_
    2831
    2932
     
    4952
    5053    def __init__(self):
    51         self.patterns = []
    52         page = WikiPage(self.env, 'BadIP')
    53         if page.exists:
    54             self._load_patterns(page)
    55         if self.badcontent_file != '':
    56             file = open(self.badcontent_file, 'r')
    57             if file is None:
    58                 self.log.warning("BadIP file cannot be opened")
    59             else:
    60                 lines = file.read().splitlines()
    61                 pat = [re.compile(p.strip()) for p in lines if p.strip()]
    62                 self.log.debug("Loaded %s patterns from BadIP file", len(pat))
    63                 self.patterns += pat
     54        self._patterns_file = self._load_file(self.badcontent_file)
    6455
    6556    # IFilterStrategy implementation
     
    9485    def wiki_page_changed(self, page, *args):
    9586        if page.name == 'BadIP':
    96             self._load_patterns(page)
     87            self._load_page(page)
     88            del self._patterns_page
     89
    9790    wiki_page_added = wiki_page_changed
    9891    wiki_page_version_deleted = wiki_page_changed
     
    10093    def wiki_page_deleted(self, page):
    10194        if page.name == 'BadIP':
    102             self.patterns = []
     95           
    10396
    10497    # Internal methods
    10598
    106     def _load_patterns(self, page):
     99    @property
     100    def patterns(self):
     101        for pattern in self._patterns_file:
     102            yield pattern
     103        for pattern in self._patterns_page:
     104            yield pattern
     105
     106    @cached
     107    def _patterns_page(self):
     108        page = WikiPage(self.env, 'BadIP')
     109        if page.exists:
     110            try:
     111                return self._load_page(page)
     112            except TracError:
     113                pass
     114        return []
     115
     116    def _load_file(self, filename):
     117        if not filename:
     118            return []
     119        try:
     120            f = open(filename, 'r')
     121        except EnvironmentError as e:
     122            self.log.warning("BadIP file cannot be opened (%s)",
     123                             exception_to_unicode(e))
     124            return []
     125        patterns = []
     126        with f:
     127            for line in f:
     128                line = line.strip()
     129                if not line:
     130                    continue
     131                patterns.append(re.compile(line))
     132            self.log.debug("Loaded %s patterns from BadIP file", len(patterns))
     133        return patterns
     134
     135    def _load_page(self, page):
     136        patterns = []
    107137        if '{{{' in page.text and '}}}' in page.text:
    108             lines = page.text.split('{{{', 1)[1].split('}}}', 1)[0].splitlines()
    109             self.patterns = [re.compile(p.strip()) for p in lines if p.strip()]
    110             self.log.debug("Loaded %s patterns from BadIP",
    111                            len(self.patterns))
     138            lines = page.text.split('{{{', 1)[1].split('}}}', 1)[0]
     139            for p in lines.splitlines():
     140                p = p.strip()
     141                if not p:
     142                    continue
     143                try:
     144                    patterns.append(re.compile(p))
     145                except re.error as e:
     146                    self.log.debug("Error in pattern %s: %s", p, e)
     147                    raise TracError(tag_("Error in pattern %(pattern)s: "
     148                                         "%(error)s.", pattern=tag.tt(p),
     149                                         error=tag.i(e)))
     150            self.log.debug("Loaded %s patterns from BadIP", len(patterns))
    112151        else:
    113152            self.log.warning("BadIP page does not contain any patterns")
    114             self.patterns = []
     153       
  • plugins/trunk/spam-filter/tracspamfilter/filters/regex.py

    r17729 r17738  
    1818import re
    1919
     20
    2021from trac.config import BoolOption, IntOption, Option
    2122from trac.core import Component, TracError, implements
    2223from trac.util.html import tag
     24
    2325from trac.wiki.api import IWikiChangeListener, IWikiPageManipulator
    2426from trac.wiki.model import WikiPage
     
    4749
    4850    def __init__(self):
    49         self.patterns = []
    50         page = WikiPage(self.env, 'BadContent')
    51         if page.exists:
    52             try:
    53                 self._load_patterns(page)
    54             except TracError:
    55                 pass
    56         if self.badcontent_file != '':
    57             with open(self.badcontent_file, 'r') as file:
    58                 if file is None:
    59                     self.log.warning("BadContent file cannot be opened")
    60                 else:
    61                     lines = file.read().splitlines()
    62                     pat = [re.compile(p.strip()) for p in lines if p.strip()]
    63                     self.log.debug("Loaded %s patterns from BadContent file",
    64                                    len(pat))
    65                     self.patterns += pat
     51        self._patterns_file = self._load_file(self.badcontent_file)
    6652
    6753    # IFilterStrategy implementation
     
    10490        if page.name == 'BadContent':
    10591            try:
    106                 self._load_patterns(page)
     92                self._load_pa(page)
    10793            except TracError as e:
    10894                return [(None, e)]
     
    11399    def wiki_page_changed(self, page, *args):
    114100        if page.name == 'BadContent':
    115             self._load_patterns(page)
     101            self._load_page(page)  # verify patterns
     102            del self._patterns_page
    116103
    117104    wiki_page_added = wiki_page_changed
     
    121108    def wiki_page_deleted(self, page):
    122109        if page.name == 'BadContent':
    123             self.patterns = []
     110           
    124111
    125112    # Internal methods
    126113
    127     def _load_patterns(self, page):
     114    @property
     115    def patterns(self):
     116        for pattern in self._patterns_file:
     117            yield pattern
     118        for pattern in self._patterns_page:
     119            yield pattern
     120
     121    @cached
     122    def _patterns_page(self):
     123        page = WikiPage(self.env, 'BadContent')
     124        if page.exists:
     125            try:
     126                return self._load_page(page)
     127            except TracError:
     128                pass
     129        return []
     130
     131    def _load_file(self, filename):
     132        if not filename:
     133            return []
     134        try:
     135            f = open(filename, 'r')
     136        except EnvironmentError as e:
     137            self.log.warning("BadContent file cannot be opened (%s)",
     138                             exception_to_unicode(e))
     139            return []
     140        patterns = []
     141        with f:
     142            for line in f:
     143                line = line.strip()
     144                if not line:
     145                    continue
     146                patterns.append(re.compile(line))
     147            self.log.debug("Loaded %s patterns from BadContent file",
     148                           len(patterns))
     149        return patterns
     150
     151    def _load_page(self, page):
     152        patterns = []
    128153        if '{{{' in page.text and '}}}' in page.text:
    129154            lines = page.text.split('{{{', 1)[1].split('}}}', 1)[0]
     
    131156            for p in lines:
    132157                try:
    133                     self.patterns.append(re.compile(p))
     158                    patterns.append(re.compile(p))
    134159                except re.error as e:
    135160                    raise TracError(tag_("Error in pattern %(pattern)s: "
    136161                                         "%(error)s.", pattern=tag.code(p),
    137162                                         error=tag.i(e)))
    138             self.log.debug("Loaded %s patterns from BadContent",
    139                            len(self.patterns))
     163            self.log.debug("Loaded %s patterns from BadContent", len(patterns))
    140164        else:
    141165            self.log.warning("BadContent page does not contain any patterns")
    142             self.patterns = []
     166       
  • plugins/trunk/spam-filter/tracspamfilter/filters/tests/regex.py

    r17729 r17738  
    2121from trac.wiki.web_ui import WikiModule
    2222
    23 from tracspamfilter.filters import regex
    2423from tracspamfilter.filters.regex import RegexFilterStrategy
    25 
    26 
    27 class DummyWikiPage(object):
    28 
    29     def __init__(self):
    30         self.text = ''
    31 
    32     def __call__(self, env, name):
    33         self.env = env
    34         self.name = name
    35         self.exists = True
    36         return self
    3724
    3825
     
    4229        self.env = EnvironmentStub(enable=['trac.*', RegexFilterStrategy],
    4330                                   default_data=True)
    44         self.page = regex.WikiPage = DummyWikiPage()
    4531        self.strategy = RegexFilterStrategy(self.env)
    4632
     
    6652    def test_one_matching_pattern(self):
    6753        req = MockRequest(self.env)
    68         self.page.text = """{{{
     54        page = WikiPage(self.env)
     55        page.name = 'BadContent'
     56        page.text = """{{{
    6957foobar
    7058}}}"""
    71         self.strategy.wiki_page_changed(self.page)
     59        )
    7260        rv = self.strategy.test(req, 'anonymous', 'foobar', '127.0.0.1')
    7361        self.assertEqual((-5, "Content contained these blacklisted "
     
    7563
    7664    def test_multiple_matching_pattern(self):
    77         self.page.text = """{{{
     65        page = WikiPage(self.env)
     66        page.name = 'BadContent'
     67        page.text = """{{{
    7868foobar
    7969^foo
    8070bar$
    8171}}}"""
    82         self.strategy.wiki_page_changed(self.page)
     72        )
    8373        req = MockRequest(self.env)
    8474        rv = self.strategy.test(req, 'anonymous', '\nfoobar', '127.0.0.1')
Note: See TracChangeset for help on using the changeset viewer.