diff rhodecode/controllers/admin/admin.py @ 3098:a5f0bc867edc rhodecode-0.0.1.5.0

merge with beta
author Marcin Kuzminski <marcin@python-works.com>
date Thu, 13 Dec 2012 22:54:21 +0100
parents d998cc84cf72 86e087bd75ce
children 3563bb7b4b82
line wrap: on
line diff
--- a/rhodecode/controllers/admin/admin.py	Tue Oct 09 00:57:07 2012 +0200
+++ b/rhodecode/controllers/admin/admin.py	Thu Dec 13 22:54:21 2012 +0100
@@ -25,18 +25,95 @@
 
 import logging
 
-from pylons import request, tmpl_context as c
+from pylons import request, tmpl_context as c, url
 from sqlalchemy.orm import joinedload
 from webhelpers.paginate import Page
+from whoosh.qparser.default import QueryParser
+from whoosh import query
+from sqlalchemy.sql.expression import or_, and_, func
 
 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
 from rhodecode.lib.base import BaseController, render
-from rhodecode.model.db import UserLog
-from rhodecode.lib.utils2 import safe_int
+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 _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
+
+    :param user_log:
+    :param search_term:
+    """
+    log.debug('Initial search term: %r' % search_term)
+    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)
+
+    def wildcard_handler(col, wc_term):
+        if wc_term.startswith('*') and not wc_term.endswith('*'):
+            #postfix == endswith
+            wc_term = remove_prefix(wc_term, prefix='*')
+            return func.lower(col).endswith(wc_term)
+        elif wc_term.startswith('*') and wc_term.endswith('*'):
+            #wildcard == ilike
+            wc_term = remove_prefix(wc_term, prefix='*')
+            wc_term = remove_suffix(wc_term, suffix='*')
+            return func.lower(col).contains(wc_term)
+
+    def get_filterion(field, val, term):
+
+        if field == 'repository':
+            field = getattr(UserLog, 'repository_name')
+        elif field == 'ip':
+            field = getattr(UserLog, 'user_ip')
+        elif field == 'date':
+            field = getattr(UserLog, 'action_date')
+        elif field == 'username':
+            field = getattr(UserLog, 'username')
+        else:
+            field = getattr(UserLog, field)
+        log.debug('filter field: %s val=>%s' % (field, val))
+
+        #sql filtering
+        if isinstance(term, query.Wildcard):
+            return wildcard_handler(field, val)
+        elif isinstance(term, query.Prefix):
+            return func.lower(field).startswith(func.lower(val))
+        elif isinstance(term, query.DateRange):
+            return and_(field >= val[0], field <= val[1])
+        return func.lower(field) == func.lower(val)
+
+    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 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 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))
+
+    return user_log
+
+
 class AdminController(BaseController):
 
     @LoginRequired()
@@ -45,14 +122,26 @@
 
     @HasPermissionAllDecorator('hg.admin')
     def index(self):
-
         users_log = UserLog.query()\
                 .options(joinedload(UserLog.user))\
-                .options(joinedload(UserLog.repository))\
-                .order_by(UserLog.action_date.desc())
+                .options(joinedload(UserLog.repository))
+
+        #FILTERING
+        c.search_term = request.GET.get('filter')
+        try:
+            users_log = _journal_filter(users_log, c.search_term)
+        except:
+            # we want this to crash for now
+            raise
+
+        users_log = users_log.order_by(UserLog.action_date.desc())
 
         p = safe_int(request.params.get('page', 1), 1)
-        c.users_log = Page(users_log, page=p, items_per_page=10)
+
+        def url_generator(**kw):
+            return url.current(filter=c.search_term, **kw)
+
+        c.users_log = Page(users_log, page=p, items_per_page=10, url=url_generator)
         c.log_data = render('admin/admin_log.html')
 
         if request.environ.get('HTTP_X_PARTIAL_XHR'):