##// END OF EJS Templates
fixes #205 db value was not set to none after moving out of group
marcink -
r1379:7ca0b584 beta
parent child Browse files
Show More
@@ -1,358 +1,358
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.model.repo
3 rhodecode.model.repo
4 ~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~
5
5
6 Repository model for rhodecode
6 Repository model for rhodecode
7
7
8 :created_on: Jun 5, 2010
8 :created_on: Jun 5, 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 modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
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, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 import os
25 import os
26 import shutil
26 import shutil
27 import logging
27 import logging
28 import traceback
28 import traceback
29 from datetime import datetime
29 from datetime import datetime
30
30
31 from sqlalchemy.orm import joinedload, make_transient
31 from sqlalchemy.orm import joinedload, make_transient
32
32
33 from vcs.utils.lazy import LazyProperty
33 from vcs.utils.lazy import LazyProperty
34 from vcs.backends import get_backend
34 from vcs.backends import get_backend
35
35
36 from rhodecode.model import BaseModel
36 from rhodecode.model import BaseModel
37 from rhodecode.model.caching_query import FromCache
37 from rhodecode.model.caching_query import FromCache
38 from rhodecode.model.db import Repository, RepoToPerm, User, Permission, \
38 from rhodecode.model.db import Repository, RepoToPerm, User, Permission, \
39 Statistics, UsersGroup, UsersGroupRepoToPerm, RhodeCodeUi, Group
39 Statistics, UsersGroup, UsersGroupRepoToPerm, RhodeCodeUi, Group
40 from rhodecode.model.user import UserModel
40 from rhodecode.model.user import UserModel
41
41
42 log = logging.getLogger(__name__)
42 log = logging.getLogger(__name__)
43
43
44
44
45 class RepoModel(BaseModel):
45 class RepoModel(BaseModel):
46
46
47 @LazyProperty
47 @LazyProperty
48 def repos_path(self):
48 def repos_path(self):
49 """Get's the repositories root path from database
49 """Get's the repositories root path from database
50 """
50 """
51
51
52 q = self.sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one()
52 q = self.sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one()
53 return q.ui_value
53 return q.ui_value
54
54
55 def get(self, repo_id, cache=False):
55 def get(self, repo_id, cache=False):
56 repo = self.sa.query(Repository)\
56 repo = self.sa.query(Repository)\
57 .filter(Repository.repo_id == repo_id)
57 .filter(Repository.repo_id == repo_id)
58
58
59 if cache:
59 if cache:
60 repo = repo.options(FromCache("sql_cache_short",
60 repo = repo.options(FromCache("sql_cache_short",
61 "get_repo_%s" % repo_id))
61 "get_repo_%s" % repo_id))
62 return repo.scalar()
62 return repo.scalar()
63
63
64 def get_by_repo_name(self, repo_name, cache=False):
64 def get_by_repo_name(self, repo_name, cache=False):
65 repo = self.sa.query(Repository)\
65 repo = self.sa.query(Repository)\
66 .filter(Repository.repo_name == repo_name)
66 .filter(Repository.repo_name == repo_name)
67
67
68 if cache:
68 if cache:
69 repo = repo.options(FromCache("sql_cache_short",
69 repo = repo.options(FromCache("sql_cache_short",
70 "get_repo_%s" % repo_name))
70 "get_repo_%s" % repo_name))
71 return repo.scalar()
71 return repo.scalar()
72
72
73
73
74 def get_users_js(self):
74 def get_users_js(self):
75
75
76 users = self.sa.query(User).filter(User.active == True).all()
76 users = self.sa.query(User).filter(User.active == True).all()
77 u_tmpl = '''{id:%s, fname:"%s", lname:"%s", nname:"%s"},'''
77 u_tmpl = '''{id:%s, fname:"%s", lname:"%s", nname:"%s"},'''
78 users_array = '[%s]' % '\n'.join([u_tmpl % (u.user_id, u.name,
78 users_array = '[%s]' % '\n'.join([u_tmpl % (u.user_id, u.name,
79 u.lastname, u.username)
79 u.lastname, u.username)
80 for u in users])
80 for u in users])
81 return users_array
81 return users_array
82
82
83 def get_users_groups_js(self):
83 def get_users_groups_js(self):
84 users_groups = self.sa.query(UsersGroup)\
84 users_groups = self.sa.query(UsersGroup)\
85 .filter(UsersGroup.users_group_active == True).all()
85 .filter(UsersGroup.users_group_active == True).all()
86
86
87 g_tmpl = '''{id:%s, grname:"%s",grmembers:"%s"},'''
87 g_tmpl = '''{id:%s, grname:"%s",grmembers:"%s"},'''
88
88
89 users_groups_array = '[%s]' % '\n'.join([g_tmpl % \
89 users_groups_array = '[%s]' % '\n'.join([g_tmpl % \
90 (gr.users_group_id, gr.users_group_name,
90 (gr.users_group_id, gr.users_group_name,
91 len(gr.members))
91 len(gr.members))
92 for gr in users_groups])
92 for gr in users_groups])
93 return users_groups_array
93 return users_groups_array
94
94
95 def update(self, repo_name, form_data):
95 def update(self, repo_name, form_data):
96 try:
96 try:
97 cur_repo = self.get_by_repo_name(repo_name, cache=False)
97 cur_repo = self.get_by_repo_name(repo_name, cache=False)
98 user_model = UserModel(self.sa)
98 user_model = UserModel(self.sa)
99
99
100 #update permissions
100 #update permissions
101 for member, perm, member_type in form_data['perms_updates']:
101 for member, perm, member_type in form_data['perms_updates']:
102 if member_type == 'user':
102 if member_type == 'user':
103 r2p = self.sa.query(RepoToPerm)\
103 r2p = self.sa.query(RepoToPerm)\
104 .filter(RepoToPerm.user == user_model.
104 .filter(RepoToPerm.user == user_model.
105 get_by_username(member))\
105 get_by_username(member))\
106 .filter(RepoToPerm.repository == cur_repo)\
106 .filter(RepoToPerm.repository == cur_repo)\
107 .one()
107 .one()
108
108
109 r2p.permission = self.sa.query(Permission)\
109 r2p.permission = self.sa.query(Permission)\
110 .filter(Permission.permission_name ==
110 .filter(Permission.permission_name ==
111 perm).scalar()
111 perm).scalar()
112 self.sa.add(r2p)
112 self.sa.add(r2p)
113 else:
113 else:
114 g2p = self.sa.query(UsersGroupRepoToPerm)\
114 g2p = self.sa.query(UsersGroupRepoToPerm)\
115 .filter(UsersGroupRepoToPerm.users_group ==
115 .filter(UsersGroupRepoToPerm.users_group ==
116 UsersGroup.get_by_group_name(member))\
116 UsersGroup.get_by_group_name(member))\
117 .filter(UsersGroupRepoToPerm.repository ==
117 .filter(UsersGroupRepoToPerm.repository ==
118 cur_repo).one()
118 cur_repo).one()
119
119
120 g2p.permission = self.sa.query(Permission)\
120 g2p.permission = self.sa.query(Permission)\
121 .filter(Permission.permission_name ==
121 .filter(Permission.permission_name ==
122 perm).scalar()
122 perm).scalar()
123 self.sa.add(g2p)
123 self.sa.add(g2p)
124
124
125 #set new permissions
125 #set new permissions
126 for member, perm, member_type in form_data['perms_new']:
126 for member, perm, member_type in form_data['perms_new']:
127 if member_type == 'user':
127 if member_type == 'user':
128 r2p = RepoToPerm()
128 r2p = RepoToPerm()
129 r2p.repository = cur_repo
129 r2p.repository = cur_repo
130 r2p.user = user_model.get_by_username(member)
130 r2p.user = user_model.get_by_username(member)
131
131
132 r2p.permission = self.sa.query(Permission)\
132 r2p.permission = self.sa.query(Permission)\
133 .filter(Permission.
133 .filter(Permission.
134 permission_name == perm)\
134 permission_name == perm)\
135 .scalar()
135 .scalar()
136 self.sa.add(r2p)
136 self.sa.add(r2p)
137 else:
137 else:
138 g2p = UsersGroupRepoToPerm()
138 g2p = UsersGroupRepoToPerm()
139 g2p.repository = cur_repo
139 g2p.repository = cur_repo
140 g2p.users_group = UsersGroup.get_by_group_name(member)
140 g2p.users_group = UsersGroup.get_by_group_name(member)
141
141
142 g2p.permission = self.sa.query(Permission)\
142 g2p.permission = self.sa.query(Permission)\
143 .filter(Permission.
143 .filter(Permission.
144 permission_name == perm)\
144 permission_name == perm)\
145 .scalar()
145 .scalar()
146 self.sa.add(g2p)
146 self.sa.add(g2p)
147
147
148 #update current repo
148 #update current repo
149 for k, v in form_data.items():
149 for k, v in form_data.items():
150 if k == 'user':
150 if k == 'user':
151 cur_repo.user = user_model.get_by_username(v)
151 cur_repo.user = user_model.get_by_username(v)
152 elif k == 'repo_name':
152 elif k == 'repo_name':
153 cur_repo.repo_name = form_data['repo_name_full']
153 cur_repo.repo_name = form_data['repo_name_full']
154 elif k == 'repo_group' and v:
154 elif k == 'repo_group':
155 cur_repo.group_id = v
155 cur_repo.group_id = v
156
156
157 else:
157 else:
158 setattr(cur_repo, k, v)
158 setattr(cur_repo, k, v)
159
159
160 self.sa.add(cur_repo)
160 self.sa.add(cur_repo)
161
161
162 if repo_name != form_data['repo_name_full']:
162 if repo_name != form_data['repo_name_full']:
163 # rename repository
163 # rename repository
164 self.__rename_repo(old=repo_name,
164 self.__rename_repo(old=repo_name,
165 new=form_data['repo_name_full'])
165 new=form_data['repo_name_full'])
166
166
167 self.sa.commit()
167 self.sa.commit()
168 except:
168 except:
169 log.error(traceback.format_exc())
169 log.error(traceback.format_exc())
170 self.sa.rollback()
170 self.sa.rollback()
171 raise
171 raise
172
172
173 def create(self, form_data, cur_user, just_db=False, fork=False):
173 def create(self, form_data, cur_user, just_db=False, fork=False):
174
174
175 try:
175 try:
176 if fork:
176 if fork:
177 #force str since hg doesn't go with unicode
177 #force str since hg doesn't go with unicode
178 repo_name = str(form_data['fork_name'])
178 repo_name = str(form_data['fork_name'])
179 org_name = str(form_data['repo_name'])
179 org_name = str(form_data['repo_name'])
180 org_full_name = org_name#str(form_data['fork_name_full'])
180 org_full_name = org_name#str(form_data['fork_name_full'])
181
181
182 else:
182 else:
183 org_name = repo_name = str(form_data['repo_name'])
183 org_name = repo_name = str(form_data['repo_name'])
184 repo_name_full = form_data['repo_name_full']
184 repo_name_full = form_data['repo_name_full']
185
185
186 new_repo = Repository()
186 new_repo = Repository()
187 new_repo.enable_statistics = False
187 new_repo.enable_statistics = False
188 for k, v in form_data.items():
188 for k, v in form_data.items():
189 if k == 'repo_name':
189 if k == 'repo_name':
190 if fork:
190 if fork:
191 v = repo_name
191 v = repo_name
192 else:
192 else:
193 v = repo_name_full
193 v = repo_name_full
194 if k == 'repo_group':
194 if k == 'repo_group':
195 k = 'group_id'
195 k = 'group_id'
196
196
197 setattr(new_repo, k, v)
197 setattr(new_repo, k, v)
198
198
199 if fork:
199 if fork:
200 parent_repo = self.sa.query(Repository)\
200 parent_repo = self.sa.query(Repository)\
201 .filter(Repository.repo_name == org_full_name).one()
201 .filter(Repository.repo_name == org_full_name).one()
202 new_repo.fork = parent_repo
202 new_repo.fork = parent_repo
203
203
204 new_repo.user_id = cur_user.user_id
204 new_repo.user_id = cur_user.user_id
205 self.sa.add(new_repo)
205 self.sa.add(new_repo)
206
206
207 #create default permission
207 #create default permission
208 repo_to_perm = RepoToPerm()
208 repo_to_perm = RepoToPerm()
209 default = 'repository.read'
209 default = 'repository.read'
210 for p in UserModel(self.sa).get_by_username('default',
210 for p in UserModel(self.sa).get_by_username('default',
211 cache=False).user_perms:
211 cache=False).user_perms:
212 if p.permission.permission_name.startswith('repository.'):
212 if p.permission.permission_name.startswith('repository.'):
213 default = p.permission.permission_name
213 default = p.permission.permission_name
214 break
214 break
215
215
216 default_perm = 'repository.none' if form_data['private'] else default
216 default_perm = 'repository.none' if form_data['private'] else default
217
217
218 repo_to_perm.permission_id = self.sa.query(Permission)\
218 repo_to_perm.permission_id = self.sa.query(Permission)\
219 .filter(Permission.permission_name == default_perm)\
219 .filter(Permission.permission_name == default_perm)\
220 .one().permission_id
220 .one().permission_id
221
221
222 repo_to_perm.repository = new_repo
222 repo_to_perm.repository = new_repo
223 repo_to_perm.user_id = UserModel(self.sa)\
223 repo_to_perm.user_id = UserModel(self.sa)\
224 .get_by_username('default', cache=False).user_id
224 .get_by_username('default', cache=False).user_id
225
225
226 self.sa.add(repo_to_perm)
226 self.sa.add(repo_to_perm)
227
227
228 if not just_db:
228 if not just_db:
229 self.__create_repo(repo_name, form_data['repo_type'],
229 self.__create_repo(repo_name, form_data['repo_type'],
230 form_data['repo_group'],
230 form_data['repo_group'],
231 form_data['clone_uri'])
231 form_data['clone_uri'])
232
232
233 self.sa.commit()
233 self.sa.commit()
234
234
235 #now automatically start following this repository as owner
235 #now automatically start following this repository as owner
236 from rhodecode.model.scm import ScmModel
236 from rhodecode.model.scm import ScmModel
237 ScmModel(self.sa).toggle_following_repo(new_repo.repo_id,
237 ScmModel(self.sa).toggle_following_repo(new_repo.repo_id,
238 cur_user.user_id)
238 cur_user.user_id)
239
239
240 except:
240 except:
241 log.error(traceback.format_exc())
241 log.error(traceback.format_exc())
242 self.sa.rollback()
242 self.sa.rollback()
243 raise
243 raise
244
244
245 def create_fork(self, form_data, cur_user):
245 def create_fork(self, form_data, cur_user):
246 from rhodecode.lib.celerylib import tasks, run_task
246 from rhodecode.lib.celerylib import tasks, run_task
247 run_task(tasks.create_repo_fork, form_data, cur_user)
247 run_task(tasks.create_repo_fork, form_data, cur_user)
248
248
249 def delete(self, repo):
249 def delete(self, repo):
250 try:
250 try:
251 self.sa.delete(repo)
251 self.sa.delete(repo)
252 self.__delete_repo(repo)
252 self.__delete_repo(repo)
253 self.sa.commit()
253 self.sa.commit()
254 except:
254 except:
255 log.error(traceback.format_exc())
255 log.error(traceback.format_exc())
256 self.sa.rollback()
256 self.sa.rollback()
257 raise
257 raise
258
258
259 def delete_perm_user(self, form_data, repo_name):
259 def delete_perm_user(self, form_data, repo_name):
260 try:
260 try:
261 self.sa.query(RepoToPerm)\
261 self.sa.query(RepoToPerm)\
262 .filter(RepoToPerm.repository \
262 .filter(RepoToPerm.repository \
263 == self.get_by_repo_name(repo_name))\
263 == self.get_by_repo_name(repo_name))\
264 .filter(RepoToPerm.user_id == form_data['user_id']).delete()
264 .filter(RepoToPerm.user_id == form_data['user_id']).delete()
265 self.sa.commit()
265 self.sa.commit()
266 except:
266 except:
267 log.error(traceback.format_exc())
267 log.error(traceback.format_exc())
268 self.sa.rollback()
268 self.sa.rollback()
269 raise
269 raise
270
270
271 def delete_perm_users_group(self, form_data, repo_name):
271 def delete_perm_users_group(self, form_data, repo_name):
272 try:
272 try:
273 self.sa.query(UsersGroupRepoToPerm)\
273 self.sa.query(UsersGroupRepoToPerm)\
274 .filter(UsersGroupRepoToPerm.repository \
274 .filter(UsersGroupRepoToPerm.repository \
275 == self.get_by_repo_name(repo_name))\
275 == self.get_by_repo_name(repo_name))\
276 .filter(UsersGroupRepoToPerm.users_group_id \
276 .filter(UsersGroupRepoToPerm.users_group_id \
277 == form_data['users_group_id']).delete()
277 == form_data['users_group_id']).delete()
278 self.sa.commit()
278 self.sa.commit()
279 except:
279 except:
280 log.error(traceback.format_exc())
280 log.error(traceback.format_exc())
281 self.sa.rollback()
281 self.sa.rollback()
282 raise
282 raise
283
283
284 def delete_stats(self, repo_name):
284 def delete_stats(self, repo_name):
285 try:
285 try:
286 self.sa.query(Statistics)\
286 self.sa.query(Statistics)\
287 .filter(Statistics.repository == \
287 .filter(Statistics.repository == \
288 self.get_by_repo_name(repo_name)).delete()
288 self.get_by_repo_name(repo_name)).delete()
289 self.sa.commit()
289 self.sa.commit()
290 except:
290 except:
291 log.error(traceback.format_exc())
291 log.error(traceback.format_exc())
292 self.sa.rollback()
292 self.sa.rollback()
293 raise
293 raise
294
294
295 def __create_repo(self, repo_name, alias, new_parent_id, clone_uri=False):
295 def __create_repo(self, repo_name, alias, new_parent_id, clone_uri=False):
296 """
296 """
297 makes repository on filesystem. It's group aware means it'll create
297 makes repository on filesystem. It's group aware means it'll create
298 a repository within a group, and alter the paths accordingly of
298 a repository within a group, and alter the paths accordingly of
299 group location
299 group location
300
300
301 :param repo_name:
301 :param repo_name:
302 :param alias:
302 :param alias:
303 :param parent_id:
303 :param parent_id:
304 :param clone_uri:
304 :param clone_uri:
305 """
305 """
306 from rhodecode.lib.utils import check_repo
306 from rhodecode.lib.utils import check_repo
307
307
308
308
309 if new_parent_id:
309 if new_parent_id:
310 paths = Group.get(new_parent_id).full_path.split(Group.url_sep())
310 paths = Group.get(new_parent_id).full_path.split(Group.url_sep())
311 new_parent_path = os.sep.join(paths)
311 new_parent_path = os.sep.join(paths)
312 else:
312 else:
313 new_parent_path = ''
313 new_parent_path = ''
314
314
315 repo_path = os.path.join(self.repos_path, new_parent_path, repo_name)
315 repo_path = os.path.join(self.repos_path, new_parent_path, repo_name)
316
316
317 if check_repo(repo_name, self.repos_path):
317 if check_repo(repo_name, self.repos_path):
318 log.info('creating repo %s in %s @ %s', repo_name, repo_path,
318 log.info('creating repo %s in %s @ %s', repo_name, repo_path,
319 clone_uri)
319 clone_uri)
320 backend = get_backend(alias)
320 backend = get_backend(alias)
321 backend(repo_path, create=True, src_url=clone_uri)
321 backend(repo_path, create=True, src_url=clone_uri)
322
322
323 def __rename_repo(self, old, new):
323 def __rename_repo(self, old, new):
324 """
324 """
325 renames repository on filesystem
325 renames repository on filesystem
326
326
327 :param old: old name
327 :param old: old name
328 :param new: new name
328 :param new: new name
329 """
329 """
330 log.info('renaming repo from %s to %s', old, new)
330 log.info('renaming repo from %s to %s', old, new)
331
331
332 old_path = os.path.join(self.repos_path, old)
332 old_path = os.path.join(self.repos_path, old)
333 new_path = os.path.join(self.repos_path, new)
333 new_path = os.path.join(self.repos_path, new)
334 if os.path.isdir(new_path):
334 if os.path.isdir(new_path):
335 raise Exception('Was trying to rename to already existing dir %s',
335 raise Exception('Was trying to rename to already existing dir %s',
336 new_path)
336 new_path)
337 shutil.move(old_path, new_path)
337 shutil.move(old_path, new_path)
338
338
339 def __delete_repo(self, repo):
339 def __delete_repo(self, repo):
340 """
340 """
341 removes repo from filesystem, the removal is acctually made by
341 removes repo from filesystem, the removal is acctually made by
342 added rm__ prefix into dir, and rename internat .hg/.git dirs so this
342 added rm__ prefix into dir, and rename internat .hg/.git dirs so this
343 repository is no longer valid for rhodecode, can be undeleted later on
343 repository is no longer valid for rhodecode, can be undeleted later on
344 by reverting the renames on this repository
344 by reverting the renames on this repository
345
345
346 :param repo: repo object
346 :param repo: repo object
347 """
347 """
348 rm_path = os.path.join(self.repos_path, repo.repo_name)
348 rm_path = os.path.join(self.repos_path, repo.repo_name)
349 log.info("Removing %s", rm_path)
349 log.info("Removing %s", rm_path)
350 #disable hg/git
350 #disable hg/git
351 alias = repo.repo_type
351 alias = repo.repo_type
352 shutil.move(os.path.join(rm_path, '.%s' % alias),
352 shutil.move(os.path.join(rm_path, '.%s' % alias),
353 os.path.join(rm_path, 'rm__.%s' % alias))
353 os.path.join(rm_path, 'rm__.%s' % alias))
354 #disable repo
354 #disable repo
355 shutil.move(rm_path, os.path.join(self.repos_path, 'rm__%s__%s' \
355 shutil.move(rm_path, os.path.join(self.repos_path, 'rm__%s__%s' \
356 % (datetime.today()\
356 % (datetime.today()\
357 .strftime('%Y%m%d_%H%M%S_%f'),
357 .strftime('%Y%m%d_%H%M%S_%f'),
358 repo.repo_name)))
358 repo.repo_name)))
General Comments 0
You need to be logged in to leave comments. Login now