Ticket #1183: irclogsplugin-0.11-searching.patch

File irclogsplugin-0.11-searching.patch, 3.9 kB (added by thomas.moschny@gmx.de, 6 months ago)

Search functionality for 0.11.

  • irclogs/__init__.py

    old new  
    1111from trac.web.main import IRequestHandler 
    1212from trac.util.html import escape, html, Markup 
    1313from trac.util.text import to_unicode 
     14from trac.util.datefmt import parse_date, format_date 
     15from trac.search import ISearchSource 
    1416 
     17import pyndexter 
    1518 
    1619class IrclogsPlugin(Component): 
    1720    implements(INavigationContributor, ITemplateProvider, IRequestHandler, \ 
    18                IPermissionRequestor
     21               IPermissionRequestor, ISearchSource
    1922    _url_re = re.compile(r'^/irclogs(/(?P<year>\d{4})(/(?P<month>\d{2})' 
    2023                         r'(/(?P<day>\d{2}))?)?)?/?$') 
    2124# TODO: make the line format somewhat configurable 
     
    4447                       doc='If not empty an button with this value as caption ' 
    4548                           'is added to the navigation bar, pointing to the ' 
    4649                           'irc plugin') 
     50    indexer = Option('irclogs', 'indexer', doc='pyndexter indexer URI') 
    4751 
    4852    def _to_unicode(self, iterable): 
    4953        for line in iterable: 
     
    5660              .replace('\\%d', '(?P<day>\d{2})') 
    5761        ) 
    5862 
     63    def _get_file_glob(self): 
     64        if 0: 
     65            return pyndexter.util.quote(self.file_format) \ 
     66                .replace('%25Y', '????') \ 
     67                .replace('%25m', '??')   \ 
     68                .replace('%25d', '??') 
     69        else: # workaround: globs are not working properly 
     70            return "*.log"  
     71 
    5972    def _get_filename(self, year, month, day): 
    6073        return os.path.join(self.path, self.file_format 
    6174                .replace('%Y', str(year)) 
     
    268281    def get_htdocs_dirs(self): 
    269282        from pkg_resources import resource_filename 
    270283        return [('irclogs', resource_filename(__name__, 'htdocs'))] 
     284 
     285    # ISearchSource methods 
     286    def get_search_filters(self, req): 
     287        if not req.perm.has_permission('IRCLOGS_VIEW'): 
     288            return [] 
     289        return [('irclogs', 'IRC Logs', True),] 
     290 
     291    def _find_match(self, text, terms): 
     292        # fixme: why can't pyndexter give us the position(s) where it 
     293        # found the terms? 
     294        for line in text.splitlines(): 
     295            for term in terms: 
     296                if term.lower() in line.lower(): 
     297                    return line 
     298 
     299    def get_search_results(self, req, terms, filters): 
     300        """Return a list of search results matching each search term in `terms`. 
     301         
     302        The `filters` parameters is a list of the enabled filters, each item 
     303        being the name of the tuples returned by `get_search_events`. 
     304 
     305        The events returned by this function must be tuples of the form 
     306        `(href, title, date, author, excerpt).` 
     307        """ 
     308        if not 'irclogs' in filters: 
     309            return 
     310 
     311        framework = pyndexter.Framework( 
     312            indexer=self.indexer, stemmer='porter://', mode=pyndexter.READONLY) 
     313        framework.add_source('file://%s?include=%s' % ( 
     314                pyndexter.util.quote(self.path), self._get_file_glob())) 
     315 
     316        for hit in framework.search(' '.join(terms)): 
     317            file = hit.uri.path.lstrip(self.path) 
     318            fileinfo = self._get_file_re().search(file).groupdict() 
     319 
     320            url = "/irclogs/%(year)s/%(month)s/%(day)s" % fileinfo 
     321            fragment = '' 
     322                 
     323            line = self._find_match(hit.current.content, terms) 
     324            if line: 
     325                lineinfo = self._line_re.search(line).groupdict() 
     326                fragment = "#%(time)s" % lineinfo 
     327                timestamp = parse_date("%(date)sT%(time)s" % lineinfo) 
     328            else: 
     329                timestamp = parse_date("%(year)s-%(month)s-%(day)s" % fileinfo) 
     330 
     331            title = "irclogs for %s" % format_date(timestamp) 
     332 
     333            yield (req.href(url)+fragment, title, timestamp, 'irclog', unicode(hit.excerpt(terms))) 
     334