##// END OF EJS Templates
repos crud controllers - change id into repo_name for compatability, added ajax repo perm user function variuos html fixes, permissions forms and managment fixes....
marcink -
r299:d303aacb default
parent child Browse files
Show More
@@ -35,19 +35,22 b' def make_map(config):'
35 action="new", conditions=dict(method=["GET"]))
35 action="new", conditions=dict(method=["GET"]))
36 m.connect("formatted_new_repo", "/repos/new.{format}",
36 m.connect("formatted_new_repo", "/repos/new.{format}",
37 action="new", conditions=dict(method=["GET"]))
37 action="new", conditions=dict(method=["GET"]))
38 m.connect("/repos/{id:.*}",
38 m.connect("/repos/{repo_name:.*}",
39 action="update", conditions=dict(method=["PUT"]))
39 action="update", conditions=dict(method=["PUT"]))
40 m.connect("/repos/{id:.*}",
40 m.connect("/repos/{repo_name:.*}",
41 action="delete", conditions=dict(method=["DELETE"]))
41 action="delete", conditions=dict(method=["DELETE"]))
42 m.connect("edit_repo", "/repos/{id:.*}/edit",
42 m.connect("edit_repo", "/repos/{repo_name:.*}/edit",
43 action="edit", conditions=dict(method=["GET"]))
44 m.connect("formatted_edit_repo", "/repos/{repo_name:.*}.{format}/edit",
43 action="edit", conditions=dict(method=["GET"]))
45 action="edit", conditions=dict(method=["GET"]))
44 m.connect("formatted_edit_repo", "/repos/{id:.*}.{format}/edit",
46 m.connect("repo", "/repos/{repo_name:.*}",
45 action="edit", conditions=dict(method=["GET"]))
47 action="show", conditions=dict(method=["GET"]))
46 m.connect("repo", "/repos/{id:.*}",
48 m.connect("formatted_repo", "/repos/{repo_name:.*}.{format}",
47 action="show", conditions=dict(method=["GET"]))
49 action="show", conditions=dict(method=["GET"]))
48 m.connect("formatted_repo", "/repos/{id:.*}.{format}",
50 #ajax delete repo perm user
49 action="show", conditions=dict(method=["GET"]))
51 m.connect('delete_repo_user', "/repos_delete_user/{repo_name:.*}",
50
52 action="delete_perm_user", conditions=dict(method=["DELETE"]))
53
51 map.resource('user', 'users', path_prefix='/_admin')
54 map.resource('user', 'users', path_prefix='/_admin')
52 map.resource('permission', 'permissions', path_prefix='/_admin')
55 map.resource('permission', 'permissions', path_prefix='/_admin')
53
56
@@ -34,12 +34,9 b' from pylons_app.model.repo_model import '
34 from pylons_app.model.hg_model import HgModel
34 from pylons_app.model.hg_model import HgModel
35 from pylons_app.model.forms import RepoForm
35 from pylons_app.model.forms import RepoForm
36 from pylons_app.model.meta import Session
36 from pylons_app.model.meta import Session
37 from datetime import datetime
38 import formencode
37 import formencode
39 from formencode import htmlfill
38 from formencode import htmlfill
40 import logging
39 import logging
41 import os
42 import shutil
43 log = logging.getLogger(__name__)
40 log = logging.getLogger(__name__)
44
41
45 class ReposController(BaseController):
42 class ReposController(BaseController):
@@ -93,24 +90,24 b' class ReposController(BaseController):'
93
90
94 return render('admin/repos/repo_add.html')
91 return render('admin/repos/repo_add.html')
95
92
96 def update(self, id):
93 def update(self, repo_name):
97 """PUT /repos/id: Update an existing item"""
94 """PUT /repos/repo_name: Update an existing item"""
98 # Forms posted to this method should contain a hidden field:
95 # Forms posted to this method should contain a hidden field:
99 # <input type="hidden" name="_method" value="PUT" />
96 # <input type="hidden" name="_method" value="PUT" />
100 # Or using helpers:
97 # Or using helpers:
101 # h.form(url('repo', id=ID),
98 # h.form(url('repo', repo_name=ID),
102 # method='put')
99 # method='put')
103 # url('repo', id=ID)
100 # url('repo', repo_name=ID)
104 repo_model = RepoModel()
101 repo_model = RepoModel()
105 _form = RepoForm(edit=True)()
102 _form = RepoForm(edit=True)()
106 try:
103 try:
107 form_result = _form.to_python(dict(request.POST))
104 form_result = _form.to_python(dict(request.POST))
108 repo_model.update(id, form_result)
105 repo_model.update(repo_name, form_result)
109 invalidate_cache('cached_repo_list')
106 invalidate_cache('cached_repo_list')
110 h.flash(_('Repository %s updated succesfully' % id), category='success')
107 h.flash(_('Repository %s updated succesfully' % repo_name), category='success')
111
108
112 except formencode.Invalid as errors:
109 except formencode.Invalid as errors:
113 c.repo_info = repo_model.get(id)
110 c.repo_info = repo_model.get(repo_name)
114 c.users_array = repo_model.get_users_js()
111 c.users_array = repo_model.get_users_js()
115 errors.value.update({'user':c.repo_info.user.username})
112 errors.value.update({'user':c.repo_info.user.username})
116 c.form_errors = errors.error_dict
113 c.form_errors = errors.error_dict
@@ -123,59 +120,72 b' class ReposController(BaseController):'
123 % form_result['repo_name'], category='error')
120 % form_result['repo_name'], category='error')
124 return redirect(url('repos'))
121 return redirect(url('repos'))
125
122
126 def delete(self, id):
123 def delete(self, repo_name):
127 """DELETE /repos/id: Delete an existing item"""
124 """DELETE /repos/repo_name: Delete an existing item"""
128 # Forms posted to this method should contain a hidden field:
125 # Forms posted to this method should contain a hidden field:
129 # <input type="hidden" name="_method" value="DELETE" />
126 # <input type="hidden" name="_method" value="DELETE" />
130 # Or using helpers:
127 # Or using helpers:
131 # h.form(url('repo', id=ID),
128 # h.form(url('repo', repo_name=ID),
132 # method='delete')
129 # method='delete')
133 # url('repo', id=ID)
130 # url('repo', repo_name=ID)
134
131
135 repo_model = RepoModel()
132 repo_model = RepoModel()
136 repo = repo_model.get(id)
133 repo = repo_model.get(repo_name)
137 if not repo:
134 if not repo:
138 h.flash(_('%s repository is not mapped to db perhaps'
135 h.flash(_('%s repository is not mapped to db perhaps'
139 ' it was moved or renamed from the filesystem'
136 ' it was moved or renamed from the filesystem'
140 ' please run the application again'
137 ' please run the application again'
141 ' in order to rescan repositories') % id, category='error')
138 ' in order to rescan repositories') % repo_name, category='error')
142
139
143 return redirect(url('repos'))
140 return redirect(url('repos'))
144 try:
141 try:
145 repo_model.delete(repo)
142 repo_model.delete(repo)
146 invalidate_cache('cached_repo_list')
143 invalidate_cache('cached_repo_list')
147 h.flash(_('deleted repository %s') % id, category='success')
144 h.flash(_('deleted repository %s') % repo_name, category='success')
148 except Exception:
145 except Exception:
149 h.flash(_('An error occured during deletion of %s') % id,
146 h.flash(_('An error occured during deletion of %s') % repo_name,
150 category='error')
147 category='error')
151
148
152 return redirect(url('repos'))
149 return redirect(url('repos'))
153
150
154 def show(self, id, format='html'):
151 def delete_perm_user(self, repo_name):
155 """GET /repos/id: Show a specific item"""
152 """
156 # url('repo', id=ID)
153 DELETE an existing repository permission user
154 @param repo_name:
155 """
157
156
158 def edit(self, id, format='html'):
157 try:
159 """GET /repos/id/edit: Form to edit an existing item"""
158 repo_model = RepoModel()
160 # url('edit_repo', id=ID)
159 repo_model.delete_perm_user(request.POST, repo_name)
160 except Exception as e:
161 h.flash(_('An error occured during deletion of repository user'),
162 category='error')
163
164
165 def show(self, repo_name, format='html'):
166 """GET /repos/repo_name: Show a specific item"""
167 # url('repo', repo_name=ID)
168
169 def edit(self, repo_name, format='html'):
170 """GET /repos/repo_name/edit: Form to edit an existing item"""
171 # url('edit_repo', repo_name=ID)
161 repo_model = RepoModel()
172 repo_model = RepoModel()
162 c.repo_info = repo = repo_model.get(id)
173 c.repo_info = repo = repo_model.get(repo_name)
163 if not repo:
174 if not repo:
164 h.flash(_('%s repository is not mapped to db perhaps'
175 h.flash(_('%s repository is not mapped to db perhaps'
165 ' it was created or renamed from the filesystem'
176 ' it was created or renamed from the filesystem'
166 ' please run the application again'
177 ' please run the application again'
167 ' in order to rescan repositories') % id, category='error')
178 ' in order to rescan repositories') % repo_name, category='error')
168
179
169 return redirect(url('repos'))
180 return redirect(url('repos'))
170 defaults = c.repo_info.__dict__
181 defaults = c.repo_info.__dict__
171 defaults.update({'user':c.repo_info.user.username})
182 defaults.update({'user':c.repo_info.user.username})
172
173 c.users_array = repo_model.get_users_js()
183 c.users_array = repo_model.get_users_js()
174
184
175 for p in c.repo_info.repo2perm:
185 for p in c.repo_info.repo2perm:
176 defaults.update({'perm_%s' % p.user.username:
186 defaults.update({'perm_%s' % p.user.username:
177 p.permission.permission_name})
187 p.permission.permission_name})
178
188
179 return htmlfill.render(
189 return htmlfill.render(
180 render('admin/repos/repo_edit.html'),
190 render('admin/repos/repo_edit.html'),
181 defaults=defaults,
191 defaults=defaults,
@@ -27,7 +27,7 b' from functools import wraps'
27 from pylons import session, url, app_globals as g
27 from pylons import session, url, app_globals as g
28 from pylons.controllers.util import abort, redirect
28 from pylons.controllers.util import abort, redirect
29 from pylons_app.model import meta
29 from pylons_app.model import meta
30 from pylons_app.model.db import User
30 from pylons_app.model.db import User, Repo2Perm
31 from sqlalchemy.exc import OperationalError
31 from sqlalchemy.exc import OperationalError
32 from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
32 from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
33 import crypt
33 import crypt
@@ -91,7 +91,18 b' def set_available_permissions(config):'
91 all_perms = sa.query(Permission).all()
91 all_perms = sa.query(Permission).all()
92 config['pylons.app_globals'].available_permissions = [x.permission_name for x in all_perms]
92 config['pylons.app_globals'].available_permissions = [x.permission_name for x in all_perms]
93
93
94
94 def get_user(session):
95 """
96 Gets user from session, and wraps permissions into user
97 @param session:
98 """
99 user = session.get('hg_app_user', AuthUser())
100 if user.is_authenticated:
101 sa = meta.Session
102 user.permissions = sa.query(Repo2Perm)\
103 .filter(Repo2Perm.user_id == user.user_id).all()
104
105 return user
95
106
96 #===============================================================================
107 #===============================================================================
97 # DECORATORS
108 # DECORATORS
@@ -5,7 +5,7 b' Provides the BaseController class for su'
5 from pylons import config, tmpl_context as c, request, session
5 from pylons import config, tmpl_context as c, request, session
6 from pylons.controllers import WSGIController
6 from pylons.controllers import WSGIController
7 from pylons.templating import render_mako as render
7 from pylons.templating import render_mako as render
8 from pylons_app.lib.auth import LoginRequired, AuthUser
8 from pylons_app.lib import auth
9 from pylons_app.lib.utils import get_repo_slug
9 from pylons_app.lib.utils import get_repo_slug
10 from pylons_app.model import meta
10 from pylons_app.model import meta
11 from pylons_app.model.hg_model import _get_repos_cached
11 from pylons_app.model.hg_model import _get_repos_cached
@@ -17,7 +17,7 b' class BaseController(WSGIController):'
17 c.hg_app_version = __version__
17 c.hg_app_version = __version__
18 c.repos_prefix = config['hg_app_name']
18 c.repos_prefix = config['hg_app_name']
19 c.repo_name = get_repo_slug(request)
19 c.repo_name = get_repo_slug(request)
20 c.hg_app_user = session.get('hg_app_user', AuthUser())
20 c.hg_app_user = auth.get_user(session)
21 c.cached_repo_list = _get_repos_cached()
21 c.cached_repo_list = _get_repos_cached()
22 self.sa = meta.Session
22 self.sa = meta.Session
23
23
@@ -155,7 +155,6 b' class ValidPerms(formencode.validators.F'
155 perms_new = []
155 perms_new = []
156 #build a list of permission to update and new permission to create
156 #build a list of permission to update and new permission to create
157 for k, v in value.items():
157 for k, v in value.items():
158 print k, v
159 if k.startswith('perm_'):
158 if k.startswith('perm_'):
160 if k.startswith('perm_new_user'):
159 if k.startswith('perm_new_user'):
161 new_perm = value.get('perm_new_user', False)
160 new_perm = value.get('perm_new_user', False)
@@ -164,9 +163,12 b' class ValidPerms(formencode.validators.F'
164 if (new_user, new_perm) not in perms_new:
163 if (new_user, new_perm) not in perms_new:
165 perms_new.append((new_user, new_perm))
164 perms_new.append((new_user, new_perm))
166 else:
165 else:
167 perms_update.append((k[5:], v))
166 usr = k[5:]
168 #clear from form list
167 if usr == 'default':
169 #del value[k]
168 if value['private']:
169 #set none for default when updating to private repo
170 v = 'repository.none'
171 perms_update.append((usr, v))
170 value['perms_updates'] = perms_update
172 value['perms_updates'] = perms_update
171 value['perms_new'] = perms_new
173 value['perms_new'] = perms_new
172 sa = meta.Session
174 sa = meta.Session
@@ -104,8 +104,10 b' class RepoModel(object):'
104
104
105 #create default permission
105 #create default permission
106 repo2perm = Repo2Perm()
106 repo2perm = Repo2Perm()
107 default_perm = 'repository.none' if form_data['private'] \
108 else 'repository.read'
107 repo2perm.permission_id = self.sa.query(Permission)\
109 repo2perm.permission_id = self.sa.query(Permission)\
108 .filter(Permission.permission_name == 'repository.read')\
110 .filter(Permission.permission_name == default_perm)\
109 .one().permission_id
111 .one().permission_id
110
112
111 repo2perm.repository = repo_name
113 repo2perm.repository = repo_name
@@ -130,7 +132,16 b' class RepoModel(object):'
130 log.error(traceback.format_exc())
132 log.error(traceback.format_exc())
131 self.sa.rollback()
133 self.sa.rollback()
132 raise
134 raise
133
135 def delete_perm_user(self, form_data, repo_name):
136 try:
137 r2p = self.sa.query(Repo2Perm).filter(Repo2Perm.repository == repo_name)\
138 .filter(Repo2Perm.user_id == form_data['user_id']).delete()
139 self.sa.commit()
140 except:
141 log.error(traceback.format_exc())
142 self.sa.rollback()
143 raise
144
134 def __create_repo(self, repo_name):
145 def __create_repo(self, repo_name):
135 repo_path = os.path.join(g.base_path, repo_name)
146 repo_path = os.path.join(g.base_path, repo_name)
136 if check_repo(repo_name, g.base_path):
147 if check_repo(repo_name, g.base_path):
@@ -30,7 +30,7 b''
30 </tr>
30 </tr>
31 <tr>
31 <tr>
32 <td>${_('Private')}</td>
32 <td>${_('Private')}</td>
33 <td>${h.checkbox('private')}</td>
33 <td>${h.checkbox('private',value="True")}</td>
34 <td>${self.get_form_error('private')}</td>
34 <td>${self.get_form_error('private')}</td>
35 </tr>
35 </tr>
36 <tr>
36 <tr>
@@ -15,22 +15,22 b''
15 </%def>
15 </%def>
16 <%def name="main()">
16 <%def name="main()">
17 <div>
17 <div>
18 <h2>${_('Repositories')} - ${_('edit')}</h2>
18 <h2>${_('Repositories')} - ${_('edit')} "${c.repo_name}"</h2>
19 ${h.form(url('repo', id=c.repo_info.repo_name),method='put')}
19 ${h.form(url('repo', repo_name=c.repo_info.repo_name),method='put')}
20 <table>
20 <table>
21 <tr>
21 <tr>
22 <td>${_('Name')}</td>
22 <td>${_('Name')}</td>
23 <td>${h.text('repo_name')}</td>
23 <td>${h.text('repo_name',size="28")}</td>
24 <td>${self.get_form_error('repo_name')}</td>
24 <td>${self.get_form_error('repo_name')}</td>
25 </tr>
25 </tr>
26 <tr>
26 <tr>
27 <td>${_('Description')}</td>
27 <td>${_('Description')}</td>
28 <td>${h.textarea('description',cols=23,rows=5)}</td>
28 <td>${h.textarea('description',cols=32,rows=5)}</td>
29 <td>${self.get_form_error('description')}</td>
29 <td>${self.get_form_error('description')}</td>
30 </tr>
30 </tr>
31 <tr>
31 <tr>
32 <td>${_('Private')}</td>
32 <td>${_('Private')}</td>
33 <td>${h.checkbox('private')}</td>
33 <td>${h.checkbox('private',value="True")}</td>
34 <td>${self.get_form_error('private')}</td>
34 <td>${self.get_form_error('private')}</td>
35 </tr>
35 </tr>
36 <tr>
36 <tr>
@@ -56,13 +56,37 b''
56 </tr>
56 </tr>
57
57
58 %for r2p in c.repo_info.repo2perm:
58 %for r2p in c.repo_info.repo2perm:
59 <tr>
59 %if r2p.user.username =='default' and c.repo_info.private:
60 <tr>
61 <td colspan="4">
62 <span style="font-size: 0.8em">${_('disabled for private repository')}</span></td>
63 <td>${r2p.user.username}</td>
64 </tr>
65 %else:
66 <tr id=${id(r2p.user.username)}>
60 <td>${h.radio('perm_%s' % r2p.user.username,'repository.none')}</td>
67 <td>${h.radio('perm_%s' % r2p.user.username,'repository.none')}</td>
61 <td>${h.radio('perm_%s' % r2p.user.username,'repository.read')}</td>
68 <td>${h.radio('perm_%s' % r2p.user.username,'repository.read')}</td>
62 <td>${h.radio('perm_%s' % r2p.user.username,'repository.write')}</td>
69 <td>${h.radio('perm_%s' % r2p.user.username,'repository.write')}</td>
63 <td>${h.radio('perm_%s' % r2p.user.username,'repository.admin')}</td>
70 <td>${h.radio('perm_%s' % r2p.user.username,'repository.admin')}</td>
64 <td>${r2p.user.username}</td>
71 <td>${r2p.user.username}</td>
72 <td>
73 %if r2p.user.username !='default':
74 <span class="delete_icon action_button" onclick="ajaxAction(${r2p.user.user_id},${id(r2p.user.username)})">
75 <script type="text/javascript">
76 function ajaxAction(user_id,field_id){
77 var sUrl = "${h.url('delete_repo_user',repo_name=c.repo_name)}";
78 var callback = { success:function(o){
79 YAHOO.util.Dom.get(String(field_id)).innerHTML = '<td colspan="6"></td>';
80 }};
81 var postData = '_method=delete&user_id='+user_id;
82 var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData);
83 };
84 </script>
85 </span>
86 %endif
87 </td>
65 </tr>
88 </tr>
89 %endif
66 %endfor
90 %endfor
67 <%
91 <%
68 if not hasattr(c,'form_errors'):
92 if not hasattr(c,'form_errors'):
@@ -24,10 +24,10 b''
24 </tr>
24 </tr>
25 %for cnt,repo in enumerate(c.repos_list):
25 %for cnt,repo in enumerate(c.repos_list):
26 <tr class="parity${cnt%2}">
26 <tr class="parity${cnt%2}">
27 <td>${h.link_to(repo['name'],h.url('edit_repo',id=repo['name']))}</td>
27 <td>${h.link_to(repo['name'],h.url('edit_repo',repo_name=repo['name']))}</td>
28 <td>r${repo['rev']}:${repo['tip']}</td>
28 <td>r${repo['rev']}:${repo['tip']}</td>
29 <td>
29 <td>
30 ${h.form(url('repo', id=repo['name']),method='delete')}
30 ${h.form(url('repo', repo_name=repo['name']),method='delete')}
31 ${h.submit('remove','delete',class_="delete_icon action_button",onclick="return confirm('Confirm to delete this repository');")}
31 ${h.submit('remove','delete',class_="delete_icon action_button",onclick="return confirm('Confirm to delete this repository');")}
32 ${h.end_form()}
32 ${h.end_form()}
33 </td>
33 </td>
@@ -106,7 +106,7 b' def is_current(selected):'
106 <li ${is_current('branches')}>${h.link_to(_('branches'),h.url('branches_home',repo_name=c.repo_name))}</li>
106 <li ${is_current('branches')}>${h.link_to(_('branches'),h.url('branches_home',repo_name=c.repo_name))}</li>
107 <li ${is_current('tags')}>${h.link_to(_('tags'),h.url('tags_home',repo_name=c.repo_name))}</li>
107 <li ${is_current('tags')}>${h.link_to(_('tags'),h.url('tags_home',repo_name=c.repo_name))}</li>
108 <li ${is_current('files')}>${h.link_to(_('files'),h.url('files_home',repo_name=c.repo_name))}</li>
108 <li ${is_current('files')}>${h.link_to(_('files'),h.url('files_home',repo_name=c.repo_name))}</li>
109 <li>${h.link_to(_('settings'),h.url('edit_repo',id=c.repo_name))}</li>
109 <li>${h.link_to(_('settings'),h.url('edit_repo',repo_name=c.repo_name))}</li>
110 </ul>
110 </ul>
111 %else:
111 %else:
112 ##Root menu
112 ##Root menu
General Comments 0
You need to be logged in to leave comments. Login now