comparison 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
comparison
equal deleted inserted replaced
2909:52b1c6de19c2 3098:a5f0bc867edc
23 # You should have received a copy of the GNU General Public License 23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>. 24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 25
26 import logging 26 import logging
27 27
28 from pylons import request, tmpl_context as c 28 from pylons import request, tmpl_context as c, url
29 from sqlalchemy.orm import joinedload 29 from sqlalchemy.orm import joinedload
30 from webhelpers.paginate import Page 30 from webhelpers.paginate import Page
31 from whoosh.qparser.default import QueryParser
32 from whoosh import query
33 from sqlalchemy.sql.expression import or_, and_, func
31 34
32 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator 35 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
33 from rhodecode.lib.base import BaseController, render 36 from rhodecode.lib.base import BaseController, render
34 from rhodecode.model.db import UserLog 37 from rhodecode.model.db import UserLog, User
35 from rhodecode.lib.utils2 import safe_int 38 from rhodecode.lib.utils2 import safe_int, remove_prefix, remove_suffix
39 from rhodecode.lib.indexers import JOURNAL_SCHEMA
40 from whoosh.qparser.dateparse import DateParserPlugin
41
36 42
37 log = logging.getLogger(__name__) 43 log = logging.getLogger(__name__)
44
45
46 def _journal_filter(user_log, search_term):
47 """
48 Filters sqlalchemy user_log based on search_term with whoosh Query language
49 http://packages.python.org/Whoosh/querylang.html
50
51 :param user_log:
52 :param search_term:
53 """
54 log.debug('Initial search term: %r' % search_term)
55 qry = None
56 if search_term:
57 qp = QueryParser('repository', schema=JOURNAL_SCHEMA)
58 qp.add_plugin(DateParserPlugin())
59 qry = qp.parse(unicode(search_term))
60 log.debug('Filtering using parsed query %r' % qry)
61
62 def wildcard_handler(col, wc_term):
63 if wc_term.startswith('*') and not wc_term.endswith('*'):
64 #postfix == endswith
65 wc_term = remove_prefix(wc_term, prefix='*')
66 return func.lower(col).endswith(wc_term)
67 elif wc_term.startswith('*') and wc_term.endswith('*'):
68 #wildcard == ilike
69 wc_term = remove_prefix(wc_term, prefix='*')
70 wc_term = remove_suffix(wc_term, suffix='*')
71 return func.lower(col).contains(wc_term)
72
73 def get_filterion(field, val, term):
74
75 if field == 'repository':
76 field = getattr(UserLog, 'repository_name')
77 elif field == 'ip':
78 field = getattr(UserLog, 'user_ip')
79 elif field == 'date':
80 field = getattr(UserLog, 'action_date')
81 elif field == 'username':
82 field = getattr(UserLog, 'username')
83 else:
84 field = getattr(UserLog, field)
85 log.debug('filter field: %s val=>%s' % (field, val))
86
87 #sql filtering
88 if isinstance(term, query.Wildcard):
89 return wildcard_handler(field, val)
90 elif isinstance(term, query.Prefix):
91 return func.lower(field).startswith(func.lower(val))
92 elif isinstance(term, query.DateRange):
93 return and_(field >= val[0], field <= val[1])
94 return func.lower(field) == func.lower(val)
95
96 if isinstance(qry, (query.And, query.Term, query.Prefix, query.Wildcard,
97 query.DateRange)):
98 if not isinstance(qry, query.And):
99 qry = [qry]
100 for term in qry:
101 field = term.fieldname
102 val = (term.text if not isinstance(term, query.DateRange)
103 else [term.startdate, term.enddate])
104 user_log = user_log.filter(get_filterion(field, val, term))
105 elif isinstance(qry, query.Or):
106 filters = []
107 for term in qry:
108 field = term.fieldname
109 val = (term.text if not isinstance(term, query.DateRange)
110 else [term.startdate, term.enddate])
111 filters.append(get_filterion(field, val, term))
112 user_log = user_log.filter(or_(*filters))
113
114 return user_log
38 115
39 116
40 class AdminController(BaseController): 117 class AdminController(BaseController):
41 118
42 @LoginRequired() 119 @LoginRequired()
43 def __before__(self): 120 def __before__(self):
44 super(AdminController, self).__before__() 121 super(AdminController, self).__before__()
45 122
46 @HasPermissionAllDecorator('hg.admin') 123 @HasPermissionAllDecorator('hg.admin')
47 def index(self): 124 def index(self):
48
49 users_log = UserLog.query()\ 125 users_log = UserLog.query()\
50 .options(joinedload(UserLog.user))\ 126 .options(joinedload(UserLog.user))\
51 .options(joinedload(UserLog.repository))\ 127 .options(joinedload(UserLog.repository))
52 .order_by(UserLog.action_date.desc()) 128
129 #FILTERING
130 c.search_term = request.GET.get('filter')
131 try:
132 users_log = _journal_filter(users_log, c.search_term)
133 except:
134 # we want this to crash for now
135 raise
136
137 users_log = users_log.order_by(UserLog.action_date.desc())
53 138
54 p = safe_int(request.params.get('page', 1), 1) 139 p = safe_int(request.params.get('page', 1), 1)
55 c.users_log = Page(users_log, page=p, items_per_page=10) 140
141 def url_generator(**kw):
142 return url.current(filter=c.search_term, **kw)
143
144 c.users_log = Page(users_log, page=p, items_per_page=10, url=url_generator)
56 c.log_data = render('admin/admin_log.html') 145 c.log_data = render('admin/admin_log.html')
57 146
58 if request.environ.get('HTTP_X_PARTIAL_XHR'): 147 if request.environ.get('HTTP_X_PARTIAL_XHR'):
59 return c.log_data 148 return c.log_data
60 return render('admin/admin.html') 149 return render('admin/admin.html')