##// END OF EJS Templates
search: repo search is a repo thing - show it that way in ui and url
Mads Kiilerich -
r3289:666fc6ac beta
parent child Browse files
Show More
@@ -1,635 +1,639
1 1 """
2 2 Routes configuration
3 3
4 4 The more specific and detailed routes should be defined first so they
5 5 may take precedent over the more generic routes. For more information
6 6 refer to the routes manual at http://routes.groovie.org/docs/
7 7 """
8 8 from __future__ import with_statement
9 9 from routes import Mapper
10 10
11 11 # prefix for non repository related links needs to be prefixed with `/`
12 12 ADMIN_PREFIX = '/_admin'
13 13
14 14
15 15 def make_map(config):
16 16 """Create, configure and return the routes Mapper"""
17 17 rmap = Mapper(directory=config['pylons.paths']['controllers'],
18 18 always_scan=config['debug'])
19 19 rmap.minimization = False
20 20 rmap.explicit = False
21 21
22 22 from rhodecode.lib.utils import is_valid_repo
23 23 from rhodecode.lib.utils import is_valid_repos_group
24 24
25 25 def check_repo(environ, match_dict):
26 26 """
27 27 check for valid repository for proper 404 handling
28 28
29 29 :param environ:
30 30 :param match_dict:
31 31 """
32 32 from rhodecode.model.db import Repository
33 33 repo_name = match_dict.get('repo_name')
34 34
35 35 if match_dict.get('f_path'):
36 36 #fix for multiple initial slashes that causes errors
37 37 match_dict['f_path'] = match_dict['f_path'].lstrip('/')
38 38
39 39 try:
40 40 by_id = repo_name.split('_')
41 41 if len(by_id) == 2 and by_id[1].isdigit() and by_id[0] == '':
42 42 repo_name = Repository.get(by_id[1]).repo_name
43 43 match_dict['repo_name'] = repo_name
44 44 except:
45 45 pass
46 46
47 47 return is_valid_repo(repo_name, config['base_path'])
48 48
49 49 def check_group(environ, match_dict):
50 50 """
51 51 check for valid repositories group for proper 404 handling
52 52
53 53 :param environ:
54 54 :param match_dict:
55 55 """
56 56 repos_group_name = match_dict.get('group_name')
57 57 return is_valid_repos_group(repos_group_name, config['base_path'])
58 58
59 59 def check_int(environ, match_dict):
60 60 return match_dict.get('id').isdigit()
61 61
62 62 # The ErrorController route (handles 404/500 error pages); it should
63 63 # likely stay at the top, ensuring it can always be resolved
64 64 rmap.connect('/error/{action}', controller='error')
65 65 rmap.connect('/error/{action}/{id}', controller='error')
66 66
67 67 #==========================================================================
68 68 # CUSTOM ROUTES HERE
69 69 #==========================================================================
70 70
71 71 #MAIN PAGE
72 72 rmap.connect('home', '/', controller='home', action='index')
73 73 rmap.connect('repo_switcher', '/repos', controller='home',
74 74 action='repo_switcher')
75 75 rmap.connect('branch_tag_switcher', '/branches-tags/{repo_name:.*?}',
76 76 controller='home', action='branch_tag_switcher')
77 77 rmap.connect('bugtracker',
78 78 "http://bitbucket.org/marcinkuzminski/rhodecode/issues",
79 79 _static=True)
80 80 rmap.connect('rst_help',
81 81 "http://docutils.sourceforge.net/docs/user/rst/quickref.html",
82 82 _static=True)
83 83 rmap.connect('rhodecode_official', "http://rhodecode.org", _static=True)
84 84
85 85 #ADMIN REPOSITORY REST ROUTES
86 86 with rmap.submapper(path_prefix=ADMIN_PREFIX,
87 87 controller='admin/repos') as m:
88 88 m.connect("repos", "/repos",
89 89 action="create", conditions=dict(method=["POST"]))
90 90 m.connect("repos", "/repos",
91 91 action="index", conditions=dict(method=["GET"]))
92 92 m.connect("formatted_repos", "/repos.{format}",
93 93 action="index",
94 94 conditions=dict(method=["GET"]))
95 95 m.connect("new_repo", "/repos/new",
96 96 action="new", conditions=dict(method=["GET"]))
97 97 m.connect("formatted_new_repo", "/repos/new.{format}",
98 98 action="new", conditions=dict(method=["GET"]))
99 99 m.connect("/repos/{repo_name:.*?}",
100 100 action="update", conditions=dict(method=["PUT"],
101 101 function=check_repo))
102 102 m.connect("/repos/{repo_name:.*?}",
103 103 action="delete", conditions=dict(method=["DELETE"],
104 104 function=check_repo))
105 105 # no longer used:
106 106 m.connect("edit_repo_admin", "/repos/{repo_name:.*?}/edit",
107 107 action="edit", conditions=dict(method=["GET"],
108 108 function=check_repo))
109 109 m.connect("formatted_edit_repo", "/repos/{repo_name:.*?}.{format}/edit",
110 110 action="edit", conditions=dict(method=["GET"],
111 111 function=check_repo))
112 112 m.connect("repo", "/repos/{repo_name:.*?}",
113 113 action="show", conditions=dict(method=["GET"],
114 114 function=check_repo))
115 115 m.connect("formatted_repo", "/repos/{repo_name:.*?}.{format}",
116 116 action="show", conditions=dict(method=["GET"],
117 117 function=check_repo))
118 118 #ajax delete repo perm user
119 119 m.connect('delete_repo_user', "/repos_delete_user/{repo_name:.*?}",
120 120 action="delete_perm_user",
121 121 conditions=dict(method=["DELETE"], function=check_repo))
122 122
123 123 #ajax delete repo perm users_group
124 124 m.connect('delete_repo_users_group',
125 125 "/repos_delete_users_group/{repo_name:.*?}",
126 126 action="delete_perm_users_group",
127 127 conditions=dict(method=["DELETE"], function=check_repo))
128 128
129 129 #settings actions
130 130 m.connect('repo_stats', "/repos_stats/{repo_name:.*?}",
131 131 action="repo_stats", conditions=dict(method=["DELETE"],
132 132 function=check_repo))
133 133 m.connect('repo_cache', "/repos_cache/{repo_name:.*?}",
134 134 action="repo_cache", conditions=dict(method=["DELETE"],
135 135 function=check_repo))
136 136 m.connect('repo_public_journal', "/repos_public_journal/{repo_name:.*?}",
137 137 action="repo_public_journal", conditions=dict(method=["PUT"],
138 138 function=check_repo))
139 139 m.connect('repo_pull', "/repo_pull/{repo_name:.*?}",
140 140 action="repo_pull", conditions=dict(method=["PUT"],
141 141 function=check_repo))
142 142 m.connect('repo_as_fork', "/repo_as_fork/{repo_name:.*?}",
143 143 action="repo_as_fork", conditions=dict(method=["PUT"],
144 144 function=check_repo))
145 145 m.connect('repo_locking', "/repo_locking/{repo_name:.*?}",
146 146 action="repo_locking", conditions=dict(method=["PUT"],
147 147 function=check_repo))
148 148
149 149 with rmap.submapper(path_prefix=ADMIN_PREFIX,
150 150 controller='admin/repos_groups') as m:
151 151 m.connect("repos_groups", "/repos_groups",
152 152 action="create", conditions=dict(method=["POST"]))
153 153 m.connect("repos_groups", "/repos_groups",
154 154 action="index", conditions=dict(method=["GET"]))
155 155 m.connect("formatted_repos_groups", "/repos_groups.{format}",
156 156 action="index", conditions=dict(method=["GET"]))
157 157 m.connect("new_repos_group", "/repos_groups/new",
158 158 action="new", conditions=dict(method=["GET"]))
159 159 m.connect("formatted_new_repos_group", "/repos_groups/new.{format}",
160 160 action="new", conditions=dict(method=["GET"]))
161 161 m.connect("update_repos_group", "/repos_groups/{group_name:.*?}",
162 162 action="update", conditions=dict(method=["PUT"],
163 163 function=check_group))
164 164 m.connect("delete_repos_group", "/repos_groups/{group_name:.*?}",
165 165 action="delete", conditions=dict(method=["DELETE"],
166 166 function=check_group))
167 167 m.connect("edit_repos_group", "/repos_groups/{group_name:.*?}/edit",
168 168 action="edit", conditions=dict(method=["GET"],))
169 169 m.connect("formatted_edit_repos_group",
170 170 "/repos_groups/{group_name:.*?}.{format}/edit",
171 171 action="edit", conditions=dict(method=["GET"],
172 172 function=check_group))
173 173 m.connect("repos_group", "/repos_groups/{group_name:.*?}",
174 174 action="show", conditions=dict(method=["GET"],
175 175 function=check_group))
176 176 m.connect("formatted_repos_group", "/repos_groups/{group_name:.*?}.{format}",
177 177 action="show", conditions=dict(method=["GET"],
178 178 function=check_group))
179 179 # ajax delete repos group perm user
180 180 m.connect('delete_repos_group_user_perm',
181 181 "/delete_repos_group_user_perm/{group_name:.*?}",
182 182 action="delete_repos_group_user_perm",
183 183 conditions=dict(method=["DELETE"], function=check_group))
184 184
185 185 # ajax delete repos group perm users_group
186 186 m.connect('delete_repos_group_users_group_perm',
187 187 "/delete_repos_group_users_group_perm/{group_name:.*?}",
188 188 action="delete_repos_group_users_group_perm",
189 189 conditions=dict(method=["DELETE"], function=check_group))
190 190
191 191 #ADMIN USER REST ROUTES
192 192 with rmap.submapper(path_prefix=ADMIN_PREFIX,
193 193 controller='admin/users') as m:
194 194 m.connect("users", "/users",
195 195 action="create", conditions=dict(method=["POST"]))
196 196 m.connect("users", "/users",
197 197 action="index", conditions=dict(method=["GET"]))
198 198 m.connect("formatted_users", "/users.{format}",
199 199 action="index", conditions=dict(method=["GET"]))
200 200 m.connect("new_user", "/users/new",
201 201 action="new", conditions=dict(method=["GET"]))
202 202 m.connect("formatted_new_user", "/users/new.{format}",
203 203 action="new", conditions=dict(method=["GET"]))
204 204 m.connect("update_user", "/users/{id}",
205 205 action="update", conditions=dict(method=["PUT"]))
206 206 m.connect("delete_user", "/users/{id}",
207 207 action="delete", conditions=dict(method=["DELETE"]))
208 208 m.connect("edit_user", "/users/{id}/edit",
209 209 action="edit", conditions=dict(method=["GET"]))
210 210 m.connect("formatted_edit_user",
211 211 "/users/{id}.{format}/edit",
212 212 action="edit", conditions=dict(method=["GET"]))
213 213 m.connect("user", "/users/{id}",
214 214 action="show", conditions=dict(method=["GET"]))
215 215 m.connect("formatted_user", "/users/{id}.{format}",
216 216 action="show", conditions=dict(method=["GET"]))
217 217
218 218 #EXTRAS USER ROUTES
219 219 m.connect("user_perm", "/users_perm/{id}",
220 220 action="update_perm", conditions=dict(method=["PUT"]))
221 221 m.connect("user_emails", "/users_emails/{id}",
222 222 action="add_email", conditions=dict(method=["PUT"]))
223 223 m.connect("user_emails_delete", "/users_emails/{id}",
224 224 action="delete_email", conditions=dict(method=["DELETE"]))
225 225 m.connect("user_ips", "/users_ips/{id}",
226 226 action="add_ip", conditions=dict(method=["PUT"]))
227 227 m.connect("user_ips_delete", "/users_ips/{id}",
228 228 action="delete_ip", conditions=dict(method=["DELETE"]))
229 229
230 230 #ADMIN USERS GROUPS REST ROUTES
231 231 with rmap.submapper(path_prefix=ADMIN_PREFIX,
232 232 controller='admin/users_groups') as m:
233 233 m.connect("users_groups", "/users_groups",
234 234 action="create", conditions=dict(method=["POST"]))
235 235 m.connect("users_groups", "/users_groups",
236 236 action="index", conditions=dict(method=["GET"]))
237 237 m.connect("formatted_users_groups", "/users_groups.{format}",
238 238 action="index", conditions=dict(method=["GET"]))
239 239 m.connect("new_users_group", "/users_groups/new",
240 240 action="new", conditions=dict(method=["GET"]))
241 241 m.connect("formatted_new_users_group", "/users_groups/new.{format}",
242 242 action="new", conditions=dict(method=["GET"]))
243 243 m.connect("update_users_group", "/users_groups/{id}",
244 244 action="update", conditions=dict(method=["PUT"]))
245 245 m.connect("delete_users_group", "/users_groups/{id}",
246 246 action="delete", conditions=dict(method=["DELETE"]))
247 247 m.connect("edit_users_group", "/users_groups/{id}/edit",
248 248 action="edit", conditions=dict(method=["GET"]))
249 249 m.connect("formatted_edit_users_group",
250 250 "/users_groups/{id}.{format}/edit",
251 251 action="edit", conditions=dict(method=["GET"]))
252 252 m.connect("users_group", "/users_groups/{id}",
253 253 action="show", conditions=dict(method=["GET"]))
254 254 m.connect("formatted_users_group", "/users_groups/{id}.{format}",
255 255 action="show", conditions=dict(method=["GET"]))
256 256
257 257 #EXTRAS USER ROUTES
258 258 m.connect("users_group_perm", "/users_groups_perm/{id}",
259 259 action="update_perm", conditions=dict(method=["PUT"]))
260 260
261 261 #ADMIN GROUP REST ROUTES
262 262 rmap.resource('group', 'groups',
263 263 controller='admin/groups', path_prefix=ADMIN_PREFIX)
264 264
265 265 #ADMIN PERMISSIONS REST ROUTES
266 266 rmap.resource('permission', 'permissions',
267 267 controller='admin/permissions', path_prefix=ADMIN_PREFIX)
268 268
269 269 #ADMIN DEFAULTS REST ROUTES
270 270 rmap.resource('default', 'defaults',
271 271 controller='admin/defaults', path_prefix=ADMIN_PREFIX)
272 272
273 273 ##ADMIN LDAP SETTINGS
274 274 rmap.connect('ldap_settings', '%s/ldap' % ADMIN_PREFIX,
275 275 controller='admin/ldap_settings', action='ldap_settings',
276 276 conditions=dict(method=["POST"]))
277 277
278 278 rmap.connect('ldap_home', '%s/ldap' % ADMIN_PREFIX,
279 279 controller='admin/ldap_settings')
280 280
281 281 #ADMIN SETTINGS REST ROUTES
282 282 with rmap.submapper(path_prefix=ADMIN_PREFIX,
283 283 controller='admin/settings') as m:
284 284 m.connect("admin_settings", "/settings",
285 285 action="create", conditions=dict(method=["POST"]))
286 286 m.connect("admin_settings", "/settings",
287 287 action="index", conditions=dict(method=["GET"]))
288 288 m.connect("formatted_admin_settings", "/settings.{format}",
289 289 action="index", conditions=dict(method=["GET"]))
290 290 m.connect("admin_new_setting", "/settings/new",
291 291 action="new", conditions=dict(method=["GET"]))
292 292 m.connect("formatted_admin_new_setting", "/settings/new.{format}",
293 293 action="new", conditions=dict(method=["GET"]))
294 294 m.connect("/settings/{setting_id}",
295 295 action="update", conditions=dict(method=["PUT"]))
296 296 m.connect("/settings/{setting_id}",
297 297 action="delete", conditions=dict(method=["DELETE"]))
298 298 m.connect("admin_edit_setting", "/settings/{setting_id}/edit",
299 299 action="edit", conditions=dict(method=["GET"]))
300 300 m.connect("formatted_admin_edit_setting",
301 301 "/settings/{setting_id}.{format}/edit",
302 302 action="edit", conditions=dict(method=["GET"]))
303 303 m.connect("admin_setting", "/settings/{setting_id}",
304 304 action="show", conditions=dict(method=["GET"]))
305 305 m.connect("formatted_admin_setting", "/settings/{setting_id}.{format}",
306 306 action="show", conditions=dict(method=["GET"]))
307 307 m.connect("admin_settings_my_account", "/my_account",
308 308 action="my_account", conditions=dict(method=["GET"]))
309 309 m.connect("admin_settings_my_account_update", "/my_account_update",
310 310 action="my_account_update", conditions=dict(method=["PUT"]))
311 311 m.connect("admin_settings_create_repository", "/create_repository",
312 312 action="create_repository", conditions=dict(method=["GET"]))
313 313 m.connect("admin_settings_my_repos", "/my_account/repos",
314 314 action="my_account_my_repos", conditions=dict(method=["GET"]))
315 315 m.connect("admin_settings_my_pullrequests", "/my_account/pull_requests",
316 316 action="my_account_my_pullrequests", conditions=dict(method=["GET"]))
317 317
318 318 #NOTIFICATION REST ROUTES
319 319 with rmap.submapper(path_prefix=ADMIN_PREFIX,
320 320 controller='admin/notifications') as m:
321 321 m.connect("notifications", "/notifications",
322 322 action="create", conditions=dict(method=["POST"]))
323 323 m.connect("notifications", "/notifications",
324 324 action="index", conditions=dict(method=["GET"]))
325 325 m.connect("notifications_mark_all_read", "/notifications/mark_all_read",
326 326 action="mark_all_read", conditions=dict(method=["GET"]))
327 327 m.connect("formatted_notifications", "/notifications.{format}",
328 328 action="index", conditions=dict(method=["GET"]))
329 329 m.connect("new_notification", "/notifications/new",
330 330 action="new", conditions=dict(method=["GET"]))
331 331 m.connect("formatted_new_notification", "/notifications/new.{format}",
332 332 action="new", conditions=dict(method=["GET"]))
333 333 m.connect("/notification/{notification_id}",
334 334 action="update", conditions=dict(method=["PUT"]))
335 335 m.connect("/notification/{notification_id}",
336 336 action="delete", conditions=dict(method=["DELETE"]))
337 337 m.connect("edit_notification", "/notification/{notification_id}/edit",
338 338 action="edit", conditions=dict(method=["GET"]))
339 339 m.connect("formatted_edit_notification",
340 340 "/notification/{notification_id}.{format}/edit",
341 341 action="edit", conditions=dict(method=["GET"]))
342 342 m.connect("notification", "/notification/{notification_id}",
343 343 action="show", conditions=dict(method=["GET"]))
344 344 m.connect("formatted_notification", "/notifications/{notification_id}.{format}",
345 345 action="show", conditions=dict(method=["GET"]))
346 346
347 347 #ADMIN MAIN PAGES
348 348 with rmap.submapper(path_prefix=ADMIN_PREFIX,
349 349 controller='admin/admin') as m:
350 350 m.connect('admin_home', '', action='index')
351 351 m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
352 352 action='add_repo')
353 353
354 354 #==========================================================================
355 355 # API V2
356 356 #==========================================================================
357 357 with rmap.submapper(path_prefix=ADMIN_PREFIX,
358 358 controller='api/api') as m:
359 359 m.connect('api', '/api')
360 360
361 361 #USER JOURNAL
362 362 rmap.connect('journal', '%s/journal' % ADMIN_PREFIX,
363 363 controller='journal', action='index')
364 364 rmap.connect('journal_rss', '%s/journal/rss' % ADMIN_PREFIX,
365 365 controller='journal', action='journal_rss')
366 366 rmap.connect('journal_atom', '%s/journal/atom' % ADMIN_PREFIX,
367 367 controller='journal', action='journal_atom')
368 368
369 369 rmap.connect('public_journal', '%s/public_journal' % ADMIN_PREFIX,
370 370 controller='journal', action="public_journal")
371 371
372 372 rmap.connect('public_journal_rss', '%s/public_journal/rss' % ADMIN_PREFIX,
373 373 controller='journal', action="public_journal_rss")
374 374
375 375 rmap.connect('public_journal_rss_old', '%s/public_journal_rss' % ADMIN_PREFIX,
376 376 controller='journal', action="public_journal_rss")
377 377
378 378 rmap.connect('public_journal_atom',
379 379 '%s/public_journal/atom' % ADMIN_PREFIX, controller='journal',
380 380 action="public_journal_atom")
381 381
382 382 rmap.connect('public_journal_atom_old',
383 383 '%s/public_journal_atom' % ADMIN_PREFIX, controller='journal',
384 384 action="public_journal_atom")
385 385
386 386 rmap.connect('toggle_following', '%s/toggle_following' % ADMIN_PREFIX,
387 387 controller='journal', action='toggle_following',
388 388 conditions=dict(method=["POST"]))
389 389
390 390 #SEARCH
391 391 rmap.connect('search', '%s/search' % ADMIN_PREFIX, controller='search',)
392 rmap.connect('search_repo', '%s/search/{search_repo:.*}' % ADMIN_PREFIX,
392 rmap.connect('search_repo_admin', '%s/search/{repo_name:.*}' % ADMIN_PREFIX,
393 393 controller='search')
394 rmap.connect('search_repo', '/{repo_name:.*?}/search',
395 controller='search',
396 conditions=dict(function=check_repo),
397 )
394 398
395 399 #LOGIN/LOGOUT/REGISTER/SIGN IN
396 400 rmap.connect('login_home', '%s/login' % ADMIN_PREFIX, controller='login')
397 401 rmap.connect('logout_home', '%s/logout' % ADMIN_PREFIX, controller='login',
398 402 action='logout')
399 403
400 404 rmap.connect('register', '%s/register' % ADMIN_PREFIX, controller='login',
401 405 action='register')
402 406
403 407 rmap.connect('reset_password', '%s/password_reset' % ADMIN_PREFIX,
404 408 controller='login', action='password_reset')
405 409
406 410 rmap.connect('reset_password_confirmation',
407 411 '%s/password_reset_confirmation' % ADMIN_PREFIX,
408 412 controller='login', action='password_reset_confirmation')
409 413
410 414 #FEEDS
411 415 rmap.connect('rss_feed_home', '/{repo_name:.*?}/feed/rss',
412 416 controller='feed', action='rss',
413 417 conditions=dict(function=check_repo))
414 418
415 419 rmap.connect('atom_feed_home', '/{repo_name:.*?}/feed/atom',
416 420 controller='feed', action='atom',
417 421 conditions=dict(function=check_repo))
418 422
419 423 #==========================================================================
420 424 # REPOSITORY ROUTES
421 425 #==========================================================================
422 426 rmap.connect('summary_home', '/{repo_name:.*?}',
423 427 controller='summary',
424 428 conditions=dict(function=check_repo))
425 429
426 430 rmap.connect('repo_size', '/{repo_name:.*?}/repo_size',
427 431 controller='summary', action='repo_size',
428 432 conditions=dict(function=check_repo))
429 433
430 434 rmap.connect('repos_group_home', '/{group_name:.*}',
431 435 controller='admin/repos_groups', action="show_by_name",
432 436 conditions=dict(function=check_group))
433 437
434 438 rmap.connect('changeset_home', '/{repo_name:.*?}/changeset/{revision}',
435 439 controller='changeset', revision='tip',
436 440 conditions=dict(function=check_repo))
437 441
438 442 rmap.connect("edit_repo", "/{repo_name:.*?}/edit",
439 443 controller='admin/repos', action="edit",
440 444 conditions=dict(method=["GET"], function=check_repo)
441 445 )
442 446
443 447 #still working url for backward compat.
444 448 rmap.connect('raw_changeset_home_depraced',
445 449 '/{repo_name:.*?}/raw-changeset/{revision}',
446 450 controller='changeset', action='changeset_raw',
447 451 revision='tip', conditions=dict(function=check_repo))
448 452
449 453 ## new URLs
450 454 rmap.connect('changeset_raw_home',
451 455 '/{repo_name:.*?}/changeset-diff/{revision}',
452 456 controller='changeset', action='changeset_raw',
453 457 revision='tip', conditions=dict(function=check_repo))
454 458
455 459 rmap.connect('changeset_patch_home',
456 460 '/{repo_name:.*?}/changeset-patch/{revision}',
457 461 controller='changeset', action='changeset_patch',
458 462 revision='tip', conditions=dict(function=check_repo))
459 463
460 464 rmap.connect('changeset_download_home',
461 465 '/{repo_name:.*?}/changeset-download/{revision}',
462 466 controller='changeset', action='changeset_download',
463 467 revision='tip', conditions=dict(function=check_repo))
464 468
465 469 rmap.connect('changeset_comment',
466 470 '/{repo_name:.*?}/changeset/{revision}/comment',
467 471 controller='changeset', revision='tip', action='comment',
468 472 conditions=dict(function=check_repo))
469 473
470 474 rmap.connect('changeset_comment_delete',
471 475 '/{repo_name:.*?}/changeset/comment/{comment_id}/delete',
472 476 controller='changeset', action='delete_comment',
473 477 conditions=dict(function=check_repo, method=["DELETE"]))
474 478
475 479 rmap.connect('changeset_info', '/changeset_info/{repo_name:.*?}/{revision}',
476 480 controller='changeset', action='changeset_info')
477 481
478 482 rmap.connect('compare_url',
479 483 '/{repo_name:.*?}/compare/{org_ref_type}@{org_ref:.*?}...{other_ref_type}@{other_ref:.*?}',
480 484 controller='compare', action='index',
481 485 conditions=dict(function=check_repo),
482 486 requirements=dict(
483 487 org_ref_type='(branch|book|tag|rev|org_ref_type)',
484 488 other_ref_type='(branch|book|tag|rev|other_ref_type)')
485 489 )
486 490
487 491 rmap.connect('pullrequest_home',
488 492 '/{repo_name:.*?}/pull-request/new', controller='pullrequests',
489 493 action='index', conditions=dict(function=check_repo,
490 494 method=["GET"]))
491 495
492 496 rmap.connect('pullrequest',
493 497 '/{repo_name:.*?}/pull-request/new', controller='pullrequests',
494 498 action='create', conditions=dict(function=check_repo,
495 499 method=["POST"]))
496 500
497 501 rmap.connect('pullrequest_show',
498 502 '/{repo_name:.*?}/pull-request/{pull_request_id}',
499 503 controller='pullrequests',
500 504 action='show', conditions=dict(function=check_repo,
501 505 method=["GET"]))
502 506 rmap.connect('pullrequest_update',
503 507 '/{repo_name:.*?}/pull-request/{pull_request_id}',
504 508 controller='pullrequests',
505 509 action='update', conditions=dict(function=check_repo,
506 510 method=["PUT"]))
507 511 rmap.connect('pullrequest_delete',
508 512 '/{repo_name:.*?}/pull-request/{pull_request_id}',
509 513 controller='pullrequests',
510 514 action='delete', conditions=dict(function=check_repo,
511 515 method=["DELETE"]))
512 516
513 517 rmap.connect('pullrequest_show_all',
514 518 '/{repo_name:.*?}/pull-request',
515 519 controller='pullrequests',
516 520 action='show_all', conditions=dict(function=check_repo,
517 521 method=["GET"]))
518 522
519 523 rmap.connect('pullrequest_comment',
520 524 '/{repo_name:.*?}/pull-request-comment/{pull_request_id}',
521 525 controller='pullrequests',
522 526 action='comment', conditions=dict(function=check_repo,
523 527 method=["POST"]))
524 528
525 529 rmap.connect('pullrequest_comment_delete',
526 530 '/{repo_name:.*?}/pull-request-comment/{comment_id}/delete',
527 531 controller='pullrequests', action='delete_comment',
528 532 conditions=dict(function=check_repo, method=["DELETE"]))
529 533
530 534 rmap.connect('summary_home_summary', '/{repo_name:.*?}/summary',
531 535 controller='summary', conditions=dict(function=check_repo))
532 536
533 537 rmap.connect('shortlog_home', '/{repo_name:.*?}/shortlog',
534 538 controller='shortlog', conditions=dict(function=check_repo))
535 539
536 540 rmap.connect('shortlog_file_home', '/{repo_name:.*?}/shortlog/{revision}/{f_path:.*}',
537 541 controller='shortlog', f_path=None,
538 542 conditions=dict(function=check_repo))
539 543
540 544 rmap.connect('branches_home', '/{repo_name:.*?}/branches',
541 545 controller='branches', conditions=dict(function=check_repo))
542 546
543 547 rmap.connect('tags_home', '/{repo_name:.*?}/tags',
544 548 controller='tags', conditions=dict(function=check_repo))
545 549
546 550 rmap.connect('bookmarks_home', '/{repo_name:.*?}/bookmarks',
547 551 controller='bookmarks', conditions=dict(function=check_repo))
548 552
549 553 rmap.connect('changelog_home', '/{repo_name:.*?}/changelog',
550 554 controller='changelog', conditions=dict(function=check_repo))
551 555
552 556 rmap.connect('changelog_details', '/{repo_name:.*?}/changelog_details/{cs}',
553 557 controller='changelog', action='changelog_details',
554 558 conditions=dict(function=check_repo))
555 559
556 560 rmap.connect('files_home', '/{repo_name:.*?}/files/{revision}/{f_path:.*}',
557 561 controller='files', revision='tip', f_path='',
558 562 conditions=dict(function=check_repo))
559 563
560 564 rmap.connect('files_history_home',
561 565 '/{repo_name:.*?}/history/{revision}/{f_path:.*}',
562 566 controller='files', action='history', revision='tip', f_path='',
563 567 conditions=dict(function=check_repo))
564 568
565 569 rmap.connect('files_diff_home', '/{repo_name:.*?}/diff/{f_path:.*}',
566 570 controller='files', action='diff', revision='tip', f_path='',
567 571 conditions=dict(function=check_repo))
568 572
569 573 rmap.connect('files_rawfile_home',
570 574 '/{repo_name:.*?}/rawfile/{revision}/{f_path:.*}',
571 575 controller='files', action='rawfile', revision='tip',
572 576 f_path='', conditions=dict(function=check_repo))
573 577
574 578 rmap.connect('files_raw_home',
575 579 '/{repo_name:.*?}/raw/{revision}/{f_path:.*}',
576 580 controller='files', action='raw', revision='tip', f_path='',
577 581 conditions=dict(function=check_repo))
578 582
579 583 rmap.connect('files_annotate_home',
580 584 '/{repo_name:.*?}/annotate/{revision}/{f_path:.*}',
581 585 controller='files', action='index', revision='tip',
582 586 f_path='', annotate=True, conditions=dict(function=check_repo))
583 587
584 588 rmap.connect('files_edit_home',
585 589 '/{repo_name:.*?}/edit/{revision}/{f_path:.*}',
586 590 controller='files', action='edit', revision='tip',
587 591 f_path='', conditions=dict(function=check_repo))
588 592
589 593 rmap.connect('files_add_home',
590 594 '/{repo_name:.*?}/add/{revision}/{f_path:.*}',
591 595 controller='files', action='add', revision='tip',
592 596 f_path='', conditions=dict(function=check_repo))
593 597
594 598 rmap.connect('files_archive_home', '/{repo_name:.*?}/archive/{fname}',
595 599 controller='files', action='archivefile',
596 600 conditions=dict(function=check_repo))
597 601
598 602 rmap.connect('files_nodelist_home',
599 603 '/{repo_name:.*?}/nodelist/{revision}/{f_path:.*}',
600 604 controller='files', action='nodelist',
601 605 conditions=dict(function=check_repo))
602 606
603 607 rmap.connect('repo_settings_delete', '/{repo_name:.*?}/settings',
604 608 controller='settings', action="delete",
605 609 conditions=dict(method=["DELETE"], function=check_repo))
606 610
607 611 rmap.connect('repo_settings_update', '/{repo_name:.*?}/settings',
608 612 controller='settings', action="update",
609 613 conditions=dict(method=["PUT"], function=check_repo))
610 614
611 615 rmap.connect('repo_settings_home', '/{repo_name:.*?}/settings',
612 616 controller='settings', action='index',
613 617 conditions=dict(function=check_repo))
614 618
615 619 rmap.connect('toggle_locking', "/{repo_name:.*?}/locking_toggle",
616 620 controller='settings', action="toggle_locking",
617 621 conditions=dict(method=["GET"], function=check_repo))
618 622
619 623 rmap.connect('repo_fork_create_home', '/{repo_name:.*?}/fork',
620 624 controller='forks', action='fork_create',
621 625 conditions=dict(function=check_repo, method=["POST"]))
622 626
623 627 rmap.connect('repo_fork_home', '/{repo_name:.*?}/fork',
624 628 controller='forks', action='fork',
625 629 conditions=dict(function=check_repo))
626 630
627 631 rmap.connect('repo_forks_home', '/{repo_name:.*?}/forks',
628 632 controller='forks', action='forks',
629 633 conditions=dict(function=check_repo))
630 634
631 635 rmap.connect('repo_followers_home', '/{repo_name:.*?}/followers',
632 636 controller='followers', action='followers',
633 637 conditions=dict(function=check_repo))
634 638
635 639 return rmap
@@ -1,146 +1,146
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.controllers.search
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 Search controller for RhodeCode
7 7
8 8 :created_on: Aug 7, 2010
9 9 :author: marcink
10 10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 11 :license: GPLv3, see COPYING for more details.
12 12 """
13 13 # This program is free software: you can redistribute it and/or modify
14 14 # it under the terms of the GNU General Public License as published by
15 15 # the Free Software Foundation, either version 3 of the License, or
16 16 # (at your option) any later version.
17 17 #
18 18 # This program is distributed in the hope that it will be useful,
19 19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 21 # GNU General Public License for more details.
22 22 #
23 23 # You should have received a copy of the GNU General Public License
24 24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 25 import logging
26 26 import traceback
27 27 import urllib
28 28 from pylons.i18n.translation import _
29 29 from pylons import request, config, tmpl_context as c
30 30
31 31 from rhodecode.lib.auth import LoginRequired
32 from rhodecode.lib.base import BaseController, render
32 from rhodecode.lib.base import BaseRepoController, render
33 33 from rhodecode.lib.indexers import CHGSETS_SCHEMA, SCHEMA, CHGSET_IDX_NAME, \
34 34 IDX_NAME, WhooshResultWrapper
35 35
36 36 from webhelpers.paginate import Page
37 37 from webhelpers.util import update_params
38 38
39 39 from whoosh.index import open_dir, EmptyIndexError
40 40 from whoosh.qparser import QueryParser, QueryParserError
41 41 from whoosh.query import Phrase, Wildcard, Term, Prefix
42 42 from rhodecode.model.repo import RepoModel
43 43 from rhodecode.lib.utils2 import safe_str, safe_int
44 44
45 45
46 46 log = logging.getLogger(__name__)
47 47
48 48
49 class SearchController(BaseController):
49 class SearchController(BaseRepoController):
50 50
51 51 @LoginRequired()
52 52 def __before__(self):
53 53 super(SearchController, self).__before__()
54 54
55 def index(self, search_repo=None):
56 c.repo_name = search_repo
55 def index(self, repo_name=None):
56 c.repo_name = repo_name
57 57 c.formated_results = []
58 58 c.runtime = ''
59 59 c.cur_query = request.GET.get('q', None)
60 60 c.cur_type = request.GET.get('type', 'content')
61 61 c.cur_search = search_type = {'content': 'content',
62 62 'commit': 'message',
63 63 'path': 'path',
64 64 'repository': 'repository'
65 65 }.get(c.cur_type, 'content')
66 66
67 67 index_name = {
68 68 'content': IDX_NAME,
69 69 'commit': CHGSET_IDX_NAME,
70 70 'path': IDX_NAME
71 71 }.get(c.cur_type, IDX_NAME)
72 72
73 73 schema_defn = {
74 74 'content': SCHEMA,
75 75 'commit': CHGSETS_SCHEMA,
76 76 'path': SCHEMA
77 77 }.get(c.cur_type, SCHEMA)
78 78
79 79 log.debug('IDX: %s' % index_name)
80 80 log.debug('SCHEMA: %s' % schema_defn)
81 81
82 82 if c.cur_query:
83 83 cur_query = c.cur_query.lower()
84 84 log.debug(cur_query)
85 85
86 86 if c.cur_query:
87 87 p = safe_int(request.params.get('page', 1), 1)
88 88 highlight_items = set()
89 89 try:
90 90 idx = open_dir(config['app_conf']['index_dir'],
91 91 indexname=index_name)
92 92 searcher = idx.searcher()
93 93
94 94 qp = QueryParser(search_type, schema=schema_defn)
95 95 if c.repo_name:
96 96 cur_query = u'repository:%s %s' % (c.repo_name, cur_query)
97 97 try:
98 98 query = qp.parse(unicode(cur_query))
99 99 # extract words for highlight
100 100 if isinstance(query, Phrase):
101 101 highlight_items.update(query.words)
102 102 elif isinstance(query, Prefix):
103 103 highlight_items.add(query.text)
104 104 else:
105 105 for i in query.all_terms():
106 106 if i[0] in ['content', 'message']:
107 107 highlight_items.add(i[1])
108 108
109 109 matcher = query.matcher(searcher)
110 110
111 111 log.debug('query: %s' % query)
112 112 log.debug('hl terms: %s' % highlight_items)
113 113 results = searcher.search(query)
114 114 res_ln = len(results)
115 115 c.runtime = '%s results (%.3f seconds)' % (
116 116 res_ln, results.runtime
117 117 )
118 118
119 119 def url_generator(**kw):
120 120 q = urllib.quote(safe_str(c.cur_query))
121 121 return update_params("?q=%s&type=%s" \
122 122 % (q, safe_str(c.cur_type)), **kw)
123 123 repo_location = RepoModel().repos_path
124 124 c.formated_results = Page(
125 125 WhooshResultWrapper(search_type, searcher, matcher,
126 126 highlight_items, repo_location),
127 127 page=p,
128 128 item_count=res_ln,
129 129 items_per_page=10,
130 130 url=url_generator
131 131 )
132 132
133 133 except QueryParserError:
134 134 c.runtime = _('Invalid search query. Try quoting it.')
135 135 searcher.close()
136 136 except (EmptyIndexError, IOError):
137 137 log.error(traceback.format_exc())
138 138 log.error('Empty Index data')
139 139 c.runtime = _('There is no index to search in. '
140 140 'Please run whoosh indexer')
141 141 except (Exception):
142 142 log.error(traceback.format_exc())
143 143 c.runtime = _('An error occurred during this search operation')
144 144
145 145 # Return a rendered template
146 146 return render('/search/search.html')
@@ -1,360 +1,360
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="root.html"/>
3 3
4 4 <!-- HEADER -->
5 5 <div id="header">
6 6 <div id="header-inner" class="title hover">
7 7 <div id="logo">
8 8 <h1><a href="${h.url('home')}">${c.rhodecode_name}</a></h1>
9 9 </div>
10 10 <!-- MENU -->
11 11 ${self.page_nav()}
12 12 <!-- END MENU -->
13 13 ${self.body()}
14 14 </div>
15 15 </div>
16 16 <!-- END HEADER -->
17 17
18 18 <!-- CONTENT -->
19 19 <div id="content">
20 20 <div class="flash_msg">
21 21 <% messages = h.flash.pop_messages() %>
22 22 % if messages:
23 23 <ul id="flash-messages">
24 24 % for message in messages:
25 25 <li class="${message.category}_msg">${message}</li>
26 26 % endfor
27 27 </ul>
28 28 % endif
29 29 </div>
30 30 <div id="main">
31 31 ${next.main()}
32 32 </div>
33 33 </div>
34 34 <!-- END CONTENT -->
35 35
36 36 <!-- FOOTER -->
37 37 <div id="footer">
38 38 <div id="footer-inner" class="title">
39 39 <div>
40 40 <p class="footer-link">
41 41 <a href="${h.url('bugtracker')}">${_('Submit a bug')}</a>
42 42 </p>
43 43 <p class="footer-link-right">
44 44 <a href="${h.url('rhodecode_official')}">RhodeCode${'-%s' % c.rhodecode_instanceid if c.rhodecode_instanceid else ''}</a>
45 45 ${c.rhodecode_version} &copy; 2010-${h.datetime.today().year} by Marcin Kuzminski
46 46 </p>
47 47 </div>
48 48 </div>
49 49 </div>
50 50 <!-- END FOOTER -->
51 51
52 52 ### MAKO DEFS ###
53 53 <%def name="page_nav()">
54 54 ${self.menu()}
55 55 </%def>
56 56
57 57 <%def name="breadcrumbs()">
58 58 <div class="breadcrumbs">
59 59 ${self.breadcrumbs_links()}
60 60 </div>
61 61 </%def>
62 62
63 63 <%def name="usermenu()">
64 64 ## USER MENU
65 65 <li>
66 66 <a class="menu_link" id="quick_login_link">
67 67 <span class="icon" style="padding:5px 5px 0px 5px">
68 68 <img src="${h.gravatar_url(c.rhodecode_user.email,20)}" alt="avatar">
69 69 </span>
70 70 %if c.rhodecode_user.username != 'default':
71 71 <span class="menu_link_user">${c.rhodecode_user.username}</span>
72 72 %if c.unread_notifications != 0:
73 73 <span class="menu_link_notifications">${c.unread_notifications}</span>
74 74 %endif
75 75 %else:
76 76 <span>${_('Not logged in')}</span>
77 77 %endif
78 78 </a>
79 79
80 80 <div class="user-menu">
81 81 <div id="quick_login">
82 82 %if c.rhodecode_user.username == 'default':
83 83 <h4>${_('Login to your account')}</h4>
84 84 ${h.form(h.url('login_home',came_from=h.url.current()))}
85 85 <div class="form">
86 86 <div class="fields">
87 87 <div class="field">
88 88 <div class="label">
89 89 <label for="username">${_('Username')}:</label>
90 90 </div>
91 91 <div class="input">
92 92 ${h.text('username',class_='focus',size=40)}
93 93 </div>
94 94
95 95 </div>
96 96 <div class="field">
97 97 <div class="label">
98 98 <label for="password">${_('Password')}:</label>
99 99 </div>
100 100 <div class="input">
101 101 ${h.password('password',class_='focus',size=40)}
102 102 </div>
103 103
104 104 </div>
105 105 <div class="buttons">
106 106 <div class="password_forgoten">${h.link_to(_('Forgot password ?'),h.url('reset_password'))}</div>
107 107 <div class="register">
108 108 %if h.HasPermissionAny('hg.admin', 'hg.register.auto_activate', 'hg.register.manual_activate')():
109 109 ${h.link_to(_("Don't have an account ?"),h.url('register'))}
110 110 %endif
111 111 </div>
112 112 <div class="submit">
113 113 ${h.submit('sign_in',_('Log In'),class_="ui-btn xsmall")}
114 114 </div>
115 115 </div>
116 116 </div>
117 117 </div>
118 118 ${h.end_form()}
119 119 %else:
120 120 <div class="links_left">
121 121 <div class="full_name">${c.rhodecode_user.full_name_or_username}</div>
122 122 <div class="email">${c.rhodecode_user.email}</div>
123 123 <div class="big_gravatar"><img alt="gravatar" src="${h.gravatar_url(c.rhodecode_user.email,48)}" /></div>
124 124 <div class="notifications"><a href="${h.url('notifications')}">${_('Notifications')}</a></div>
125 125 <div class="unread">${_('Unread')}: ${c.unread_notifications}</div>
126 126 </div>
127 127 <div class="links_right">
128 128 <ol class="links">
129 129 <li>${h.link_to(_(u'Home'),h.url('home'))}</li>
130 130 <li>${h.link_to(_(u'Journal'),h.url('journal'))}</li>
131 131 <li>${h.link_to(_(u'My account'),h.url('admin_settings_my_account'))}</li>
132 132 <li class="logout">${h.link_to(_(u'Log Out'),h.url('logout_home'))}</li>
133 133 </ol>
134 134 </div>
135 135 %endif
136 136 </div>
137 137 </div>
138 138
139 139 </li>
140 140 </%def>
141 141
142 142 <%def name="menu(current=None)">
143 143 <%
144 144 def is_current(selected):
145 145 if selected == current:
146 146 return h.literal('class="current"')
147 147 %>
148 148 <ul id="quick">
149 149 <!-- repo switcher -->
150 150 <li ${is_current('home')}>
151 151 <a class="menu_link" id="repo_switcher" title="${_('Switch repository')}" href="${h.url('home')}">
152 152 <span class="icon">
153 153 <img src="${h.url('/images/icons/database.png')}" alt="${_('Products')}" />
154 154 </span>
155 155 <span>${_('Repositories')}</span>
156 156 </a>
157 157 <ul id="repo_switcher_list" class="repo_switcher">
158 158 <li>
159 159 <a href="#">${_('loading...')}</a>
160 160 </li>
161 161 </ul>
162 162 </li>
163 163 ## we render this menu only not for those pages
164 164 %if current not in ['home','admin', 'search', 'journal']:
165 165 ##REGULAR MENU
166 166 <li ${is_current('summary')}>
167 167 <a class="menu_link" title="${_('Summary page')}" href="${h.url('summary_home',repo_name=c.repo_name)}">
168 168 <span class="icon">
169 169 <img src="${h.url('/images/icons/clipboard_16.png')}" alt="${_('Summary')}" />
170 170 </span>
171 171 <span>${_('Summary')}</span>
172 172 </a>
173 173 </li>
174 174 <li ${is_current('changelog')}>
175 175 <a class="menu_link" title="${_('Changeset list')}" href="${h.url('changelog_home',repo_name=c.repo_name)}">
176 176 <span class="icon">
177 177 <img src="${h.url('/images/icons/time.png')}" alt="${_('Changelog')}" />
178 178 </span>
179 179 <span>${_('Changelog')}</span>
180 180 </a>
181 181 </li>
182 182 <li ${is_current('switch_to')}>
183 183 <a class="menu_link" id="branch_tag_switcher" title="${_('Switch to')}" href="#">
184 184 <span class="icon">
185 185 <img src="${h.url('/images/icons/arrow_switch.png')}" alt="${_('Switch to')}" />
186 186 </span>
187 187 <span>${_('Switch to')}</span>
188 188 </a>
189 189 <ul id="switch_to_list" class="switch_to">
190 190 <li><a href="#">${_('loading...')}</a></li>
191 191 </ul>
192 192 </li>
193 193 <li ${is_current('files')}>
194 194 <a class="menu_link" title="${_('Show repository content')}" href="${h.url('files_home',repo_name=c.repo_name)}">
195 195 <span class="icon">
196 196 <img src="${h.url('/images/icons/file.png')}" alt="${_('Files')}" />
197 197 </span>
198 198 <span>${_('Files')}</span>
199 199 </a>
200 200 </li>
201 201 <li ${is_current('options')}>
202 202 <a class="menu_link" title="${_('Options')}" href="#">
203 203 <span class="icon">
204 204 <img src="${h.url('/images/icons/table_gear.png')}" alt="${_('Admin')}" />
205 205 </span>
206 206 <span>${_('Options')}</span>
207 207 </a>
208 208 <ul>
209 209 %if h.HasRepoPermissionAll('repository.admin')(c.repo_name):
210 210 %if h.HasPermissionAll('hg.admin')('access settings on repository'):
211 211 <li>${h.link_to(_('repository settings'),h.url('edit_repo',repo_name=c.repo_name),class_='settings')}</li>
212 212 %else:
213 213 <li>${h.link_to(_('repository settings'),h.url('repo_settings_home',repo_name=c.repo_name),class_='settings')}</li>
214 214 %endif
215 215 %endif
216 216
217 217 <li>${h.link_to(_('fork'),h.url('repo_fork_home',repo_name=c.repo_name),class_='fork')}</li>
218 218 %if h.is_hg(c.rhodecode_repo):
219 219 <li>${h.link_to(_('open new pull request'),h.url('pullrequest_home',repo_name=c.repo_name),class_='pull_request')}</li>
220 220 %endif
221 221 %if c.rhodecode_db_repo.fork:
222 222 <li>${h.link_to(_('compare fork'),h.url('compare_url',repo_name=c.repo_name,org_ref_type='branch',org_ref=request.GET.get('branch') or 'default',other_ref_type='branch',other_ref='default',repo=c.rhodecode_db_repo.fork.repo_name),class_='compare_request')}</li>
223 223 %endif
224 <li>${h.link_to(_('search'),h.url('search_repo',search_repo=c.repo_name),class_='search')}</li>
224 <li>${h.link_to(_('search'),h.url('search_repo',repo_name=c.repo_name),class_='search')}</li>
225 225
226 226 %if h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name) and c.rhodecode_db_repo.enable_locking:
227 227 %if c.rhodecode_db_repo.locked[0]:
228 228 <li>${h.link_to(_('unlock'), h.url('toggle_locking',repo_name=c.repo_name),class_='locking_del')}</li>
229 229 %else:
230 230 <li>${h.link_to(_('lock'), h.url('toggle_locking',repo_name=c.repo_name),class_='locking_add')}</li>
231 231 %endif
232 232 %endif
233 233
234 234 % if h.HasPermissionAll('hg.admin')('access admin main page'):
235 235 <li>
236 236 ${h.link_to(_('admin'),h.url('admin_home'),class_='admin')}
237 237 <%def name="admin_menu()">
238 238 <ul>
239 239 <li>${h.link_to(_('admin journal'),h.url('admin_home'),class_='journal')}</li>
240 240 <li>${h.link_to(_('repositories'),h.url('repos'),class_='repos')}</li>
241 241 <li>${h.link_to(_('repositories groups'),h.url('repos_groups'),class_='repos_groups')}</li>
242 242 <li>${h.link_to(_('users'),h.url('users'),class_='users')}</li>
243 243 <li>${h.link_to(_('users groups'),h.url('users_groups'),class_='groups')}</li>
244 244 <li>${h.link_to(_('permissions'),h.url('edit_permission',id='default'),class_='permissions')}</li>
245 245 <li>${h.link_to(_('ldap'),h.url('ldap_home'),class_='ldap')}</li>
246 246 <li>${h.link_to(_('defaults'),h.url('defaults'),class_='defaults')}</li>
247 247 <li class="last">${h.link_to(_('settings'),h.url('admin_settings'),class_='settings')}</li>
248 248 </ul>
249 249 </%def>
250 250 ## ADMIN MENU
251 251 ${admin_menu()}
252 252 </li>
253 253 % endif
254 254 </ul>
255 255 </li>
256 256 <li>
257 257 <a class="menu_link" title="${_('Followers')}" href="${h.url('repo_followers_home',repo_name=c.repo_name)}">
258 258 <span class="icon_short">
259 259 <img src="${h.url('/images/icons/heart.png')}" alt="${_('Followers')}" />
260 260 </span>
261 261 <span id="current_followers_count" class="short">${c.repository_followers}</span>
262 262 </a>
263 263 </li>
264 264 <li>
265 265 <a class="menu_link" title="${_('Forks')}" href="${h.url('repo_forks_home',repo_name=c.repo_name)}">
266 266 <span class="icon_short">
267 267 <img src="${h.url('/images/icons/arrow_divide.png')}" alt="${_('Forks')}" />
268 268 </span>
269 269 <span class="short">${c.repository_forks}</span>
270 270 </a>
271 271 </li>
272 272 <li>
273 273 <a class="menu_link" title="${_('Pull requests')}" href="${h.url('pullrequest_show_all',repo_name=c.repo_name)}">
274 274 <span class="icon_short">
275 275 <img src="${h.url('/images/icons/arrow_join.png')}" alt="${_('Pull requests')}" />
276 276 </span>
277 277 <span class="short">${c.repository_pull_requests}</span>
278 278 </a>
279 279 </li>
280 280 ${usermenu()}
281 281 <script type="text/javascript">
282 282 YUE.on('branch_tag_switcher','mouseover',function(){
283 283 var loaded = YUD.hasClass('branch_tag_switcher','loaded');
284 284 if(!loaded){
285 285 YUD.addClass('branch_tag_switcher','loaded');
286 286 ypjax("${h.url('branch_tag_switcher',repo_name=c.repo_name)}",'switch_to_list',
287 287 function(o){},
288 288 function(o){YUD.removeClass('branch_tag_switcher','loaded');}
289 289 ,null);
290 290 }
291 291 return false;
292 292 });
293 293 </script>
294 294 %else:
295 295 ##ROOT MENU
296 296 %if c.rhodecode_user.username != 'default':
297 297 <li ${is_current('journal')}>
298 298 <a class="menu_link" title="${_('Show recent activity')}" href="${h.url('journal')}">
299 299 <span class="icon">
300 300 <img src="${h.url('/images/icons/book.png')}" alt="${_('Journal')}" />
301 301 </span>
302 302 <span>${_('Journal')}</span>
303 303 </a>
304 304 </li>
305 305 %else:
306 306 <li ${is_current('journal')}>
307 307 <a class="menu_link" title="${_('Public journal')}" href="${h.url('public_journal')}">
308 308 <span class="icon">
309 309 <img src="${h.url('/images/icons/book.png')}" alt="${_('Public journal')}" />
310 310 </span>
311 311 <span>${_('Public journal')}</span>
312 312 </a>
313 313 </li>
314 314 %endif
315 315 <li ${is_current('search')}>
316 316 <a class="menu_link" title="${_('Search in repositories')}" href="${h.url('search')}">
317 317 <span class="icon">
318 318 <img src="${h.url('/images/icons/search_16.png')}" alt="${_('Search')}" />
319 319 </span>
320 320 <span>${_('Search')}</span>
321 321 </a>
322 322 </li>
323 323 %if h.HasPermissionAll('hg.admin')('access admin main page'):
324 324 <li ${is_current('admin')}>
325 325 <a class="menu_link" title="${_('Admin')}" href="${h.url('admin_home')}">
326 326 <span class="icon">
327 327 <img src="${h.url('/images/icons/cog_edit.png')}" alt="${_('Admin')}" />
328 328 </span>
329 329 <span>${_('Admin')}</span>
330 330 </a>
331 331 ${admin_menu()}
332 332 </li>
333 333 %endif
334 334 ${usermenu()}
335 335 %endif
336 336 <script type="text/javascript">
337 337 YUE.on('repo_switcher','mouseover',function(){
338 338 var target = 'q_filter_rs';
339 339 var qfilter_activate = function(){
340 340 var nodes = YUQ('ul#repo_switcher_list li a.repo_name');
341 341 var func = function(node){
342 342 return node.parentNode;
343 343 }
344 344 q_filter(target,nodes,func);
345 345 }
346 346
347 347 var loaded = YUD.hasClass('repo_switcher','loaded');
348 348 if(!loaded){
349 349 YUD.addClass('repo_switcher','loaded');
350 350 ypjax("${h.url('repo_switcher')}",'repo_switcher_list',
351 351 function(o){qfilter_activate();YUD.get(target).focus()},
352 352 function(o){YUD.removeClass('repo_switcher','loaded');}
353 353 ,null);
354 354 }else{
355 355 YUD.get(target).focus();
356 356 }
357 357 return false;
358 358 });
359 359 </script>
360 360 </%def>
@@ -1,87 +1,91
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="/base/base.html"/>
3
3 4 <%def name="title()">
4 %if c.cur_query:
5 5 %if c.repo_name:
6 ${_('Search "%s" in repository: %s') % (c.cur_query, c.repo_name)}
7 %else:
8 ${_('Search "%s" in all repositories') % c.cur_query}
9 %endif
10 %else:
11 %if c.repo_name:
12 ${_('Search in repository: %s') % c.repo_name}
6 ${_('Search repository')} ${c.repo_name} - ${c.rhodecode_name}
13 7 %else:
14 8 ${_('Search in all repositories')}
15 9 %endif
16 %endif
17 - ${c.rhodecode_name}
18 10 </%def>
19 <%def name="breadcrumbs()">
20 ${c.rhodecode_name}
11
12 <%def name="breadcrumbs_links()">
13 %if c.repo_name:
14 ${h.link_to(_(u'Home'),h.url('/'))}
15 &raquo;
16 ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
17 &raquo;
18 ${_('Search')}
19 %else:
20 ${_('Search in all repositories')}
21 %endif
22 %if c.cur_query:
23 &raquo;
24 ${c.cur_query}
25 %endif
21 26 </%def>
27
22 28 <%def name="page_nav()">
29 %if c.repo_name:
30 ${self.menu('options')}
31 %else:
23 32 ${self.menu('search')}
33 %endif
24 34 </%def>
25 35 <%def name="main()">
26 36
27 37 <div class="box">
28 38 <!-- box / title -->
29 39 <div class="title">
30 <h5>
31 %if c.repo_name:
32 ${_('Search in repository: %s') % c.repo_name}
33 %else:
34 ${_('Search in all repositories')}
35 %endif
36 </h5>
40 ${self.breadcrumbs()}
37 41 </div>
38 42 <!-- end box / title -->
39 43 %if c.repo_name:
40 ${h.form(h.url('search_repo',search_repo=c.repo_name),method='get')}
44 ${h.form(h.url('search_repo',repo_name=c.repo_name),method='get')}
41 45 %else:
42 46 ${h.form(h.url('search'),method='get')}
43 47 %endif
44 48 <div class="form">
45 49 <div class="fields">
46 50 <div class="field field-first field-noborder">
47 51 <div class="label">
48 52 <label for="q">${_('Search term')}</label>
49 53 </div>
50 54 <div class="input">${h.text('q',c.cur_query,class_="small")}
51 55 <div class="button highlight">
52 56 <input type="submit" value="${_('Search')}" class="ui-button"/>
53 57 </div>
54 58 </div>
55 59 <div style="font-weight: bold;clear:Both;margin-left:200px">${c.runtime}</div>
56 60 </div>
57 61
58 62 <div class="field">
59 63 <div class="label">
60 64 <label for="type">${_('Search in')}</label>
61 65 </div>
62 66 <div class="select">
63 67 ${h.select('type',c.cur_type,[('content',_('File contents')),
64 68 ('commit',_('Commit messages')),
65 69 ('path',_('File names')),
66 70 ##('repository',_('Repository names')),
67 71 ])}
68 72 </div>
69 73 </div>
70 74
71 75 </div>
72 76 </div>
73 77 ${h.end_form()}
74 78 <div class="search">
75 79 %if c.cur_type == 'content':
76 80 <%include file='search_content.html'/>
77 81 %elif c.cur_type == 'path':
78 82 <%include file='search_path.html'/>
79 83 %elif c.cur_type == 'commit':
80 84 <%include file='search_commit.html'/>
81 85 %elif c.cur_type == 'repository':
82 86 <%include file='search_repository.html'/>
83 87 %endif
84 88 </div>
85 89 </div>
86 90
87 91 </%def>
General Comments 0
You need to be logged in to leave comments. Login now