##// END OF EJS Templates
action-parser: fixed filter call
super-admin -
r4970:5ee395cb default
parent child Browse files
Show More
@@ -1,357 +1,357 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2020 RhodeCode GmbH
3 # Copyright (C) 2010-2020 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import logging
21 import logging
22
22
23 from webhelpers2.html.builder import literal
23 from webhelpers2.html.builder import literal
24 from webhelpers2.html.tags import link_to
24 from webhelpers2.html.tags import link_to
25
25
26 from rhodecode.lib.utils2 import AttributeDict
26 from rhodecode.lib.utils2 import AttributeDict
27 from rhodecode.lib.vcs.backends.base import BaseCommit
27 from rhodecode.lib.vcs.backends.base import BaseCommit
28 from rhodecode.lib.vcs.exceptions import CommitDoesNotExistError
28 from rhodecode.lib.vcs.exceptions import CommitDoesNotExistError
29
29
30
30
31 log = logging.getLogger(__name__)
31 log = logging.getLogger(__name__)
32
32
33
33
34 def action_parser(request, user_log, feed=False, parse_cs=False):
34 def action_parser(request, user_log, feed=False, parse_cs=False):
35 """
35 """
36 This helper will action_map the specified string action into translated
36 This helper will action_map the specified string action into translated
37 fancy names with icons and links
37 fancy names with icons and links
38
38
39 :param user_log: user log instance
39 :param user_log: user log instance
40 :param feed: use output for feeds (no html and fancy icons)
40 :param feed: use output for feeds (no html and fancy icons)
41 :param parse_cs: parse Changesets into VCS instances
41 :param parse_cs: parse Changesets into VCS instances
42 """
42 """
43 if user_log.version == 'v2':
43 if user_log.version == 'v2':
44 ap = AuditLogParser(request, user_log)
44 ap = AuditLogParser(request, user_log)
45 return ap.callbacks()
45 return ap.callbacks()
46 else:
46 else:
47 # old style
47 # old style
48 ap = ActionParser(request, user_log, feed=False, parse_commits=False)
48 ap = ActionParser(request, user_log, feed=False, parse_commits=False)
49 return ap.callbacks()
49 return ap.callbacks()
50
50
51
51
52 class ActionParser(object):
52 class ActionParser(object):
53
53
54 commits_limit = 3 # display this amount always
54 commits_limit = 3 # display this amount always
55 commits_top_limit = 50 # show up to this amount of commits hidden
55 commits_top_limit = 50 # show up to this amount of commits hidden
56
56
57 def __init__(self, request, user_log, feed=False, parse_commits=False):
57 def __init__(self, request, user_log, feed=False, parse_commits=False):
58 self.user_log = user_log
58 self.user_log = user_log
59 self.feed = feed
59 self.feed = feed
60 self.parse_commits = parse_commits
60 self.parse_commits = parse_commits
61 self.request = request
61 self.request = request
62
62
63 self.action = user_log.action
63 self.action = user_log.action
64 self.action_params = ' '
64 self.action_params = ' '
65 x = self.action.split(':', 1)
65 x = self.action.split(':', 1)
66 if len(x) > 1:
66 if len(x) > 1:
67 self.action, self.action_params = x
67 self.action, self.action_params = x
68
68
69 def callbacks(self):
69 def callbacks(self):
70 action_str = self.action_map.get(self.action, self.action)
70 action_str = self.action_map.get(self.action, self.action)
71 if self.feed:
71 if self.feed:
72 action = action_str[0].replace('[', '').replace(']', '')
72 action = action_str[0].replace('[', '').replace(']', '')
73 else:
73 else:
74 action = action_str[0]\
74 action = action_str[0]\
75 .replace('[', '<span class="journal_highlight">')\
75 .replace('[', '<span class="journal_highlight">')\
76 .replace(']', '</span>')
76 .replace(']', '</span>')
77
77
78 action_params_func = _no_params_func
78 action_params_func = _no_params_func
79 if callable(action_str[1]):
79 if callable(action_str[1]):
80 action_params_func = action_str[1]
80 action_params_func = action_str[1]
81
81
82 # returned callbacks we need to call to get
82 # returned callbacks we need to call to get
83 return [
83 return [
84 lambda: literal(action), action_params_func,
84 lambda: literal(action), action_params_func,
85 self.action_parser_icon]
85 self.action_parser_icon]
86
86
87 @property
87 @property
88 def action_map(self):
88 def action_map(self):
89 _ = self.request.translate
89 _ = self.request.translate
90 # action : translated str, callback(extractor), icon
90 # action : translated str, callback(extractor), icon
91 action_map = {
91 action_map = {
92 'user_deleted_repo': (
92 'user_deleted_repo': (
93 _('[deleted] repository'),
93 _('[deleted] repository'),
94 None, 'icon-trash'),
94 None, 'icon-trash'),
95 'user_created_repo': (
95 'user_created_repo': (
96 _('[created] repository'),
96 _('[created] repository'),
97 None, 'icon-plus icon-plus-colored'),
97 None, 'icon-plus icon-plus-colored'),
98 'user_created_fork': (
98 'user_created_fork': (
99 _('[created] repository as fork'),
99 _('[created] repository as fork'),
100 None, 'icon-code-fork'),
100 None, 'icon-code-fork'),
101 'user_forked_repo': (
101 'user_forked_repo': (
102 _('[forked] repository'),
102 _('[forked] repository'),
103 self.get_fork_name, 'icon-code-fork'),
103 self.get_fork_name, 'icon-code-fork'),
104 'user_updated_repo': (
104 'user_updated_repo': (
105 _('[updated] repository'),
105 _('[updated] repository'),
106 None, 'icon-pencil icon-pencil-colored'),
106 None, 'icon-pencil icon-pencil-colored'),
107 'user_downloaded_archive': (
107 'user_downloaded_archive': (
108 _('[downloaded] archive from repository'),
108 _('[downloaded] archive from repository'),
109 self.get_archive_name, 'icon-download-alt'),
109 self.get_archive_name, 'icon-download-alt'),
110 'admin_deleted_repo': (
110 'admin_deleted_repo': (
111 _('[delete] repository'),
111 _('[delete] repository'),
112 None, 'icon-trash'),
112 None, 'icon-trash'),
113 'admin_created_repo': (
113 'admin_created_repo': (
114 _('[created] repository'),
114 _('[created] repository'),
115 None, 'icon-plus icon-plus-colored'),
115 None, 'icon-plus icon-plus-colored'),
116 'admin_forked_repo': (
116 'admin_forked_repo': (
117 _('[forked] repository'),
117 _('[forked] repository'),
118 None, 'icon-code-fork icon-fork-colored'),
118 None, 'icon-code-fork icon-fork-colored'),
119 'admin_updated_repo': (
119 'admin_updated_repo': (
120 _('[updated] repository'),
120 _('[updated] repository'),
121 None, 'icon-pencil icon-pencil-colored'),
121 None, 'icon-pencil icon-pencil-colored'),
122 'admin_created_user': (
122 'admin_created_user': (
123 _('[created] user'),
123 _('[created] user'),
124 self.get_user_name, 'icon-user icon-user-colored'),
124 self.get_user_name, 'icon-user icon-user-colored'),
125 'admin_updated_user': (
125 'admin_updated_user': (
126 _('[updated] user'),
126 _('[updated] user'),
127 self.get_user_name, 'icon-user icon-user-colored'),
127 self.get_user_name, 'icon-user icon-user-colored'),
128 'admin_created_users_group': (
128 'admin_created_users_group': (
129 _('[created] user group'),
129 _('[created] user group'),
130 self.get_users_group, 'icon-pencil icon-pencil-colored'),
130 self.get_users_group, 'icon-pencil icon-pencil-colored'),
131 'admin_updated_users_group': (
131 'admin_updated_users_group': (
132 _('[updated] user group'),
132 _('[updated] user group'),
133 self.get_users_group, 'icon-pencil icon-pencil-colored'),
133 self.get_users_group, 'icon-pencil icon-pencil-colored'),
134 'user_commented_revision': (
134 'user_commented_revision': (
135 _('[commented] on commit in repository'),
135 _('[commented] on commit in repository'),
136 self.get_cs_links, 'icon-comment icon-comment-colored'),
136 self.get_cs_links, 'icon-comment icon-comment-colored'),
137 'user_commented_pull_request': (
137 'user_commented_pull_request': (
138 _('[commented] on pull request for'),
138 _('[commented] on pull request for'),
139 self.get_pull_request, 'icon-comment icon-comment-colored'),
139 self.get_pull_request, 'icon-comment icon-comment-colored'),
140 'user_closed_pull_request': (
140 'user_closed_pull_request': (
141 _('[closed] pull request for'),
141 _('[closed] pull request for'),
142 self.get_pull_request, 'icon-check'),
142 self.get_pull_request, 'icon-check'),
143 'user_merged_pull_request': (
143 'user_merged_pull_request': (
144 _('[merged] pull request for'),
144 _('[merged] pull request for'),
145 self.get_pull_request, 'icon-check'),
145 self.get_pull_request, 'icon-check'),
146 'push': (
146 'push': (
147 _('[pushed] into'),
147 _('[pushed] into'),
148 self.get_cs_links, 'icon-arrow-up'),
148 self.get_cs_links, 'icon-arrow-up'),
149 'push_local': (
149 'push_local': (
150 _('[committed via RhodeCode] into repository'),
150 _('[committed via RhodeCode] into repository'),
151 self.get_cs_links, 'icon-pencil icon-pencil-colored'),
151 self.get_cs_links, 'icon-pencil icon-pencil-colored'),
152 'push_remote': (
152 'push_remote': (
153 _('[pulled from remote] into repository'),
153 _('[pulled from remote] into repository'),
154 self.get_cs_links, 'icon-arrow-up'),
154 self.get_cs_links, 'icon-arrow-up'),
155 'pull': (
155 'pull': (
156 _('[pulled] from'),
156 _('[pulled] from'),
157 None, 'icon-arrow-down'),
157 None, 'icon-arrow-down'),
158 'started_following_repo': (
158 'started_following_repo': (
159 _('[started following] repository'),
159 _('[started following] repository'),
160 None, 'icon-heart icon-heart-colored'),
160 None, 'icon-heart icon-heart-colored'),
161 'stopped_following_repo': (
161 'stopped_following_repo': (
162 _('[stopped following] repository'),
162 _('[stopped following] repository'),
163 None, 'icon-heart-empty icon-heart-colored'),
163 None, 'icon-heart-empty icon-heart-colored'),
164 }
164 }
165 return action_map
165 return action_map
166
166
167 def get_fork_name(self):
167 def get_fork_name(self):
168 from rhodecode.lib import helpers as h
168 from rhodecode.lib import helpers as h
169 _ = self.request.translate
169 _ = self.request.translate
170 repo_name = self.action_params
170 repo_name = self.action_params
171 _url = h.route_path('repo_summary', repo_name=repo_name)
171 _url = h.route_path('repo_summary', repo_name=repo_name)
172 return _('fork name %s') % link_to(self.action_params, _url)
172 return _('fork name %s') % link_to(self.action_params, _url)
173
173
174 def get_user_name(self):
174 def get_user_name(self):
175 user_name = self.action_params
175 user_name = self.action_params
176 return user_name
176 return user_name
177
177
178 def get_users_group(self):
178 def get_users_group(self):
179 group_name = self.action_params
179 group_name = self.action_params
180 return group_name
180 return group_name
181
181
182 def get_pull_request(self):
182 def get_pull_request(self):
183 from rhodecode.lib import helpers as h
183 from rhodecode.lib import helpers as h
184 _ = self.request.translate
184 _ = self.request.translate
185 pull_request_id = self.action_params
185 pull_request_id = self.action_params
186 if self.is_deleted():
186 if self.is_deleted():
187 repo_name = self.user_log.repository_name
187 repo_name = self.user_log.repository_name
188 else:
188 else:
189 repo_name = self.user_log.repository.repo_name
189 repo_name = self.user_log.repository.repo_name
190 return link_to(
190 return link_to(
191 _('Pull request #%s') % pull_request_id,
191 _('Pull request #%s') % pull_request_id,
192 h.route_path('pullrequest_show', repo_name=repo_name,
192 h.route_path('pullrequest_show', repo_name=repo_name,
193 pull_request_id=pull_request_id))
193 pull_request_id=pull_request_id))
194
194
195 def get_archive_name(self):
195 def get_archive_name(self):
196 archive_name = self.action_params
196 archive_name = self.action_params
197 return archive_name
197 return archive_name
198
198
199 def action_parser_icon(self):
199 def action_parser_icon(self):
200 tmpl = """<i class="%s" alt="%s"></i>"""
200 tmpl = """<i class="%s" alt="%s"></i>"""
201 ico = self.action_map.get(self.action, ['', '', ''])[2]
201 ico = self.action_map.get(self.action, ['', '', ''])[2]
202 return literal(tmpl % (ico, self.action))
202 return literal(tmpl % (ico, self.action))
203
203
204 def get_cs_links(self):
204 def get_cs_links(self):
205 from rhodecode.lib import helpers as h
205 from rhodecode.lib import helpers as h
206 _ = self.request.translate
206 _ = self.request.translate
207 if self.is_deleted():
207 if self.is_deleted():
208 return self.action_params
208 return self.action_params
209
209
210 repo_name = self.user_log.repository.repo_name
210 repo_name = self.user_log.repository.repo_name
211 commit_ids = self.action_params.split(',')
211 commit_ids = self.action_params.split(',')
212 commits = self.get_commits(commit_ids)
212 commits = self.get_commits(commit_ids)
213
213
214 link_generator = (
214 link_generator = (
215 self.lnk(commit, repo_name)
215 self.lnk(commit, repo_name)
216 for commit in commits[:self.commits_limit])
216 for commit in commits[:self.commits_limit])
217 commit_links = [" " + ', '.join(link_generator)]
217 commit_links = [" " + ', '.join(link_generator)]
218 _op1, _name1 = _get_op(commit_ids[0])
218 _op1, _name1 = _get_op(commit_ids[0])
219 _op2, _name2 = _get_op(commit_ids[-1])
219 _op2, _name2 = _get_op(commit_ids[-1])
220
220
221 commit_id_range = '%s...%s' % (_name1, _name2)
221 commit_id_range = '%s...%s' % (_name1, _name2)
222
222
223 compare_view = (
223 compare_view = (
224 ' <div class="compare_view tooltip" title="%s">'
224 ' <div class="compare_view tooltip" title="%s">'
225 '<a href="%s">%s</a> </div>' % (
225 '<a href="%s">%s</a> </div>' % (
226 _('Show all combined commits %s->%s') % (
226 _('Show all combined commits %s->%s') % (
227 commit_ids[0][:12], commit_ids[-1][:12]
227 commit_ids[0][:12], commit_ids[-1][:12]
228 ),
228 ),
229 h.route_path(
229 h.route_path(
230 'repo_commit', repo_name=repo_name,
230 'repo_commit', repo_name=repo_name,
231 commit_id=commit_id_range), _('compare view')
231 commit_id=commit_id_range), _('compare view')
232 )
232 )
233 )
233 )
234
234
235 if len(commit_ids) > self.commits_limit:
235 if len(commit_ids) > self.commits_limit:
236 more_count = len(commit_ids) - self.commits_limit
236 more_count = len(commit_ids) - self.commits_limit
237 commit_links.append(
237 commit_links.append(
238 _(' and %(num)s more commits') % {'num': more_count}
238 _(' and %(num)s more commits') % {'num': more_count}
239 )
239 )
240
240
241 if len(commits) > 1:
241 if len(commits) > 1:
242 commit_links.append(compare_view)
242 commit_links.append(compare_view)
243 return ''.join(commit_links)
243 return ''.join(commit_links)
244
244
245 def get_commits(self, commit_ids):
245 def get_commits(self, commit_ids):
246 commits = []
246 commits = []
247 if not filter(lambda v: v != '', commit_ids):
247 if not [v for v in commit_ids if v != '']:
248 return commits
248 return commits
249
249
250 repo = None
250 repo = None
251 if self.parse_commits:
251 if self.parse_commits:
252 repo = self.user_log.repository.scm_instance()
252 repo = self.user_log.repository.scm_instance()
253
253
254 for commit_id in commit_ids[:self.commits_top_limit]:
254 for commit_id in commit_ids[:self.commits_top_limit]:
255 _op, _name = _get_op(commit_id)
255 _op, _name = _get_op(commit_id)
256
256
257 # we want parsed commits, or new log store format is bad
257 # we want parsed commits, or new log store format is bad
258 if self.parse_commits:
258 if self.parse_commits:
259 try:
259 try:
260 commit = repo.get_commit(commit_id=commit_id)
260 commit = repo.get_commit(commit_id=commit_id)
261 commits.append(commit)
261 commits.append(commit)
262 except CommitDoesNotExistError:
262 except CommitDoesNotExistError:
263 log.error(
263 log.error(
264 'cannot find commit id %s in this repository',
264 'cannot find commit id %s in this repository',
265 commit_id)
265 commit_id)
266 commits.append(commit_id)
266 commits.append(commit_id)
267 continue
267 continue
268 else:
268 else:
269 fake_commit = AttributeDict({
269 fake_commit = AttributeDict({
270 'short_id': commit_id[:12],
270 'short_id': commit_id[:12],
271 'raw_id': commit_id,
271 'raw_id': commit_id,
272 'message': '',
272 'message': '',
273 'op': _op,
273 'op': _op,
274 'ref_name': _name
274 'ref_name': _name
275 })
275 })
276 commits.append(fake_commit)
276 commits.append(fake_commit)
277
277
278 return commits
278 return commits
279
279
280 def lnk(self, commit_or_id, repo_name):
280 def lnk(self, commit_or_id, repo_name):
281 from rhodecode.lib.helpers import tooltip
281 from rhodecode.lib.helpers import tooltip
282 from rhodecode.lib import helpers as h
282 from rhodecode.lib import helpers as h
283 _ = self.request.translate
283 _ = self.request.translate
284 title = ''
284 title = ''
285 lazy_cs = True
285 lazy_cs = True
286 if isinstance(commit_or_id, (BaseCommit, AttributeDict)):
286 if isinstance(commit_or_id, (BaseCommit, AttributeDict)):
287 lazy_cs = True
287 lazy_cs = True
288 if (getattr(commit_or_id, 'op', None) and
288 if (getattr(commit_or_id, 'op', None) and
289 getattr(commit_or_id, 'ref_name', None)):
289 getattr(commit_or_id, 'ref_name', None)):
290 lazy_cs = False
290 lazy_cs = False
291 lbl = '?'
291 lbl = '?'
292 if commit_or_id.op == 'delete_branch':
292 if commit_or_id.op == 'delete_branch':
293 lbl = '%s' % _('Deleted branch: %s') % commit_or_id.ref_name
293 lbl = '%s' % _('Deleted branch: %s') % commit_or_id.ref_name
294 title = ''
294 title = ''
295 elif commit_or_id.op == 'tag':
295 elif commit_or_id.op == 'tag':
296 lbl = '%s' % _('Created tag: %s') % commit_or_id.ref_name
296 lbl = '%s' % _('Created tag: %s') % commit_or_id.ref_name
297 title = ''
297 title = ''
298 _url = '#'
298 _url = '#'
299
299
300 else:
300 else:
301 lbl = '%s' % (commit_or_id.short_id[:8])
301 lbl = '%s' % (commit_or_id.short_id[:8])
302 _url = h.route_path('repo_commit', repo_name=repo_name,
302 _url = h.route_path('repo_commit', repo_name=repo_name,
303 commit_id=commit_or_id.raw_id)
303 commit_id=commit_or_id.raw_id)
304 title = tooltip(commit_or_id.message)
304 title = tooltip(commit_or_id.message)
305 else:
305 else:
306 # commit cannot be found/striped/removed etc.
306 # commit cannot be found/striped/removed etc.
307 lbl = ('%s' % commit_or_id)[:12]
307 lbl = ('%s' % commit_or_id)[:12]
308 _url = '#'
308 _url = '#'
309 title = _('Commit not found')
309 title = _('Commit not found')
310 if self.parse_commits:
310 if self.parse_commits:
311 return link_to(lbl, _url, title=title, class_='tooltip')
311 return link_to(lbl, _url, title=title, class_='tooltip')
312 return link_to(lbl, _url, raw_id=commit_or_id.raw_id, repo_name=repo_name,
312 return link_to(lbl, _url, raw_id=commit_or_id.raw_id, repo_name=repo_name,
313 class_='lazy-cs' if lazy_cs else '')
313 class_='lazy-cs' if lazy_cs else '')
314
314
315 def is_deleted(self):
315 def is_deleted(self):
316 return self.user_log.repository is None
316 return self.user_log.repository is None
317
317
318
318
319 class AuditLogParser(object):
319 class AuditLogParser(object):
320 def __init__(self, request, audit_log_entry):
320 def __init__(self, request, audit_log_entry):
321 self.audit_log_entry = audit_log_entry
321 self.audit_log_entry = audit_log_entry
322 self.request = request
322 self.request = request
323
323
324 def get_icon(self, action):
324 def get_icon(self, action):
325 return 'icon-rhodecode'
325 return 'icon-rhodecode'
326
326
327 def callbacks(self):
327 def callbacks(self):
328 action_str = self.audit_log_entry.action
328 action_str = self.audit_log_entry.action
329
329
330 def callback():
330 def callback():
331 # returned callbacks we need to call to get
331 # returned callbacks we need to call to get
332 action = action_str \
332 action = action_str \
333 .replace('[', '<span class="journal_highlight">')\
333 .replace('[', '<span class="journal_highlight">')\
334 .replace(']', '</span>')
334 .replace(']', '</span>')
335 return literal(action)
335 return literal(action)
336
336
337 def icon():
337 def icon():
338 tmpl = """<i class="%s" alt="%s"></i>"""
338 tmpl = """<i class="%s" alt="%s"></i>"""
339 ico = self.get_icon(action_str)
339 ico = self.get_icon(action_str)
340 return literal(tmpl % (ico, action_str))
340 return literal(tmpl % (ico, action_str))
341
341
342 action_params_func = _no_params_func
342 action_params_func = _no_params_func
343
343
344 return [
344 return [
345 callback, action_params_func, icon]
345 callback, action_params_func, icon]
346
346
347
347
348 def _no_params_func():
348 def _no_params_func():
349 return ""
349 return ""
350
350
351
351
352 def _get_op(commit_id):
352 def _get_op(commit_id):
353 _op = None
353 _op = None
354 _name = commit_id
354 _name = commit_id
355 if len(commit_id.split('=>')) == 2:
355 if len(commit_id.split('=>')) == 2:
356 _op, _name = commit_id.split('=>')
356 _op, _name = commit_id.split('=>')
357 return _op, _name
357 return _op, _name
General Comments 0
You need to be logged in to leave comments. Login now