# HG changeset patch # User Marcin Kuzminski # Date 1354834512 -3600 # Node ID cc7eedb5323cf00a0ca7eaba1d0f9cb81a50c0ff # Parent 9dca99ffd495fb9ec465a35c9d5ad8badc676bb2 final implementation of #210 journal filtering. diff -r 9dca99ffd495 -r cc7eedb5323c rhodecode/controllers/admin/admin.py --- a/rhodecode/controllers/admin/admin.py Thu Dec 06 21:57:24 2012 +0100 +++ b/rhodecode/controllers/admin/admin.py Thu Dec 06 23:55:12 2012 +0100 @@ -30,19 +30,20 @@ from webhelpers.paginate import Page from whoosh.qparser.default import QueryParser from whoosh import query -from sqlalchemy.sql.expression import or_ +from sqlalchemy.sql.expression import or_, and_ from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator from rhodecode.lib.base import BaseController, render from rhodecode.model.db import UserLog, User from rhodecode.lib.utils2 import safe_int, remove_prefix, remove_suffix from rhodecode.lib.indexers import JOURNAL_SCHEMA +from whoosh.qparser.dateparse import DateParserPlugin log = logging.getLogger(__name__) -def _filter(user_log, search_term): +def _journal_filter(user_log, search_term): """ Filters sqlalchemy user_log based on search_term with whoosh Query language http://packages.python.org/Whoosh/querylang.html @@ -54,6 +55,7 @@ qry = None if search_term: qp = QueryParser('repository', schema=JOURNAL_SCHEMA) + qp.add_plugin(DateParserPlugin()) qry = qp.parse(unicode(search_term)) log.debug('Filtering using parsed query %r' % qry) @@ -87,20 +89,25 @@ return wildcard_handler(field, val) elif isinstance(term, query.Prefix): return field.startswith(val) + elif isinstance(term, query.DateRange): + return and_(field >= val[0], field <= val[1]) return field == val - if isinstance(qry, (query.And, query.Term, query.Prefix, query.Wildcard)): + if isinstance(qry, (query.And, query.Term, query.Prefix, query.Wildcard, + query.DateRange)): if not isinstance(qry, query.And): qry = [qry] for term in qry: field = term.fieldname - val = term.text + val = (term.text if not isinstance(term, query.DateRange) + else [term.startdate, term.enddate]) user_log = user_log.filter(get_filterion(field, val, term)) elif isinstance(qry, query.Or): filters = [] for term in qry: field = term.fieldname - val = term.text + val = (term.text if not isinstance(term, query.DateRange) + else [term.startdate, term.enddate]) filters.append(get_filterion(field, val, term)) user_log = user_log.filter(or_(*filters)) @@ -122,7 +129,7 @@ #FILTERING c.search_term = request.GET.get('filter') try: - users_log = _filter(users_log, c.search_term) + users_log = _journal_filter(users_log, c.search_term) except: # we want this to crash for now raise diff -r 9dca99ffd495 -r cc7eedb5323c rhodecode/controllers/journal.py --- a/rhodecode/controllers/journal.py Thu Dec 06 21:57:24 2012 +0100 +++ b/rhodecode/controllers/journal.py Thu Dec 06 23:55:12 2012 +0100 @@ -42,6 +42,7 @@ from sqlalchemy.sql.expression import func from rhodecode.model.scm import ScmModel from rhodecode.lib.utils2 import safe_int +from rhodecode.controllers.admin.admin import _journal_filter log = logging.getLogger(__name__) @@ -65,9 +66,14 @@ .options(joinedload(UserFollowing.follows_repository))\ .all() + #FILTERING + c.search_term = request.GET.get('filter') journal = self._get_journal_data(c.following) - c.journal_pager = Page(journal, page=p, items_per_page=20) + def url_generator(**kw): + return url.current(filter=c.search_term, **kw) + + c.journal_pager = Page(journal, page=p, items_per_page=20, url=url_generator) c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager) c.journal_data = render('journal/journal_data.html') @@ -141,9 +147,15 @@ if filtering_criterion is not None: journal = self.sa.query(UserLog)\ .options(joinedload(UserLog.user))\ - .options(joinedload(UserLog.repository))\ - .filter(filtering_criterion)\ - .order_by(UserLog.action_date.desc()) + .options(joinedload(UserLog.repository)) + #filter + try: + journal = _journal_filter(journal, c.search_term) + except: + # we want this to crash for now + raise + journal = journal.filter(filtering_criterion)\ + .order_by(UserLog.action_date.desc()) else: journal = [] diff -r 9dca99ffd495 -r cc7eedb5323c rhodecode/lib/helpers.py --- a/rhodecode/lib/helpers.py Thu Dec 06 21:57:24 2012 +0100 +++ b/rhodecode/lib/helpers.py Thu Dec 06 23:55:12 2012 +0100 @@ -11,6 +11,7 @@ import logging import re import urlparse +import textwrap from datetime import datetime from pygments.formatters.html import HtmlFormatter @@ -1135,3 +1136,23 @@ def get_permission_name(key): return dict(Permission.PERMS).get(key) + + +def journal_filter_help(): + return _(textwrap.dedent(''' + Example filter terms: + repository:vcs + username:marcin + action:*push* + ip:127.0.0.1 + date:20120101 + date:[20120101100000 TO 20120102] + + Generate wildcards using '*' character: + "repositroy:vcs*" - search everything starting with 'vcs' + "repository:*vcs*" - search for repository containing 'vcs' + + Optional AND / OR operators in queries + "repository:vcs OR repository:test" + "username:test AND repository:test*" + ''')) diff -r 9dca99ffd495 -r cc7eedb5323c rhodecode/templates/admin/admin.html --- a/rhodecode/templates/admin/admin.html Thu Dec 06 21:57:24 2012 +0100 +++ b/rhodecode/templates/admin/admin.html Thu Dec 06 23:55:12 2012 +0100 @@ -7,25 +7,8 @@ <%def name="breadcrumbs_links()">
- - ? + + ? ${_('Admin journal')} - ${ungettext('%s entry', '%s entries', c.users_log.item_count) % (c.users_log.item_count)}
@@ -50,24 +33,24 @@ diff -r 9dca99ffd495 -r cc7eedb5323c rhodecode/templates/journal/journal.html --- a/rhodecode/templates/journal/journal.html Thu Dec 06 21:57:24 2012 +0100 +++ b/rhodecode/templates/journal/journal.html Thu Dec 06 23:55:12 2012 +0100 @@ -4,7 +4,15 @@ ${_('Journal')} - ${c.rhodecode_name} <%def name="breadcrumbs()"> - ${c.rhodecode_name} +
+
+ + ? + + ${_('journal')} - ${ungettext('%s entry', '%s entries', c.journal_pager.item_count) % (c.journal_pager.item_count)} +
+ ${h.end_form()} +
<%def name="page_nav()"> ${self.menu('home')} @@ -18,18 +26,18 @@
-
${_('Journal')}
- + ${self.breadcrumbs()} +
${c.journal_data}
@@ -106,6 +114,26 @@