##// END OF EJS Templates
goto-switcher: reduce query data to only required attributes for speedups.
marcink -
r4152:beb1dad7 default
parent child Browse files
Show More
@@ -1,822 +1,830 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2016-2019 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 import re
22 22 import logging
23 23 import collections
24 24
25 25 from pyramid.httpexceptions import HTTPNotFound
26 26 from pyramid.view import view_config
27 27
28 28 from rhodecode.apps._base import BaseAppView, DataGridAppView
29 29 from rhodecode.lib import helpers as h
30 30 from rhodecode.lib.auth import (
31 31 LoginRequired, NotAnonymous, HasRepoGroupPermissionAnyDecorator, CSRFRequired,
32 32 HasRepoGroupPermissionAny, AuthUser)
33 33 from rhodecode.lib.codeblocks import filenode_as_lines_tokens
34 34 from rhodecode.lib.index import searcher_from_config
35 35 from rhodecode.lib.utils2 import safe_unicode, str2bool, safe_int
36 36 from rhodecode.lib.vcs.nodes import FileNode
37 37 from rhodecode.model.db import (
38 38 func, true, or_, case, in_filter_generator, Session,
39 39 Repository, RepoGroup, User, UserGroup)
40 40 from rhodecode.model.repo import RepoModel
41 41 from rhodecode.model.repo_group import RepoGroupModel
42 42 from rhodecode.model.user import UserModel
43 43 from rhodecode.model.user_group import UserGroupModel
44 44
45 45 log = logging.getLogger(__name__)
46 46
47 47
48 48 class HomeView(BaseAppView, DataGridAppView):
49 49
50 50 def load_default_context(self):
51 51 c = self._get_local_tmpl_context()
52 52 c.user = c.auth_user.get_instance()
53 53
54 54 return c
55 55
56 56 @LoginRequired()
57 57 @view_config(
58 58 route_name='user_autocomplete_data', request_method='GET',
59 59 renderer='json_ext', xhr=True)
60 60 def user_autocomplete_data(self):
61 61 self.load_default_context()
62 62 query = self.request.GET.get('query')
63 63 active = str2bool(self.request.GET.get('active') or True)
64 64 include_groups = str2bool(self.request.GET.get('user_groups'))
65 65 expand_groups = str2bool(self.request.GET.get('user_groups_expand'))
66 66 skip_default_user = str2bool(self.request.GET.get('skip_default_user'))
67 67
68 68 log.debug('generating user list, query:%s, active:%s, with_groups:%s',
69 69 query, active, include_groups)
70 70
71 71 _users = UserModel().get_users(
72 72 name_contains=query, only_active=active)
73 73
74 74 def maybe_skip_default_user(usr):
75 75 if skip_default_user and usr['username'] == UserModel.cls.DEFAULT_USER:
76 76 return False
77 77 return True
78 78 _users = filter(maybe_skip_default_user, _users)
79 79
80 80 if include_groups:
81 81 # extend with user groups
82 82 _user_groups = UserGroupModel().get_user_groups(
83 83 name_contains=query, only_active=active,
84 84 expand_groups=expand_groups)
85 85 _users = _users + _user_groups
86 86
87 87 return {'suggestions': _users}
88 88
89 89 @LoginRequired()
90 90 @NotAnonymous()
91 91 @view_config(
92 92 route_name='user_group_autocomplete_data', request_method='GET',
93 93 renderer='json_ext', xhr=True)
94 94 def user_group_autocomplete_data(self):
95 95 self.load_default_context()
96 96 query = self.request.GET.get('query')
97 97 active = str2bool(self.request.GET.get('active') or True)
98 98 expand_groups = str2bool(self.request.GET.get('user_groups_expand'))
99 99
100 100 log.debug('generating user group list, query:%s, active:%s',
101 101 query, active)
102 102
103 103 _user_groups = UserGroupModel().get_user_groups(
104 104 name_contains=query, only_active=active,
105 105 expand_groups=expand_groups)
106 106 _user_groups = _user_groups
107 107
108 108 return {'suggestions': _user_groups}
109 109
110 110 def _get_repo_list(self, name_contains=None, repo_type=None, repo_group_name='', limit=20):
111 111 org_query = name_contains
112 112 allowed_ids = self._rhodecode_user.repo_acl_ids(
113 113 ['repository.read', 'repository.write', 'repository.admin'],
114 114 cache=False, name_filter=name_contains) or [-1]
115 115
116 query = Repository.query()\
116 query = Session().query(
117 Repository.repo_name,
118 Repository.repo_id,
119 Repository.repo_type,
120 Repository.private,
121 )\
117 122 .filter(Repository.archived.isnot(true()))\
118 123 .filter(or_(
119 124 # generate multiple IN to fix limitation problems
120 125 *in_filter_generator(Repository.repo_id, allowed_ids)
121 126 ))
122 127
123 128 query = query.order_by(case(
124 129 [
125 130 (Repository.repo_name.startswith(repo_group_name), repo_group_name+'/'),
126 131 ],
127 132 ))
128 133 query = query.order_by(func.length(Repository.repo_name))
129 134 query = query.order_by(Repository.repo_name)
130 135
131 136 if repo_type:
132 137 query = query.filter(Repository.repo_type == repo_type)
133 138
134 139 if name_contains:
135 140 ilike_expression = u'%{}%'.format(safe_unicode(name_contains))
136 141 query = query.filter(
137 142 Repository.repo_name.ilike(ilike_expression))
138 143 query = query.limit(limit)
139 144
140 145 acl_iter = query
141 146
142 147 return [
143 148 {
144 149 'id': obj.repo_name,
145 150 'value': org_query,
146 151 'value_display': obj.repo_name,
147 152 'text': obj.repo_name,
148 153 'type': 'repo',
149 154 'repo_id': obj.repo_id,
150 155 'repo_type': obj.repo_type,
151 156 'private': obj.private,
152 157 'url': h.route_path('repo_summary', repo_name=obj.repo_name)
153 158 }
154 159 for obj in acl_iter]
155 160
156 161 def _get_repo_group_list(self, name_contains=None, repo_group_name='', limit=20):
157 162 org_query = name_contains
158 163 allowed_ids = self._rhodecode_user.repo_group_acl_ids(
159 164 ['group.read', 'group.write', 'group.admin'],
160 165 cache=False, name_filter=name_contains) or [-1]
161 166
162 query = RepoGroup.query()\
167 query = Session().query(
168 RepoGroup.group_id,
169 RepoGroup.group_name,
170 )\
163 171 .filter(or_(
164 172 # generate multiple IN to fix limitation problems
165 173 *in_filter_generator(RepoGroup.group_id, allowed_ids)
166 174 ))
167 175
168 176 query = query.order_by(case(
169 177 [
170 178 (RepoGroup.group_name.startswith(repo_group_name), repo_group_name+'/'),
171 179 ],
172 180 ))
173 181 query = query.order_by(func.length(RepoGroup.group_name))
174 182 query = query.order_by(RepoGroup.group_name)
175 183
176 184 if name_contains:
177 185 ilike_expression = u'%{}%'.format(safe_unicode(name_contains))
178 186 query = query.filter(
179 187 RepoGroup.group_name.ilike(ilike_expression))
180 188 query = query.limit(limit)
181 189
182 190 acl_iter = query
183 191
184 192 return [
185 193 {
186 194 'id': obj.group_name,
187 195 'value': org_query,
188 196 'value_display': obj.group_name,
189 197 'text': obj.group_name,
190 198 'type': 'repo_group',
191 199 'repo_group_id': obj.group_id,
192 200 'url': h.route_path(
193 201 'repo_group_home', repo_group_name=obj.group_name)
194 202 }
195 203 for obj in acl_iter]
196 204
197 205 def _get_user_list(self, name_contains=None, limit=20):
198 206 org_query = name_contains
199 207 if not name_contains:
200 208 return [], False
201 209
202 210 # TODO(marcink): should all logged in users be allowed to search others?
203 211 allowed_user_search = self._rhodecode_user.username != User.DEFAULT_USER
204 212 if not allowed_user_search:
205 213 return [], False
206 214
207 215 name_contains = re.compile('(?:user:[ ]?)(.+)').findall(name_contains)
208 216 if len(name_contains) != 1:
209 217 return [], False
210 218
211 219 name_contains = name_contains[0]
212 220
213 221 query = User.query()\
214 222 .order_by(func.length(User.username))\
215 223 .order_by(User.username) \
216 224 .filter(User.username != User.DEFAULT_USER)
217 225
218 226 if name_contains:
219 227 ilike_expression = u'%{}%'.format(safe_unicode(name_contains))
220 228 query = query.filter(
221 229 User.username.ilike(ilike_expression))
222 230 query = query.limit(limit)
223 231
224 232 acl_iter = query
225 233
226 234 return [
227 235 {
228 236 'id': obj.user_id,
229 237 'value': org_query,
230 238 'value_display': 'user: `{}`'.format(obj.username),
231 239 'type': 'user',
232 240 'icon_link': h.gravatar_url(obj.email, 30),
233 241 'url': h.route_path(
234 242 'user_profile', username=obj.username)
235 243 }
236 244 for obj in acl_iter], True
237 245
238 246 def _get_user_groups_list(self, name_contains=None, limit=20):
239 247 org_query = name_contains
240 248 if not name_contains:
241 249 return [], False
242 250
243 251 # TODO(marcink): should all logged in users be allowed to search others?
244 252 allowed_user_search = self._rhodecode_user.username != User.DEFAULT_USER
245 253 if not allowed_user_search:
246 254 return [], False
247 255
248 256 name_contains = re.compile('(?:user_group:[ ]?)(.+)').findall(name_contains)
249 257 if len(name_contains) != 1:
250 258 return [], False
251 259
252 260 name_contains = name_contains[0]
253 261
254 262 query = UserGroup.query()\
255 263 .order_by(func.length(UserGroup.users_group_name))\
256 264 .order_by(UserGroup.users_group_name)
257 265
258 266 if name_contains:
259 267 ilike_expression = u'%{}%'.format(safe_unicode(name_contains))
260 268 query = query.filter(
261 269 UserGroup.users_group_name.ilike(ilike_expression))
262 270 query = query.limit(limit)
263 271
264 272 acl_iter = query
265 273
266 274 return [
267 275 {
268 276 'id': obj.users_group_id,
269 277 'value': org_query,
270 278 'value_display': 'user_group: `{}`'.format(obj.users_group_name),
271 279 'type': 'user_group',
272 280 'url': h.route_path(
273 281 'user_group_profile', user_group_name=obj.users_group_name)
274 282 }
275 283 for obj in acl_iter], True
276 284
277 285 def _get_hash_commit_list(self, auth_user, searcher, query, repo=None, repo_group=None):
278 286 repo_name = repo_group_name = None
279 287 if repo:
280 288 repo_name = repo.repo_name
281 289 if repo_group:
282 290 repo_group_name = repo_group.group_name
283 291
284 292 org_query = query
285 293 if not query or len(query) < 3 or not searcher:
286 294 return [], False
287 295
288 296 commit_hashes = re.compile('(?:commit:[ ]?)([0-9a-f]{2,40})').findall(query)
289 297
290 298 if len(commit_hashes) != 1:
291 299 return [], False
292 300
293 301 commit_hash = commit_hashes[0]
294 302
295 303 result = searcher.search(
296 304 'commit_id:{}*'.format(commit_hash), 'commit', auth_user,
297 305 repo_name, repo_group_name, raise_on_exc=False)
298 306
299 307 commits = []
300 308 for entry in result['results']:
301 309 repo_data = {
302 310 'repository_id': entry.get('repository_id'),
303 311 'repository_type': entry.get('repo_type'),
304 312 'repository_name': entry.get('repository'),
305 313 }
306 314
307 315 commit_entry = {
308 316 'id': entry['commit_id'],
309 317 'value': org_query,
310 318 'value_display': '`{}` commit: {}'.format(
311 319 entry['repository'], entry['commit_id']),
312 320 'type': 'commit',
313 321 'repo': entry['repository'],
314 322 'repo_data': repo_data,
315 323
316 324 'url': h.route_path(
317 325 'repo_commit',
318 326 repo_name=entry['repository'], commit_id=entry['commit_id'])
319 327 }
320 328
321 329 commits.append(commit_entry)
322 330 return commits, True
323 331
324 332 def _get_path_list(self, auth_user, searcher, query, repo=None, repo_group=None):
325 333 repo_name = repo_group_name = None
326 334 if repo:
327 335 repo_name = repo.repo_name
328 336 if repo_group:
329 337 repo_group_name = repo_group.group_name
330 338
331 339 org_query = query
332 340 if not query or len(query) < 3 or not searcher:
333 341 return [], False
334 342
335 343 paths_re = re.compile('(?:file:[ ]?)(.+)').findall(query)
336 344 if len(paths_re) != 1:
337 345 return [], False
338 346
339 347 file_path = paths_re[0]
340 348
341 349 search_path = searcher.escape_specials(file_path)
342 350 result = searcher.search(
343 351 'file.raw:*{}*'.format(search_path), 'path', auth_user,
344 352 repo_name, repo_group_name, raise_on_exc=False)
345 353
346 354 files = []
347 355 for entry in result['results']:
348 356 repo_data = {
349 357 'repository_id': entry.get('repository_id'),
350 358 'repository_type': entry.get('repo_type'),
351 359 'repository_name': entry.get('repository'),
352 360 }
353 361
354 362 file_entry = {
355 363 'id': entry['commit_id'],
356 364 'value': org_query,
357 365 'value_display': '`{}` file: {}'.format(
358 366 entry['repository'], entry['file']),
359 367 'type': 'file',
360 368 'repo': entry['repository'],
361 369 'repo_data': repo_data,
362 370
363 371 'url': h.route_path(
364 372 'repo_files',
365 373 repo_name=entry['repository'], commit_id=entry['commit_id'],
366 374 f_path=entry['file'])
367 375 }
368 376
369 377 files.append(file_entry)
370 378 return files, True
371 379
372 380 @LoginRequired()
373 381 @view_config(
374 382 route_name='repo_list_data', request_method='GET',
375 383 renderer='json_ext', xhr=True)
376 384 def repo_list_data(self):
377 385 _ = self.request.translate
378 386 self.load_default_context()
379 387
380 388 query = self.request.GET.get('query')
381 389 repo_type = self.request.GET.get('repo_type')
382 390 log.debug('generating repo list, query:%s, repo_type:%s',
383 391 query, repo_type)
384 392
385 393 res = []
386 394 repos = self._get_repo_list(query, repo_type=repo_type)
387 395 if repos:
388 396 res.append({
389 397 'text': _('Repositories'),
390 398 'children': repos
391 399 })
392 400
393 401 data = {
394 402 'more': False,
395 403 'results': res
396 404 }
397 405 return data
398 406
399 407 @LoginRequired()
400 408 @view_config(
401 409 route_name='repo_group_list_data', request_method='GET',
402 410 renderer='json_ext', xhr=True)
403 411 def repo_group_list_data(self):
404 412 _ = self.request.translate
405 413 self.load_default_context()
406 414
407 415 query = self.request.GET.get('query')
408 416
409 417 log.debug('generating repo group list, query:%s',
410 418 query)
411 419
412 420 res = []
413 421 repo_groups = self._get_repo_group_list(query)
414 422 if repo_groups:
415 423 res.append({
416 424 'text': _('Repository Groups'),
417 425 'children': repo_groups
418 426 })
419 427
420 428 data = {
421 429 'more': False,
422 430 'results': res
423 431 }
424 432 return data
425 433
426 434 def _get_default_search_queries(self, search_context, searcher, query):
427 435 if not searcher:
428 436 return []
429 437
430 438 is_es_6 = searcher.is_es_6
431 439
432 440 queries = []
433 441 repo_group_name, repo_name, repo_context = None, None, None
434 442
435 443 # repo group context
436 444 if search_context.get('search_context[repo_group_name]'):
437 445 repo_group_name = search_context.get('search_context[repo_group_name]')
438 446 if search_context.get('search_context[repo_name]'):
439 447 repo_name = search_context.get('search_context[repo_name]')
440 448 repo_context = search_context.get('search_context[repo_view_type]')
441 449
442 450 if is_es_6 and repo_name:
443 451 # files
444 452 def query_modifier():
445 453 qry = query
446 454 return {'q': qry, 'type': 'content'}
447 455
448 456 label = u'File search for `{}`'.format(h.escape(query))
449 457 file_qry = {
450 458 'id': -10,
451 459 'value': query,
452 460 'value_display': label,
453 461 'value_icon': '<i class="icon-code"></i>',
454 462 'type': 'search',
455 463 'subtype': 'repo',
456 464 'url': h.route_path('search_repo',
457 465 repo_name=repo_name,
458 466 _query=query_modifier())
459 467 }
460 468
461 469 # commits
462 470 def query_modifier():
463 471 qry = query
464 472 return {'q': qry, 'type': 'commit'}
465 473
466 474 label = u'Commit search for `{}`'.format(h.escape(query))
467 475 commit_qry = {
468 476 'id': -20,
469 477 'value': query,
470 478 'value_display': label,
471 479 'value_icon': '<i class="icon-history"></i>',
472 480 'type': 'search',
473 481 'subtype': 'repo',
474 482 'url': h.route_path('search_repo',
475 483 repo_name=repo_name,
476 484 _query=query_modifier())
477 485 }
478 486
479 487 if repo_context in ['commit', 'commits']:
480 488 queries.extend([commit_qry, file_qry])
481 489 elif repo_context in ['files', 'summary']:
482 490 queries.extend([file_qry, commit_qry])
483 491 else:
484 492 queries.extend([commit_qry, file_qry])
485 493
486 494 elif is_es_6 and repo_group_name:
487 495 # files
488 496 def query_modifier():
489 497 qry = query
490 498 return {'q': qry, 'type': 'content'}
491 499
492 500 label = u'File search for `{}`'.format(query)
493 501 file_qry = {
494 502 'id': -30,
495 503 'value': query,
496 504 'value_display': label,
497 505 'value_icon': '<i class="icon-code"></i>',
498 506 'type': 'search',
499 507 'subtype': 'repo_group',
500 508 'url': h.route_path('search_repo_group',
501 509 repo_group_name=repo_group_name,
502 510 _query=query_modifier())
503 511 }
504 512
505 513 # commits
506 514 def query_modifier():
507 515 qry = query
508 516 return {'q': qry, 'type': 'commit'}
509 517
510 518 label = u'Commit search for `{}`'.format(query)
511 519 commit_qry = {
512 520 'id': -40,
513 521 'value': query,
514 522 'value_display': label,
515 523 'value_icon': '<i class="icon-history"></i>',
516 524 'type': 'search',
517 525 'subtype': 'repo_group',
518 526 'url': h.route_path('search_repo_group',
519 527 repo_group_name=repo_group_name,
520 528 _query=query_modifier())
521 529 }
522 530
523 531 if repo_context in ['commit', 'commits']:
524 532 queries.extend([commit_qry, file_qry])
525 533 elif repo_context in ['files', 'summary']:
526 534 queries.extend([file_qry, commit_qry])
527 535 else:
528 536 queries.extend([commit_qry, file_qry])
529 537
530 538 # Global, not scoped
531 539 if not queries:
532 540 queries.append(
533 541 {
534 542 'id': -1,
535 543 'value': query,
536 544 'value_display': u'File search for: `{}`'.format(query),
537 545 'value_icon': '<i class="icon-code"></i>',
538 546 'type': 'search',
539 547 'subtype': 'global',
540 548 'url': h.route_path('search',
541 549 _query={'q': query, 'type': 'content'})
542 550 })
543 551 queries.append(
544 552 {
545 553 'id': -2,
546 554 'value': query,
547 555 'value_display': u'Commit search for: `{}`'.format(query),
548 556 'value_icon': '<i class="icon-history"></i>',
549 557 'type': 'search',
550 558 'subtype': 'global',
551 559 'url': h.route_path('search',
552 560 _query={'q': query, 'type': 'commit'})
553 561 })
554 562
555 563 return queries
556 564
557 565 @LoginRequired()
558 566 @view_config(
559 567 route_name='goto_switcher_data', request_method='GET',
560 568 renderer='json_ext', xhr=True)
561 569 def goto_switcher_data(self):
562 570 c = self.load_default_context()
563 571
564 572 _ = self.request.translate
565 573
566 574 query = self.request.GET.get('query')
567 575 log.debug('generating main filter data, query %s', query)
568 576
569 577 res = []
570 578 if not query:
571 579 return {'suggestions': res}
572 580
573 581 def no_match(name):
574 582 return {
575 583 'id': -1,
576 584 'value': "",
577 585 'value_display': name,
578 586 'type': 'text',
579 587 'url': ""
580 588 }
581 589 searcher = searcher_from_config(self.request.registry.settings)
582 590 has_specialized_search = False
583 591
584 592 # set repo context
585 593 repo = None
586 594 repo_id = safe_int(self.request.GET.get('search_context[repo_id]'))
587 595 if repo_id:
588 596 repo = Repository.get(repo_id)
589 597
590 598 # set group context
591 599 repo_group = None
592 600 repo_group_id = safe_int(self.request.GET.get('search_context[repo_group_id]'))
593 601 if repo_group_id:
594 602 repo_group = RepoGroup.get(repo_group_id)
595 603 prefix_match = False
596 604
597 605 # user: type search
598 606 if not prefix_match:
599 607 users, prefix_match = self._get_user_list(query)
600 608 if users:
601 609 has_specialized_search = True
602 610 for serialized_user in users:
603 611 res.append(serialized_user)
604 612 elif prefix_match:
605 613 has_specialized_search = True
606 614 res.append(no_match('No matching users found'))
607 615
608 616 # user_group: type search
609 617 if not prefix_match:
610 618 user_groups, prefix_match = self._get_user_groups_list(query)
611 619 if user_groups:
612 620 has_specialized_search = True
613 621 for serialized_user_group in user_groups:
614 622 res.append(serialized_user_group)
615 623 elif prefix_match:
616 624 has_specialized_search = True
617 625 res.append(no_match('No matching user groups found'))
618 626
619 627 # FTS commit: type search
620 628 if not prefix_match:
621 629 commits, prefix_match = self._get_hash_commit_list(
622 630 c.auth_user, searcher, query, repo, repo_group)
623 631 if commits:
624 632 has_specialized_search = True
625 633 unique_repos = collections.OrderedDict()
626 634 for commit in commits:
627 635 repo_name = commit['repo']
628 636 unique_repos.setdefault(repo_name, []).append(commit)
629 637
630 638 for _repo, commits in unique_repos.items():
631 639 for commit in commits:
632 640 res.append(commit)
633 641 elif prefix_match:
634 642 has_specialized_search = True
635 643 res.append(no_match('No matching commits found'))
636 644
637 645 # FTS file: type search
638 646 if not prefix_match:
639 647 paths, prefix_match = self._get_path_list(
640 648 c.auth_user, searcher, query, repo, repo_group)
641 649 if paths:
642 650 has_specialized_search = True
643 651 unique_repos = collections.OrderedDict()
644 652 for path in paths:
645 653 repo_name = path['repo']
646 654 unique_repos.setdefault(repo_name, []).append(path)
647 655
648 656 for repo, paths in unique_repos.items():
649 657 for path in paths:
650 658 res.append(path)
651 659 elif prefix_match:
652 660 has_specialized_search = True
653 661 res.append(no_match('No matching files found'))
654 662
655 663 # main suggestions
656 664 if not has_specialized_search:
657 665 repo_group_name = ''
658 666 if repo_group:
659 667 repo_group_name = repo_group.group_name
660 668
661 669 for _q in self._get_default_search_queries(self.request.GET, searcher, query):
662 670 res.append(_q)
663 671
664 672 repo_groups = self._get_repo_group_list(query, repo_group_name=repo_group_name)
665 673 for serialized_repo_group in repo_groups:
666 674 res.append(serialized_repo_group)
667 675
668 676 repos = self._get_repo_list(query, repo_group_name=repo_group_name)
669 677 for serialized_repo in repos:
670 678 res.append(serialized_repo)
671 679
672 680 if not repos and not repo_groups:
673 681 res.append(no_match('No matches found'))
674 682
675 683 return {'suggestions': res}
676 684
677 685 @LoginRequired()
678 686 @view_config(
679 687 route_name='home', request_method='GET',
680 688 renderer='rhodecode:templates/index.mako')
681 689 def main_page(self):
682 690 c = self.load_default_context()
683 691 c.repo_group = None
684 692 return self._get_template_context(c)
685 693
686 694 def _main_page_repo_groups_data(self, repo_group_id):
687 695 column_map = {
688 696 'name': 'group_name_hash',
689 697 'desc': 'group_description',
690 698 'last_change': 'updated_on',
691 699 'owner': 'user_username',
692 700 }
693 701 draw, start, limit = self._extract_chunk(self.request)
694 702 search_q, order_by, order_dir = self._extract_ordering(
695 703 self.request, column_map=column_map)
696 704 return RepoGroupModel().get_repo_groups_data_table(
697 705 draw, start, limit,
698 706 search_q, order_by, order_dir,
699 707 self._rhodecode_user, repo_group_id)
700 708
701 709 def _main_page_repos_data(self, repo_group_id):
702 710 column_map = {
703 711 'name': 'repo_name',
704 712 'desc': 'description',
705 713 'last_change': 'updated_on',
706 714 'owner': 'user_username',
707 715 }
708 716 draw, start, limit = self._extract_chunk(self.request)
709 717 search_q, order_by, order_dir = self._extract_ordering(
710 718 self.request, column_map=column_map)
711 719 return RepoModel().get_repos_data_table(
712 720 draw, start, limit,
713 721 search_q, order_by, order_dir,
714 722 self._rhodecode_user, repo_group_id)
715 723
716 724 @LoginRequired()
717 725 @view_config(
718 726 route_name='main_page_repo_groups_data',
719 727 request_method='GET', renderer='json_ext', xhr=True)
720 728 def main_page_repo_groups_data(self):
721 729 self.load_default_context()
722 730 repo_group_id = safe_int(self.request.GET.get('repo_group_id'))
723 731
724 732 if repo_group_id:
725 733 group = RepoGroup.get_or_404(repo_group_id)
726 734 _perms = AuthUser.repo_group_read_perms
727 735 if not HasRepoGroupPermissionAny(*_perms)(
728 736 group.group_name, 'user is allowed to list repo group children'):
729 737 raise HTTPNotFound()
730 738
731 739 return self._main_page_repo_groups_data(repo_group_id)
732 740
733 741 @LoginRequired()
734 742 @view_config(
735 743 route_name='main_page_repos_data',
736 744 request_method='GET', renderer='json_ext', xhr=True)
737 745 def main_page_repos_data(self):
738 746 self.load_default_context()
739 747 repo_group_id = safe_int(self.request.GET.get('repo_group_id'))
740 748
741 749 if repo_group_id:
742 750 group = RepoGroup.get_or_404(repo_group_id)
743 751 _perms = AuthUser.repo_group_read_perms
744 752 if not HasRepoGroupPermissionAny(*_perms)(
745 753 group.group_name, 'user is allowed to list repo group children'):
746 754 raise HTTPNotFound()
747 755
748 756 return self._main_page_repos_data(repo_group_id)
749 757
750 758 @LoginRequired()
751 759 @HasRepoGroupPermissionAnyDecorator(*AuthUser.repo_group_read_perms)
752 760 @view_config(
753 761 route_name='repo_group_home', request_method='GET',
754 762 renderer='rhodecode:templates/index_repo_group.mako')
755 763 @view_config(
756 764 route_name='repo_group_home_slash', request_method='GET',
757 765 renderer='rhodecode:templates/index_repo_group.mako')
758 766 def repo_group_main_page(self):
759 767 c = self.load_default_context()
760 768 c.repo_group = self.request.db_repo_group
761 769 return self._get_template_context(c)
762 770
763 771 @LoginRequired()
764 772 @CSRFRequired()
765 773 @view_config(
766 774 route_name='markup_preview', request_method='POST',
767 775 renderer='string', xhr=True)
768 776 def markup_preview(self):
769 777 # Technically a CSRF token is not needed as no state changes with this
770 778 # call. However, as this is a POST is better to have it, so automated
771 779 # tools don't flag it as potential CSRF.
772 780 # Post is required because the payload could be bigger than the maximum
773 781 # allowed by GET.
774 782
775 783 text = self.request.POST.get('text')
776 784 renderer = self.request.POST.get('renderer') or 'rst'
777 785 if text:
778 786 return h.render(text, renderer=renderer, mentions=True)
779 787 return ''
780 788
781 789 @LoginRequired()
782 790 @CSRFRequired()
783 791 @view_config(
784 792 route_name='file_preview', request_method='POST',
785 793 renderer='string', xhr=True)
786 794 def file_preview(self):
787 795 # Technically a CSRF token is not needed as no state changes with this
788 796 # call. However, as this is a POST is better to have it, so automated
789 797 # tools don't flag it as potential CSRF.
790 798 # Post is required because the payload could be bigger than the maximum
791 799 # allowed by GET.
792 800
793 801 text = self.request.POST.get('text')
794 802 file_path = self.request.POST.get('file_path')
795 803
796 804 renderer = h.renderer_from_filename(file_path)
797 805
798 806 if renderer:
799 807 return h.render(text, renderer=renderer, mentions=True)
800 808 else:
801 809 self.load_default_context()
802 810 _render = self.request.get_partial_renderer(
803 811 'rhodecode:templates/files/file_content.mako')
804 812
805 813 lines = filenode_as_lines_tokens(FileNode(file_path, text))
806 814
807 815 return _render('render_lines', lines)
808 816
809 817 @LoginRequired()
810 818 @CSRFRequired()
811 819 @view_config(
812 820 route_name='store_user_session_value', request_method='POST',
813 821 renderer='string', xhr=True)
814 822 def store_user_session_attr(self):
815 823 key = self.request.POST.get('key')
816 824 val = self.request.POST.get('val')
817 825
818 826 existing_value = self.request.session.get(key)
819 827 if existing_value != val:
820 828 self.request.session[key] = val
821 829
822 830 return 'stored:{}:{}'.format(key, val)
General Comments 0
You need to be logged in to leave comments. Login now