##// END OF EJS Templates
fixed #113 to high permission was required to fork a repository
marcink -
r1054:32dbf759 beta
parent child Browse files
Show More
@@ -1,200 +1,202
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.settings
3 rhodecode.controllers.settings
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Settings controller for rhodecode
6 Settings controller for rhodecode
7
7
8 :created_on: Jun 30, 2010
8 :created_on: Jun 30, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software; you can redistribute it and/or
13 # This program is free software; you can redistribute it and/or
14 # modify it under the terms of the GNU General Public License
14 # modify it under the terms of the GNU General Public License
15 # as published by the Free Software Foundation; version 2
15 # as published by the Free Software Foundation; version 2
16 # of the License or (at your opinion) any later version of the license.
16 # of the License or (at your opinion) any later version of the license.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program; if not, write to the Free Software
24 # along with this program; if not, write to the Free Software
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 # MA 02110-1301, USA.
26 # MA 02110-1301, USA.
27
27
28 import logging
28 import logging
29 import traceback
29 import traceback
30
30
31 import formencode
31 import formencode
32
32
33 from pylons import tmpl_context as c, request, url
33 from pylons import tmpl_context as c, request, url
34 from pylons.controllers.util import redirect
34 from pylons.controllers.util import redirect
35 from pylons.i18n.translation import _
35 from pylons.i18n.translation import _
36
36
37 import rhodecode.lib.helpers as h
37 import rhodecode.lib.helpers as h
38 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAllDecorator
38 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAllDecorator
39 from rhodecode.lib.base import BaseRepoController, render
39 from rhodecode.lib.base import BaseRepoController, render
40 from rhodecode.lib.utils import invalidate_cache, action_logger
40 from rhodecode.lib.utils import invalidate_cache, action_logger
41 from rhodecode.model.forms import RepoSettingsForm, RepoForkForm
41 from rhodecode.model.forms import RepoSettingsForm, RepoForkForm
42 from rhodecode.model.repo import RepoModel
42 from rhodecode.model.repo import RepoModel
43 from rhodecode.model.db import User
43 from rhodecode.model.db import User
44
44
45 log = logging.getLogger(__name__)
45 log = logging.getLogger(__name__)
46
46
47 class SettingsController(BaseRepoController):
47 class SettingsController(BaseRepoController):
48
48
49 @LoginRequired()
49 @LoginRequired()
50 @HasRepoPermissionAllDecorator('repository.admin')
51 def __before__(self):
50 def __before__(self):
52 super(SettingsController, self).__before__()
51 super(SettingsController, self).__before__()
53
52
53 @HasRepoPermissionAllDecorator('repository.admin')
54 def index(self, repo_name):
54 def index(self, repo_name):
55 repo_model = RepoModel()
55 repo_model = RepoModel()
56 c.repo_info = repo = repo_model.get_by_repo_name(repo_name)
56 c.repo_info = repo = repo_model.get_by_repo_name(repo_name)
57 if not repo:
57 if not repo:
58 h.flash(_('%s repository is not mapped to db perhaps'
58 h.flash(_('%s repository is not mapped to db perhaps'
59 ' it was created or renamed from the file system'
59 ' it was created or renamed from the file system'
60 ' please run the application again'
60 ' please run the application again'
61 ' in order to rescan repositories') % repo_name,
61 ' in order to rescan repositories') % repo_name,
62 category='error')
62 category='error')
63
63
64 return redirect(url('home'))
64 return redirect(url('home'))
65
65
66 c.users_array = repo_model.get_users_js()
66 c.users_array = repo_model.get_users_js()
67 c.users_groups_array = repo_model.get_users_groups_js()
67 c.users_groups_array = repo_model.get_users_groups_js()
68
68
69 defaults = c.repo_info.get_dict()
69 defaults = c.repo_info.get_dict()
70
70
71 #fill owner
71 #fill owner
72 if c.repo_info.user:
72 if c.repo_info.user:
73 defaults.update({'user':c.repo_info.user.username})
73 defaults.update({'user':c.repo_info.user.username})
74 else:
74 else:
75 replacement_user = self.sa.query(User)\
75 replacement_user = self.sa.query(User)\
76 .filter(User.admin == True).first().username
76 .filter(User.admin == True).first().username
77 defaults.update({'user':replacement_user})
77 defaults.update({'user':replacement_user})
78
78
79 #fill repository users
79 #fill repository users
80 for p in c.repo_info.repo_to_perm:
80 for p in c.repo_info.repo_to_perm:
81 defaults.update({'u_perm_%s' % p.user.username:
81 defaults.update({'u_perm_%s' % p.user.username:
82 p.permission.permission_name})
82 p.permission.permission_name})
83
83
84 #fill repository groups
84 #fill repository groups
85 for p in c.repo_info.users_group_to_perm:
85 for p in c.repo_info.users_group_to_perm:
86 defaults.update({'g_perm_%s' % p.users_group.users_group_name:
86 defaults.update({'g_perm_%s' % p.users_group.users_group_name:
87 p.permission.permission_name})
87 p.permission.permission_name})
88
88
89 return formencode.htmlfill.render(
89 return formencode.htmlfill.render(
90 render('settings/repo_settings.html'),
90 render('settings/repo_settings.html'),
91 defaults=defaults,
91 defaults=defaults,
92 encoding="UTF-8",
92 encoding="UTF-8",
93 force_defaults=False
93 force_defaults=False
94 )
94 )
95
95
96 @HasRepoPermissionAllDecorator('repository.admin')
96 def update(self, repo_name):
97 def update(self, repo_name):
97 repo_model = RepoModel()
98 repo_model = RepoModel()
98 changed_name = repo_name
99 changed_name = repo_name
99 _form = RepoSettingsForm(edit=True, old_data={'repo_name':repo_name})()
100 _form = RepoSettingsForm(edit=True, old_data={'repo_name':repo_name})()
100 try:
101 try:
101 form_result = _form.to_python(dict(request.POST))
102 form_result = _form.to_python(dict(request.POST))
102 repo_model.update(repo_name, form_result)
103 repo_model.update(repo_name, form_result)
103 invalidate_cache('get_repo_cached_%s' % repo_name)
104 invalidate_cache('get_repo_cached_%s' % repo_name)
104 h.flash(_('Repository %s updated successfully' % repo_name),
105 h.flash(_('Repository %s updated successfully' % repo_name),
105 category='success')
106 category='success')
106 changed_name = form_result['repo_name']
107 changed_name = form_result['repo_name']
107 action_logger(self.rhodecode_user, 'user_updated_repo',
108 action_logger(self.rhodecode_user, 'user_updated_repo',
108 changed_name, '', self.sa)
109 changed_name, '', self.sa)
109 except formencode.Invalid, errors:
110 except formencode.Invalid, errors:
110 c.repo_info = repo_model.get_by_repo_name(repo_name)
111 c.repo_info = repo_model.get_by_repo_name(repo_name)
111 c.users_array = repo_model.get_users_js()
112 c.users_array = repo_model.get_users_js()
112 errors.value.update({'user':c.repo_info.user.username})
113 errors.value.update({'user':c.repo_info.user.username})
113 return formencode.htmlfill.render(
114 return formencode.htmlfill.render(
114 render('settings/repo_settings.html'),
115 render('settings/repo_settings.html'),
115 defaults=errors.value,
116 defaults=errors.value,
116 errors=errors.error_dict or {},
117 errors=errors.error_dict or {},
117 prefix_error=False,
118 prefix_error=False,
118 encoding="UTF-8")
119 encoding="UTF-8")
119 except Exception:
120 except Exception:
120 log.error(traceback.format_exc())
121 log.error(traceback.format_exc())
121 h.flash(_('error occurred during update of repository %s') \
122 h.flash(_('error occurred during update of repository %s') \
122 % repo_name, category='error')
123 % repo_name, category='error')
123
124
124 return redirect(url('repo_settings_home', repo_name=changed_name))
125 return redirect(url('repo_settings_home', repo_name=changed_name))
125
126
126
127
127
128 @HasRepoPermissionAllDecorator('repository.admin')
128 def delete(self, repo_name):
129 def delete(self, repo_name):
129 """DELETE /repos/repo_name: Delete an existing item"""
130 """DELETE /repos/repo_name: Delete an existing item"""
130 # Forms posted to this method should contain a hidden field:
131 # Forms posted to this method should contain a hidden field:
131 # <input type="hidden" name="_method" value="DELETE" />
132 # <input type="hidden" name="_method" value="DELETE" />
132 # Or using helpers:
133 # Or using helpers:
133 # h.form(url('repo_settings_delete', repo_name=ID),
134 # h.form(url('repo_settings_delete', repo_name=ID),
134 # method='delete')
135 # method='delete')
135 # url('repo_settings_delete', repo_name=ID)
136 # url('repo_settings_delete', repo_name=ID)
136
137
137 repo_model = RepoModel()
138 repo_model = RepoModel()
138 repo = repo_model.get_by_repo_name(repo_name)
139 repo = repo_model.get_by_repo_name(repo_name)
139 if not repo:
140 if not repo:
140 h.flash(_('%s repository is not mapped to db perhaps'
141 h.flash(_('%s repository is not mapped to db perhaps'
141 ' it was moved or renamed from the filesystem'
142 ' it was moved or renamed from the filesystem'
142 ' please run the application again'
143 ' please run the application again'
143 ' in order to rescan repositories') % repo_name,
144 ' in order to rescan repositories') % repo_name,
144 category='error')
145 category='error')
145
146
146 return redirect(url('home'))
147 return redirect(url('home'))
147 try:
148 try:
148 action_logger(self.rhodecode_user, 'user_deleted_repo',
149 action_logger(self.rhodecode_user, 'user_deleted_repo',
149 repo_name, '', self.sa)
150 repo_name, '', self.sa)
150 repo_model.delete(repo)
151 repo_model.delete(repo)
151 invalidate_cache('get_repo_cached_%s' % repo_name)
152 invalidate_cache('get_repo_cached_%s' % repo_name)
152 h.flash(_('deleted repository %s') % repo_name, category='success')
153 h.flash(_('deleted repository %s') % repo_name, category='success')
153 except Exception:
154 except Exception:
154 h.flash(_('An error occurred during deletion of %s') % repo_name,
155 h.flash(_('An error occurred during deletion of %s') % repo_name,
155 category='error')
156 category='error')
156
157
157 return redirect(url('home'))
158 return redirect(url('home'))
158
159
160 @HasRepoPermissionAllDecorator('repository.read')
159 def fork(self, repo_name):
161 def fork(self, repo_name):
160 repo_model = RepoModel()
162 repo_model = RepoModel()
161 c.repo_info = repo = repo_model.get_by_repo_name(repo_name)
163 c.repo_info = repo = repo_model.get_by_repo_name(repo_name)
162 if not repo:
164 if not repo:
163 h.flash(_('%s repository is not mapped to db perhaps'
165 h.flash(_('%s repository is not mapped to db perhaps'
164 ' it was created or renamed from the file system'
166 ' it was created or renamed from the file system'
165 ' please run the application again'
167 ' please run the application again'
166 ' in order to rescan repositories') % repo_name,
168 ' in order to rescan repositories') % repo_name,
167 category='error')
169 category='error')
168
170
169 return redirect(url('home'))
171 return redirect(url('home'))
170
172
171 return render('settings/repo_fork.html')
173 return render('settings/repo_fork.html')
172
174
173
175
174
176 @HasRepoPermissionAllDecorator('repository.read')
175 def fork_create(self, repo_name):
177 def fork_create(self, repo_name):
176 repo_model = RepoModel()
178 repo_model = RepoModel()
177 c.repo_info = repo_model.get_by_repo_name(repo_name)
179 c.repo_info = repo_model.get_by_repo_name(repo_name)
178 _form = RepoForkForm(old_data={'repo_type':c.repo_info.repo_type})()
180 _form = RepoForkForm(old_data={'repo_type':c.repo_info.repo_type})()
179 form_result = {}
181 form_result = {}
180 try:
182 try:
181 form_result = _form.to_python(dict(request.POST))
183 form_result = _form.to_python(dict(request.POST))
182 form_result.update({'repo_name':repo_name})
184 form_result.update({'repo_name':repo_name})
183 repo_model.create_fork(form_result, c.rhodecode_user)
185 repo_model.create_fork(form_result, c.rhodecode_user)
184 h.flash(_('forked %s repository as %s') \
186 h.flash(_('forked %s repository as %s') \
185 % (repo_name, form_result['fork_name']),
187 % (repo_name, form_result['fork_name']),
186 category='success')
188 category='success')
187 action_logger(self.rhodecode_user,
189 action_logger(self.rhodecode_user,
188 'user_forked_repo:%s' % form_result['fork_name'],
190 'user_forked_repo:%s' % form_result['fork_name'],
189 repo_name, '', self.sa)
191 repo_name, '', self.sa)
190 except formencode.Invalid, errors:
192 except formencode.Invalid, errors:
191 c.new_repo = errors.value['fork_name']
193 c.new_repo = errors.value['fork_name']
192 r = render('settings/repo_fork.html')
194 r = render('settings/repo_fork.html')
193
195
194 return formencode.htmlfill.render(
196 return formencode.htmlfill.render(
195 r,
197 r,
196 defaults=errors.value,
198 defaults=errors.value,
197 errors=errors.error_dict or {},
199 errors=errors.error_dict or {},
198 prefix_error=False,
200 prefix_error=False,
199 encoding="UTF-8")
201 encoding="UTF-8")
200 return redirect(url('home'))
202 return redirect(url('home'))
@@ -1,392 +1,392
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" id="mainhtml">
3 <html xmlns="http://www.w3.org/1999/xhtml" id="mainhtml">
4 <head>
4 <head>
5 <title>${next.title()}</title>
5 <title>${next.title()}</title>
6 <link rel="icon" href="${h.url('/images/icons/database_gear.png')}" type="image/png" />
6 <link rel="icon" href="${h.url('/images/icons/database_gear.png')}" type="image/png" />
7 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
7 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
8 <meta name="robots" content="index, nofollow"/>
8 <meta name="robots" content="index, nofollow"/>
9 <!-- stylesheets -->
9 <!-- stylesheets -->
10 ${self.css()}
10 ${self.css()}
11 <!-- scripts -->
11 <!-- scripts -->
12 ${self.js()}
12 ${self.js()}
13 %if c.ga_code:
13 %if c.ga_code:
14 <script type="text/javascript">
14 <script type="text/javascript">
15
15
16 var _gaq = _gaq || [];
16 var _gaq = _gaq || [];
17 _gaq.push(['_setAccount', '${c.ga_code}']);
17 _gaq.push(['_setAccount', '${c.ga_code}']);
18 _gaq.push(['_trackPageview']);
18 _gaq.push(['_trackPageview']);
19
19
20 (function() {
20 (function() {
21 var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
21 var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
22 ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
22 ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
23 var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
23 var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
24 })();
24 })();
25
25
26
26
27 </script>
27 </script>
28 %endif
28 %endif
29 </head>
29 </head>
30 <body>
30 <body>
31 <!-- header -->
31 <!-- header -->
32 <div id="header">
32 <div id="header">
33 <!-- user -->
33 <!-- user -->
34 <ul id="logged-user">
34 <ul id="logged-user">
35 <li class="first">
35 <li class="first">
36 <div class="gravatar">
36 <div class="gravatar">
37 <img alt="gravatar" src="${h.gravatar_url(c.rhodecode_user.email,20)}" />
37 <img alt="gravatar" src="${h.gravatar_url(c.rhodecode_user.email,20)}" />
38 </div>
38 </div>
39 <div class="account">
39 <div class="account">
40 %if c.rhodecode_user.username == 'default':
40 %if c.rhodecode_user.username == 'default':
41 %if h.HasPermissionAny('hg.admin', 'hg.register.auto_activate', 'hg.register.manual_activate')():
41 %if h.HasPermissionAny('hg.admin', 'hg.register.auto_activate', 'hg.register.manual_activate')():
42 ${h.link_to('anonymous',h.url('register'),title='%s %s'%(c.rhodecode_user.name,c.rhodecode_user.lastname))}
42 ${h.link_to('anonymous',h.url('register'),title='%s %s'%(c.rhodecode_user.name,c.rhodecode_user.lastname))}
43 %else:
43 %else:
44 ${h.link_to('anonymous',h.url('#'),title='%s %s'%(c.rhodecode_user.name,c.rhodecode_user.lastname))}
44 ${h.link_to('anonymous',h.url('#'),title='%s %s'%(c.rhodecode_user.name,c.rhodecode_user.lastname))}
45 %endif
45 %endif
46
46
47 %else:
47 %else:
48 ${h.link_to(c.rhodecode_user.username,h.url('admin_settings_my_account'),title='%s %s'%(c.rhodecode_user.name,c.rhodecode_user.lastname))}
48 ${h.link_to(c.rhodecode_user.username,h.url('admin_settings_my_account'),title='%s %s'%(c.rhodecode_user.name,c.rhodecode_user.lastname))}
49 %endif
49 %endif
50 </div>
50 </div>
51 </li>
51 </li>
52 <li>
52 <li>
53 <a href="${h.url('home')}">${_('Home')}</a>
53 <a href="${h.url('home')}">${_('Home')}</a>
54 </li>
54 </li>
55 %if c.rhodecode_user.username != 'default':
55 %if c.rhodecode_user.username != 'default':
56 <li>
56 <li>
57 <a href="${h.url('journal')}">${_('Journal')}</a>
57 <a href="${h.url('journal')}">${_('Journal')}</a>
58 ##(${c.unread_journal})</a>
58 ##(${c.unread_journal})</a>
59 </li>
59 </li>
60 %endif
60 %endif
61 %if c.rhodecode_user.username == 'default':
61 %if c.rhodecode_user.username == 'default':
62 <li class="last highlight">${h.link_to(u'Login',h.url('login_home'))}</li>
62 <li class="last highlight">${h.link_to(u'Login',h.url('login_home'))}</li>
63 %else:
63 %else:
64 <li class="last highlight">${h.link_to(u'Log Out',h.url('logout_home'))}</li>
64 <li class="last highlight">${h.link_to(u'Log Out',h.url('logout_home'))}</li>
65 %endif
65 %endif
66 </ul>
66 </ul>
67 <!-- end user -->
67 <!-- end user -->
68 <div id="header-inner" class="title top-left-rounded-corner top-right-rounded-corner">
68 <div id="header-inner" class="title top-left-rounded-corner top-right-rounded-corner">
69 <!-- logo -->
69 <!-- logo -->
70 <div id="logo">
70 <div id="logo">
71 <h1><a href="${h.url('home')}">${c.rhodecode_name}</a></h1>
71 <h1><a href="${h.url('home')}">${c.rhodecode_name}</a></h1>
72 </div>
72 </div>
73 <!-- end logo -->
73 <!-- end logo -->
74 <!-- menu -->
74 <!-- menu -->
75 ${self.page_nav()}
75 ${self.page_nav()}
76 <!-- quick -->
76 <!-- quick -->
77 </div>
77 </div>
78 </div>
78 </div>
79 <!-- end header -->
79 <!-- end header -->
80
80
81 <!-- CONTENT -->
81 <!-- CONTENT -->
82 <div id="content">
82 <div id="content">
83 <div class="flash_msg">
83 <div class="flash_msg">
84 <% messages = h.flash.pop_messages() %>
84 <% messages = h.flash.pop_messages() %>
85 % if messages:
85 % if messages:
86 <ul id="flash-messages">
86 <ul id="flash-messages">
87 % for message in messages:
87 % for message in messages:
88 <li class="${message.category}_msg">${message}</li>
88 <li class="${message.category}_msg">${message}</li>
89 % endfor
89 % endfor
90 </ul>
90 </ul>
91 % endif
91 % endif
92 </div>
92 </div>
93 <div id="main">
93 <div id="main">
94 ${next.main()}
94 ${next.main()}
95 </div>
95 </div>
96 </div>
96 </div>
97 <!-- END CONTENT -->
97 <!-- END CONTENT -->
98
98
99 <!-- footer -->
99 <!-- footer -->
100 <div id="footer">
100 <div id="footer">
101 <div id="footer-inner" class="title bottom-left-rounded-corner bottom-right-rounded-corner">
101 <div id="footer-inner" class="title bottom-left-rounded-corner bottom-right-rounded-corner">
102 <div>
102 <div>
103 <p class="footer-link">${h.link_to(_('Submit a bug'),h.url('bugtracker'))}</p>
103 <p class="footer-link">${h.link_to(_('Submit a bug'),h.url('bugtracker'))}</p>
104 <p class="footer-link">${h.link_to(_('GPL license'),h.url('gpl_license'))}</p>
104 <p class="footer-link">${h.link_to(_('GPL license'),h.url('gpl_license'))}</p>
105 <p>RhodeCode ${c.rhodecode_version} &copy; 2010-2011 by Marcin Kuzminski</p>
105 <p>RhodeCode ${c.rhodecode_version} &copy; 2010-2011 by Marcin Kuzminski</p>
106 </div>
106 </div>
107 </div>
107 </div>
108 <script type="text/javascript">
108 <script type="text/javascript">
109 function tooltip_activate(){
109 function tooltip_activate(){
110 ${h.tooltip.activate()}
110 ${h.tooltip.activate()}
111 }
111 }
112 tooltip_activate();
112 tooltip_activate();
113 </script>
113 </script>
114 </div>
114 </div>
115 <!-- end footer -->
115 <!-- end footer -->
116 </body>
116 </body>
117
117
118 </html>
118 </html>
119
119
120 ### MAKO DEFS ###
120 ### MAKO DEFS ###
121 <%def name="page_nav()">
121 <%def name="page_nav()">
122 ${self.menu()}
122 ${self.menu()}
123 </%def>
123 </%def>
124
124
125 <%def name="menu(current=None)">
125 <%def name="menu(current=None)">
126 <%
126 <%
127 def is_current(selected):
127 def is_current(selected):
128 if selected == current:
128 if selected == current:
129 return h.literal('class="current"')
129 return h.literal('class="current"')
130 %>
130 %>
131 %if current not in ['home','admin']:
131 %if current not in ['home','admin']:
132 ##REGULAR MENU
132 ##REGULAR MENU
133 <ul id="quick">
133 <ul id="quick">
134 <!-- repo switcher -->
134 <!-- repo switcher -->
135 <li>
135 <li>
136 <a id="repo_switcher" title="${_('Switch repository')}" href="#">
136 <a id="repo_switcher" title="${_('Switch repository')}" href="#">
137 <span class="icon">
137 <span class="icon">
138 <img src="${h.url("/images/icons/database.png")}" alt="${_('Products')}" />
138 <img src="${h.url("/images/icons/database.png")}" alt="${_('Products')}" />
139 </span>
139 </span>
140 <span>&darr;</span>
140 <span>&darr;</span>
141 </a>
141 </a>
142 <ul class="repo_switcher">
142 <ul class="repo_switcher">
143 %for repo in c.cached_repo_list:
143 %for repo in c.cached_repo_list:
144
144
145 %if repo['dbrepo']['private']:
145 %if repo['dbrepo']['private']:
146 <li><img src="${h.url("/images/icons/lock.png")}" alt="${_('Private repository')}" class="repo_switcher_type"/>${h.link_to(repo['repo'].name,h.url('summary_home',repo_name=repo['repo'].name),class_="%s" % repo['dbrepo']['repo_type'])}</li>
146 <li><img src="${h.url("/images/icons/lock.png")}" alt="${_('Private repository')}" class="repo_switcher_type"/>${h.link_to(repo['repo'].name,h.url('summary_home',repo_name=repo['repo'].name),class_="%s" % repo['dbrepo']['repo_type'])}</li>
147 %else:
147 %else:
148 <li><img src="${h.url("/images/icons/lock_open.png")}" alt="${_('Public repository')}" class="repo_switcher_type" />${h.link_to(repo['repo'].name,h.url('summary_home',repo_name=repo['repo'].name),class_="%s" % repo['dbrepo']['repo_type'])}</li>
148 <li><img src="${h.url("/images/icons/lock_open.png")}" alt="${_('Public repository')}" class="repo_switcher_type" />${h.link_to(repo['repo'].name,h.url('summary_home',repo_name=repo['repo'].name),class_="%s" % repo['dbrepo']['repo_type'])}</li>
149 %endif
149 %endif
150 %endfor
150 %endfor
151 </ul>
151 </ul>
152 </li>
152 </li>
153
153
154 <li ${is_current('summary')}>
154 <li ${is_current('summary')}>
155 <a title="${_('Summary')}" href="${h.url('summary_home',repo_name=c.repo_name)}">
155 <a title="${_('Summary')}" href="${h.url('summary_home',repo_name=c.repo_name)}">
156 <span class="icon">
156 <span class="icon">
157 <img src="${h.url("/images/icons/clipboard_16.png")}" alt="${_('Summary')}" />
157 <img src="${h.url("/images/icons/clipboard_16.png")}" alt="${_('Summary')}" />
158 </span>
158 </span>
159 <span>${_('Summary')}</span>
159 <span>${_('Summary')}</span>
160 </a>
160 </a>
161 </li>
161 </li>
162 ##<li ${is_current('shortlog')}>
162 ##<li ${is_current('shortlog')}>
163 ## <a title="${_('Shortlog')}" href="${h.url('shortlog_home',repo_name=c.repo_name)}">
163 ## <a title="${_('Shortlog')}" href="${h.url('shortlog_home',repo_name=c.repo_name)}">
164 ## <span class="icon">
164 ## <span class="icon">
165 ## <img src="${h.url("/images/icons/application_view_list.png")}" alt="${_('Shortlog')}" />
165 ## <img src="${h.url("/images/icons/application_view_list.png")}" alt="${_('Shortlog')}" />
166 ## </span>
166 ## </span>
167 ## <span>${_('Shortlog')}</span>
167 ## <span>${_('Shortlog')}</span>
168 ## </a>
168 ## </a>
169 ##</li>
169 ##</li>
170 <li ${is_current('changelog')}>
170 <li ${is_current('changelog')}>
171 <a title="${_('Changelog')}" href="${h.url('changelog_home',repo_name=c.repo_name)}">
171 <a title="${_('Changelog')}" href="${h.url('changelog_home',repo_name=c.repo_name)}">
172 <span class="icon">
172 <span class="icon">
173 <img src="${h.url("/images/icons/time.png")}" alt="${_('Changelog')}" />
173 <img src="${h.url("/images/icons/time.png")}" alt="${_('Changelog')}" />
174 </span>
174 </span>
175 <span>${_('Changelog')}</span>
175 <span>${_('Changelog')}</span>
176 </a>
176 </a>
177 </li>
177 </li>
178
178
179 <li ${is_current('switch_to')}>
179 <li ${is_current('switch_to')}>
180 <a title="${_('Switch to')}" href="#">
180 <a title="${_('Switch to')}" href="#">
181 <span class="icon">
181 <span class="icon">
182 <img src="${h.url("/images/icons/arrow_switch.png")}" alt="${_('Switch to')}" />
182 <img src="${h.url("/images/icons/arrow_switch.png")}" alt="${_('Switch to')}" />
183 </span>
183 </span>
184 <span>${_('Switch to')}</span>
184 <span>${_('Switch to')}</span>
185 </a>
185 </a>
186 <ul>
186 <ul>
187 <li>
187 <li>
188 ${h.link_to('%s (%s)' % (_('branches'),len(c.rhodecode_repo.branches.values()),),h.url('branches_home',repo_name=c.repo_name),class_='branches childs')}
188 ${h.link_to('%s (%s)' % (_('branches'),len(c.rhodecode_repo.branches.values()),),h.url('branches_home',repo_name=c.repo_name),class_='branches childs')}
189 <ul>
189 <ul>
190 %if c.rhodecode_repo.branches.values():
190 %if c.rhodecode_repo.branches.values():
191 %for cnt,branch in enumerate(c.rhodecode_repo.branches.items()):
191 %for cnt,branch in enumerate(c.rhodecode_repo.branches.items()):
192 <li>${h.link_to('%s - %s' % (branch[0],h.short_id(branch[1])),h.url('files_home',repo_name=c.repo_name,revision=branch[1]))}</li>
192 <li>${h.link_to('%s - %s' % (branch[0],h.short_id(branch[1])),h.url('files_home',repo_name=c.repo_name,revision=branch[1]))}</li>
193 %endfor
193 %endfor
194 %else:
194 %else:
195 <li>${h.link_to(_('There are no branches yet'),'#')}</li>
195 <li>${h.link_to(_('There are no branches yet'),'#')}</li>
196 %endif
196 %endif
197 </ul>
197 </ul>
198 </li>
198 </li>
199 <li>
199 <li>
200 ${h.link_to('%s (%s)' % (_('tags'),len(c.rhodecode_repo.tags.values()),),h.url('tags_home',repo_name=c.repo_name),class_='tags childs')}
200 ${h.link_to('%s (%s)' % (_('tags'),len(c.rhodecode_repo.tags.values()),),h.url('tags_home',repo_name=c.repo_name),class_='tags childs')}
201 <ul>
201 <ul>
202 %if c.rhodecode_repo.tags.values():
202 %if c.rhodecode_repo.tags.values():
203 %for cnt,tag in enumerate(c.rhodecode_repo.tags.items()):
203 %for cnt,tag in enumerate(c.rhodecode_repo.tags.items()):
204 <li>${h.link_to('%s - %s' % (tag[0],h.short_id(tag[1])),h.url('files_home',repo_name=c.repo_name,revision=tag[1]))}</li>
204 <li>${h.link_to('%s - %s' % (tag[0],h.short_id(tag[1])),h.url('files_home',repo_name=c.repo_name,revision=tag[1]))}</li>
205 %endfor
205 %endfor
206 %else:
206 %else:
207 <li>${h.link_to(_('There are no tags yet'),'#')}</li>
207 <li>${h.link_to(_('There are no tags yet'),'#')}</li>
208 %endif
208 %endif
209 </ul>
209 </ul>
210 </li>
210 </li>
211 </ul>
211 </ul>
212 </li>
212 </li>
213 <li ${is_current('files')}>
213 <li ${is_current('files')}>
214 <a title="${_('Files')}" href="${h.url('files_home',repo_name=c.repo_name)}">
214 <a title="${_('Files')}" href="${h.url('files_home',repo_name=c.repo_name)}">
215 <span class="icon">
215 <span class="icon">
216 <img src="${h.url("/images/icons/file.png")}" alt="${_('Files')}" />
216 <img src="${h.url("/images/icons/file.png")}" alt="${_('Files')}" />
217 </span>
217 </span>
218 <span>${_('Files')}</span>
218 <span>${_('Files')}</span>
219 </a>
219 </a>
220 </li>
220 </li>
221
221
222 <li ${is_current('options')}>
222 <li ${is_current('options')}>
223 <a title="${_('Options')}" href="#">
223 <a title="${_('Options')}" href="#">
224 <span class="icon">
224 <span class="icon">
225 <img src="${h.url("/images/icons/table_gear.png")}" alt="${_('Admin')}" />
225 <img src="${h.url("/images/icons/table_gear.png")}" alt="${_('Admin')}" />
226 </span>
226 </span>
227 <span>${_('Options')}</span>
227 <span>${_('Options')}</span>
228 </a>
228 </a>
229 <ul>
229 <ul>
230 %if h.HasRepoPermissionAll('repository.admin')(c.repo_name):
230 %if h.HasRepoPermissionAll('repository.admin')(c.repo_name):
231 %if h.HasPermissionAll('hg.admin')('access settings on repository'):
231 %if h.HasPermissionAll('hg.admin')('access settings on repository'):
232 <li>${h.link_to(_('settings'),h.url('edit_repo',repo_name=c.repo_name),class_='settings')}</li>
232 <li>${h.link_to(_('settings'),h.url('edit_repo',repo_name=c.repo_name),class_='settings')}</li>
233 %else:
233 %else:
234 <li>${h.link_to(_('settings'),h.url('repo_settings_home',repo_name=c.repo_name),class_='settings')}</li>
234 <li>${h.link_to(_('settings'),h.url('repo_settings_home',repo_name=c.repo_name),class_='settings')}</li>
235 %endif
235 %endif
236 %endif
236 <li>${h.link_to(_('fork'),h.url('repo_fork_home',repo_name=c.repo_name),class_='fork')}</li>
237 <li>${h.link_to(_('fork'),h.url('repo_fork_home',repo_name=c.repo_name),class_='fork')}</li>
237 %endif
238 <li>${h.link_to(_('search'),h.url('search_repo',search_repo=c.repo_name),class_='search')}</li>
238 <li>${h.link_to(_('search'),h.url('search_repo',search_repo=c.repo_name),class_='search')}</li>
239
239
240 %if h.HasPermissionAll('hg.admin')('access admin main page'):
240 %if h.HasPermissionAll('hg.admin')('access admin main page'):
241 <li>
241 <li>
242 ${h.link_to(_('admin'),h.url('admin_home'),class_='admin')}
242 ${h.link_to(_('admin'),h.url('admin_home'),class_='admin')}
243 <%def name="admin_menu()">
243 <%def name="admin_menu()">
244 <ul>
244 <ul>
245 <li>${h.link_to(_('journal'),h.url('admin_home'),class_='journal')}</li>
245 <li>${h.link_to(_('journal'),h.url('admin_home'),class_='journal')}</li>
246 <li>${h.link_to(_('repositories'),h.url('repos'),class_='repos')}</li>
246 <li>${h.link_to(_('repositories'),h.url('repos'),class_='repos')}</li>
247 <li>${h.link_to(_('users'),h.url('users'),class_='users')}</li>
247 <li>${h.link_to(_('users'),h.url('users'),class_='users')}</li>
248 <li>${h.link_to(_('users groups'),h.url('users_groups'),class_='groups')}</li>
248 <li>${h.link_to(_('users groups'),h.url('users_groups'),class_='groups')}</li>
249 <li>${h.link_to(_('permissions'),h.url('edit_permission',id='default'),class_='permissions')}</li>
249 <li>${h.link_to(_('permissions'),h.url('edit_permission',id='default'),class_='permissions')}</li>
250 <li>${h.link_to(_('ldap'),h.url('ldap_home'),class_='ldap')}</li>
250 <li>${h.link_to(_('ldap'),h.url('ldap_home'),class_='ldap')}</li>
251 <li class="last">${h.link_to(_('settings'),h.url('admin_settings'),class_='settings')}</li>
251 <li class="last">${h.link_to(_('settings'),h.url('admin_settings'),class_='settings')}</li>
252 </ul>
252 </ul>
253 </%def>
253 </%def>
254
254
255 ${admin_menu()}
255 ${admin_menu()}
256 </li>
256 </li>
257 %endif
257 %endif
258
258
259 </ul>
259 </ul>
260 </li>
260 </li>
261
261
262 <li>
262 <li>
263 <a title="${_('Followers')}" href="#">
263 <a title="${_('Followers')}" href="#">
264 <span class="icon_short">
264 <span class="icon_short">
265 <img src="${h.url("/images/icons/heart.png")}" alt="${_('Followers')}" />
265 <img src="${h.url("/images/icons/heart.png")}" alt="${_('Followers')}" />
266 </span>
266 </span>
267 <span class="short">${c.repository_followers}</span>
267 <span class="short">${c.repository_followers}</span>
268 </a>
268 </a>
269 </li>
269 </li>
270 <li>
270 <li>
271 <a title="${_('Forks')}" href="#">
271 <a title="${_('Forks')}" href="#">
272 <span class="icon_short">
272 <span class="icon_short">
273 <img src="${h.url("/images/icons/arrow_divide.png")}" alt="${_('Forks')}" />
273 <img src="${h.url("/images/icons/arrow_divide.png")}" alt="${_('Forks')}" />
274 </span>
274 </span>
275 <span class="short">${c.repository_forks}</span>
275 <span class="short">${c.repository_forks}</span>
276 </a>
276 </a>
277 </li>
277 </li>
278
278
279
279
280
280
281 </ul>
281 </ul>
282 %else:
282 %else:
283 ##ROOT MENU
283 ##ROOT MENU
284 <ul id="quick">
284 <ul id="quick">
285 <li>
285 <li>
286 <a title="${_('Home')}" href="${h.url('home')}">
286 <a title="${_('Home')}" href="${h.url('home')}">
287 <span class="icon">
287 <span class="icon">
288 <img src="${h.url("/images/icons/home_16.png")}" alt="${_('Home')}" />
288 <img src="${h.url("/images/icons/home_16.png")}" alt="${_('Home')}" />
289 </span>
289 </span>
290 <span>${_('Home')}</span>
290 <span>${_('Home')}</span>
291 </a>
291 </a>
292 </li>
292 </li>
293 %if c.rhodecode_user.username != 'default':
293 %if c.rhodecode_user.username != 'default':
294 <li>
294 <li>
295 <a title="${_('Journal')}" href="${h.url('journal')}">
295 <a title="${_('Journal')}" href="${h.url('journal')}">
296 <span class="icon">
296 <span class="icon">
297 <img src="${h.url("/images/icons/book.png")}" alt="${_('Journal')}" />
297 <img src="${h.url("/images/icons/book.png")}" alt="${_('Journal')}" />
298 </span>
298 </span>
299 <span>${_('Journal')}</span>
299 <span>${_('Journal')}</span>
300 </a>
300 </a>
301 </li>
301 </li>
302 %endif
302 %endif
303 <li>
303 <li>
304 <a title="${_('Search')}" href="${h.url('search')}">
304 <a title="${_('Search')}" href="${h.url('search')}">
305 <span class="icon">
305 <span class="icon">
306 <img src="${h.url("/images/icons/search_16.png")}" alt="${_('Search')}" />
306 <img src="${h.url("/images/icons/search_16.png")}" alt="${_('Search')}" />
307 </span>
307 </span>
308 <span>${_('Search')}</span>
308 <span>${_('Search')}</span>
309 </a>
309 </a>
310 </li>
310 </li>
311
311
312 %if h.HasPermissionAll('hg.admin')('access admin main page'):
312 %if h.HasPermissionAll('hg.admin')('access admin main page'):
313 <li ${is_current('admin')}>
313 <li ${is_current('admin')}>
314 <a title="${_('Admin')}" href="${h.url('admin_home')}">
314 <a title="${_('Admin')}" href="${h.url('admin_home')}">
315 <span class="icon">
315 <span class="icon">
316 <img src="${h.url("/images/icons/cog_edit.png")}" alt="${_('Admin')}" />
316 <img src="${h.url("/images/icons/cog_edit.png")}" alt="${_('Admin')}" />
317 </span>
317 </span>
318 <span>${_('Admin')}</span>
318 <span>${_('Admin')}</span>
319 </a>
319 </a>
320 ${admin_menu()}
320 ${admin_menu()}
321 </li>
321 </li>
322 %endif
322 %endif
323 </ul>
323 </ul>
324 %endif
324 %endif
325 </%def>
325 </%def>
326
326
327
327
328 <%def name="css()">
328 <%def name="css()">
329 <link rel="stylesheet" type="text/css" href="${h.url('/css/style.css')}" media="screen" />
329 <link rel="stylesheet" type="text/css" href="${h.url('/css/style.css')}" media="screen" />
330 <link rel="stylesheet" type="text/css" href="${h.url('/css/pygments.css')}" />
330 <link rel="stylesheet" type="text/css" href="${h.url('/css/pygments.css')}" />
331 <link rel="stylesheet" type="text/css" href="${h.url('/css/diff.css')}" />
331 <link rel="stylesheet" type="text/css" href="${h.url('/css/diff.css')}" />
332 </%def>
332 </%def>
333
333
334 <%def name="js()">
334 <%def name="js()">
335 ##<script type="text/javascript" src="${h.url('/js/yui/utilities/utilities.js')}"></script>
335 ##<script type="text/javascript" src="${h.url('/js/yui/utilities/utilities.js')}"></script>
336 ##<script type="text/javascript" src="${h.url('/js/yui/container/container.js')}"></script>
336 ##<script type="text/javascript" src="${h.url('/js/yui/container/container.js')}"></script>
337 ##<script type="text/javascript" src="${h.url('/js/yui/datasource/datasource.js')}"></script>
337 ##<script type="text/javascript" src="${h.url('/js/yui/datasource/datasource.js')}"></script>
338 ##<script type="text/javascript" src="${h.url('/js/yui/autocomplete/autocomplete.js')}"></script>
338 ##<script type="text/javascript" src="${h.url('/js/yui/autocomplete/autocomplete.js')}"></script>
339 ##<script type="text/javascript" src="${h.url('/js/yui/selector/selector-min.js')}"></script>
339 ##<script type="text/javascript" src="${h.url('/js/yui/selector/selector-min.js')}"></script>
340
340
341 <script type="text/javascript" src="${h.url('/js/yui2a.js')}"></script>
341 <script type="text/javascript" src="${h.url('/js/yui2a.js')}"></script>
342 <!--[if IE]><script language="javascript" type="text/javascript" src="${h.url('/js/excanvas.min.js')}"></script><![endif]-->
342 <!--[if IE]><script language="javascript" type="text/javascript" src="${h.url('/js/excanvas.min.js')}"></script><![endif]-->
343 <script type="text/javascript" src="${h.url('/js/yui.flot.js')}"></script>
343 <script type="text/javascript" src="${h.url('/js/yui.flot.js')}"></script>
344
344
345 <script type="text/javascript">
345 <script type="text/javascript">
346 var base_url = "${h.url('toggle_following')}";
346 var base_url = "${h.url('toggle_following')}";
347 var YUC = YAHOO.util.Connect;
347 var YUC = YAHOO.util.Connect;
348 var YUD = YAHOO.util.Dom;
348 var YUD = YAHOO.util.Dom;
349 var YUE = YAHOO.util.Event;
349 var YUE = YAHOO.util.Event;
350
350
351 function onSuccess(target){
351 function onSuccess(target){
352
352
353 var f = YUD.get(target.id);
353 var f = YUD.get(target.id);
354 if(f.getAttribute('class')=='follow'){
354 if(f.getAttribute('class')=='follow'){
355 f.setAttribute('class','following');
355 f.setAttribute('class','following');
356 f.setAttribute('title',"${_('Stop following this repository')}");
356 f.setAttribute('title',"${_('Stop following this repository')}");
357 }
357 }
358 else{
358 else{
359 f.setAttribute('class','follow');
359 f.setAttribute('class','follow');
360 f.setAttribute('title',"${_('Start following this repository')}");
360 f.setAttribute('title',"${_('Start following this repository')}");
361 }
361 }
362 }
362 }
363
363
364 function toggleFollowingUser(fallows_user_id,token){
364 function toggleFollowingUser(fallows_user_id,token){
365 args = 'follows_user_id='+fallows_user_id;
365 args = 'follows_user_id='+fallows_user_id;
366 args+= '&amp;auth_token='+token;
366 args+= '&amp;auth_token='+token;
367 YUC.asyncRequest('POST',base_url,{
367 YUC.asyncRequest('POST',base_url,{
368 success:function(o){
368 success:function(o){
369 onSuccess();
369 onSuccess();
370 }
370 }
371 },args); return false;
371 },args); return false;
372 }
372 }
373
373
374 function toggleFollowingRepo(target,fallows_repo_id,token){
374 function toggleFollowingRepo(target,fallows_repo_id,token){
375
375
376 args = 'follows_repo_id='+fallows_repo_id;
376 args = 'follows_repo_id='+fallows_repo_id;
377 args+= '&amp;auth_token='+token;
377 args+= '&amp;auth_token='+token;
378 YUC.asyncRequest('POST',base_url,{
378 YUC.asyncRequest('POST',base_url,{
379 success:function(o){
379 success:function(o){
380 onSuccess(target);
380 onSuccess(target);
381 }
381 }
382 },args); return false;
382 },args); return false;
383 }
383 }
384 </script>
384 </script>
385
385
386 </%def>
386 </%def>
387
387
388 <%def name="breadcrumbs()">
388 <%def name="breadcrumbs()">
389 <div class="breadcrumbs">
389 <div class="breadcrumbs">
390 ${self.breadcrumbs_links()}
390 ${self.breadcrumbs_links()}
391 </div>
391 </div>
392 </%def> No newline at end of file
392 </%def>
General Comments 0
You need to be logged in to leave comments. Login now