##// END OF EJS Templates
Fixed problems with repository creation
marcink -
r1017:ade3414a beta
parent child Browse files
Show More
@@ -1,327 +1,329 b''
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
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 import os
27 import os
28 import shutil
28 import shutil
29 import logging
29 import logging
30 import traceback
30 import traceback
31 from datetime import datetime
31 from datetime import datetime
32
32
33 from rhodecode.model import BaseModel
33 from rhodecode.model import BaseModel
34 from rhodecode.model.caching_query import FromCache
34 from rhodecode.model.caching_query import FromCache
35 from rhodecode.model.db import Repository, RepoToPerm, User, Permission, \
35 from rhodecode.model.db import Repository, RepoToPerm, User, Permission, \
36 Statistics, UsersGroup, UsersGroupToPerm
36 Statistics, UsersGroup, UsersGroupToPerm
37 from rhodecode.model.user import UserModel
37 from rhodecode.model.user import UserModel
38 from rhodecode.model.users_group import UsersGroupMember, UsersGroupModel
38 from rhodecode.model.users_group import UsersGroupMember, UsersGroupModel
39
39
40 from vcs.backends import get_backend
40 from vcs.backends import get_backend
41
41
42 log = logging.getLogger(__name__)
42 log = logging.getLogger(__name__)
43
43
44 class RepoModel(BaseModel):
44 class RepoModel(BaseModel):
45
45
46 def __init__(self, sa=None):
46 def __init__(self, sa=None):
47 try:
47 try:
48 from pylons import app_globals
48 from pylons import app_globals
49 self._base_path = app_globals.base_path
49 self._base_path = app_globals.base_path
50 except:
50 except:
51 self._base_path = None
51 self._base_path = None
52
52
53 @property
53 super(RepoModel, self).__init__(sa)
54 def base_path():
54
55 if self._base_path is None:
55 @property
56 raise Exception('Base Path is empty, try set this after'
56 def base_path(self):
57 'class initialization when not having '
57 if self._base_path is None:
58 'app_globals available')
58 raise Exception('Base Path is empty, try set this after'
59 return self._base_path
59 'class initialization when not having '
60 'app_globals available')
61 return self._base_path
60
62
61 super(RepoModel, self).__init__()
63 super(RepoModel, self).__init__()
62
64
63
65
64 def get(self, repo_id, cache=False):
66 def get(self, repo_id, cache=False):
65 repo = self.sa.query(Repository)\
67 repo = self.sa.query(Repository)\
66 .filter(Repository.repo_id == repo_id)
68 .filter(Repository.repo_id == repo_id)
67
69
68 if cache:
70 if cache:
69 repo = repo.options(FromCache("sql_cache_short",
71 repo = repo.options(FromCache("sql_cache_short",
70 "get_repo_%s" % repo_id))
72 "get_repo_%s" % repo_id))
71 return repo.scalar()
73 return repo.scalar()
72
74
73
75
74 def get_by_repo_name(self, repo_name, cache=False):
76 def get_by_repo_name(self, repo_name, cache=False):
75 repo = self.sa.query(Repository)\
77 repo = self.sa.query(Repository)\
76 .filter(Repository.repo_name == repo_name)
78 .filter(Repository.repo_name == repo_name)
77
79
78 if cache:
80 if cache:
79 repo = repo.options(FromCache("sql_cache_short",
81 repo = repo.options(FromCache("sql_cache_short",
80 "get_repo_%s" % repo_name))
82 "get_repo_%s" % repo_name))
81 return repo.scalar()
83 return repo.scalar()
82
84
83 def get_users_js(self):
85 def get_users_js(self):
84
86
85 users = self.sa.query(User).filter(User.active == True).all()
87 users = self.sa.query(User).filter(User.active == True).all()
86 u_tmpl = '''{id:%s, fname:"%s", lname:"%s", nname:"%s"},'''
88 u_tmpl = '''{id:%s, fname:"%s", lname:"%s", nname:"%s"},'''
87 users_array = '[%s]' % '\n'.join([u_tmpl % (u.user_id, u.name,
89 users_array = '[%s]' % '\n'.join([u_tmpl % (u.user_id, u.name,
88 u.lastname, u.username)
90 u.lastname, u.username)
89 for u in users])
91 for u in users])
90 return users_array
92 return users_array
91
93
92
94
93 def get_users_groups_js(self):
95 def get_users_groups_js(self):
94 users_groups = self.sa.query(UsersGroup)\
96 users_groups = self.sa.query(UsersGroup)\
95 .filter(UsersGroup.users_group_active == True).all()
97 .filter(UsersGroup.users_group_active == True).all()
96
98
97 g_tmpl = '''{id:%s, grname:"%s",grmembers:"%s"},'''
99 g_tmpl = '''{id:%s, grname:"%s",grmembers:"%s"},'''
98
100
99 users_groups_array = '[%s]' % '\n'.join([g_tmpl % \
101 users_groups_array = '[%s]' % '\n'.join([g_tmpl % \
100 (gr.users_group_id, gr.users_group_name,
102 (gr.users_group_id, gr.users_group_name,
101 len(gr.members))
103 len(gr.members))
102 for gr in users_groups])
104 for gr in users_groups])
103 return users_groups_array
105 return users_groups_array
104
106
105 def update(self, repo_name, form_data):
107 def update(self, repo_name, form_data):
106 try:
108 try:
107 cur_repo = self.get_by_repo_name(repo_name, cache=False)
109 cur_repo = self.get_by_repo_name(repo_name, cache=False)
108 user_model = UserModel(self.sa)
110 user_model = UserModel(self.sa)
109 users_group_model = UsersGroupModel(self.sa)
111 users_group_model = UsersGroupModel(self.sa)
110
112
111 #update permissions
113 #update permissions
112 for member, perm, member_type in form_data['perms_updates']:
114 for member, perm, member_type in form_data['perms_updates']:
113 if member_type == 'user':
115 if member_type == 'user':
114 r2p = self.sa.query(RepoToPerm)\
116 r2p = self.sa.query(RepoToPerm)\
115 .filter(RepoToPerm.user == user_model.get_by_username(member))\
117 .filter(RepoToPerm.user == user_model.get_by_username(member))\
116 .filter(RepoToPerm.repository == cur_repo)\
118 .filter(RepoToPerm.repository == cur_repo)\
117 .one()
119 .one()
118
120
119 r2p.permission = self.sa.query(Permission)\
121 r2p.permission = self.sa.query(Permission)\
120 .filter(Permission.permission_name == perm)\
122 .filter(Permission.permission_name == perm)\
121 .scalar()
123 .scalar()
122 self.sa.add(r2p)
124 self.sa.add(r2p)
123 else:
125 else:
124 g2p = self.sa.query(UsersGroupToPerm)\
126 g2p = self.sa.query(UsersGroupToPerm)\
125 .filter(UsersGroupToPerm.users_group == users_group_model.get_by_groupname(member))\
127 .filter(UsersGroupToPerm.users_group == users_group_model.get_by_groupname(member))\
126 .filter(UsersGroupToPerm.repository == cur_repo)\
128 .filter(UsersGroupToPerm.repository == cur_repo)\
127 .one()
129 .one()
128
130
129 g2p.permission = self.sa.query(Permission)\
131 g2p.permission = self.sa.query(Permission)\
130 .filter(Permission.permission_name == perm)\
132 .filter(Permission.permission_name == perm)\
131 .scalar()
133 .scalar()
132 self.sa.add(g2p)
134 self.sa.add(g2p)
133
135
134 #set new permissions
136 #set new permissions
135 for member, perm, member_type in form_data['perms_new']:
137 for member, perm, member_type in form_data['perms_new']:
136 if member_type == 'user':
138 if member_type == 'user':
137 r2p = RepoToPerm()
139 r2p = RepoToPerm()
138 r2p.repository = cur_repo
140 r2p.repository = cur_repo
139 r2p.user = user_model.get_by_username(member)
141 r2p.user = user_model.get_by_username(member)
140
142
141 r2p.permission = self.sa.query(Permission)\
143 r2p.permission = self.sa.query(Permission)\
142 .filter(Permission.permission_name == perm)\
144 .filter(Permission.permission_name == perm)\
143 .scalar()
145 .scalar()
144 self.sa.add(r2p)
146 self.sa.add(r2p)
145 else:
147 else:
146 g2p = UsersGroupToPerm()
148 g2p = UsersGroupToPerm()
147 g2p.repository = cur_repo
149 g2p.repository = cur_repo
148 g2p.users_group = users_group_model.get_by_groupname(member)
150 g2p.users_group = users_group_model.get_by_groupname(member)
149
151
150 g2p.permission = self.sa.query(Permission)\
152 g2p.permission = self.sa.query(Permission)\
151 .filter(Permission.permission_name == perm)\
153 .filter(Permission.permission_name == perm)\
152 .scalar()
154 .scalar()
153 self.sa.add(g2p)
155 self.sa.add(g2p)
154
156
155 #update current repo
157 #update current repo
156 for k, v in form_data.items():
158 for k, v in form_data.items():
157 if k == 'user':
159 if k == 'user':
158 cur_repo.user = user_model.get(v)
160 cur_repo.user = user_model.get(v)
159 else:
161 else:
160 setattr(cur_repo, k, v)
162 setattr(cur_repo, k, v)
161
163
162 self.sa.add(cur_repo)
164 self.sa.add(cur_repo)
163
165
164 if repo_name != form_data['repo_name']:
166 if repo_name != form_data['repo_name']:
165 #rename our data
167 #rename our data
166 self.__rename_repo(repo_name, form_data['repo_name'])
168 self.__rename_repo(repo_name, form_data['repo_name'])
167
169
168 self.sa.commit()
170 self.sa.commit()
169 except:
171 except:
170 log.error(traceback.format_exc())
172 log.error(traceback.format_exc())
171 self.sa.rollback()
173 self.sa.rollback()
172 raise
174 raise
173
175
174 def create(self, form_data, cur_user, just_db=False, fork=False):
176 def create(self, form_data, cur_user, just_db=False, fork=False):
175 try:
177 try:
176 if fork:
178 if fork:
177 #force str since hg doesn't go with unicode
179 #force str since hg doesn't go with unicode
178 repo_name = str(form_data['fork_name'])
180 repo_name = str(form_data['fork_name'])
179 org_name = str(form_data['repo_name'])
181 org_name = str(form_data['repo_name'])
180
182
181 else:
183 else:
182 org_name = repo_name = str(form_data['repo_name'])
184 org_name = repo_name = str(form_data['repo_name'])
183 new_repo = Repository()
185 new_repo = Repository()
184 new_repo.enable_statistics = True
186 new_repo.enable_statistics = True
185 for k, v in form_data.items():
187 for k, v in form_data.items():
186 if k == 'repo_name':
188 if k == 'repo_name':
187 v = repo_name
189 v = repo_name
188 setattr(new_repo, k, v)
190 setattr(new_repo, k, v)
189
191
190 if fork:
192 if fork:
191 parent_repo = self.sa.query(Repository)\
193 parent_repo = self.sa.query(Repository)\
192 .filter(Repository.repo_name == org_name).scalar()
194 .filter(Repository.repo_name == org_name).scalar()
193 new_repo.fork = parent_repo
195 new_repo.fork = parent_repo
194
196
195 new_repo.user_id = cur_user.user_id
197 new_repo.user_id = cur_user.user_id
196 self.sa.add(new_repo)
198 self.sa.add(new_repo)
197
199
198 #create default permission
200 #create default permission
199 repo_to_perm = RepoToPerm()
201 repo_to_perm = RepoToPerm()
200 default = 'repository.read'
202 default = 'repository.read'
201 for p in UserModel(self.sa).get_by_username('default', cache=False).user_perms:
203 for p in UserModel(self.sa).get_by_username('default', cache=False).user_perms:
202 if p.permission.permission_name.startswith('repository.'):
204 if p.permission.permission_name.startswith('repository.'):
203 default = p.permission.permission_name
205 default = p.permission.permission_name
204 break
206 break
205
207
206 default_perm = 'repository.none' if form_data['private'] else default
208 default_perm = 'repository.none' if form_data['private'] else default
207
209
208 repo_to_perm.permission_id = self.sa.query(Permission)\
210 repo_to_perm.permission_id = self.sa.query(Permission)\
209 .filter(Permission.permission_name == default_perm)\
211 .filter(Permission.permission_name == default_perm)\
210 .one().permission_id
212 .one().permission_id
211
213
212 repo_to_perm.repository_id = new_repo.repo_id
214 repo_to_perm.repository_id = new_repo.repo_id
213 repo_to_perm.user_id = UserModel(self.sa)\
215 repo_to_perm.user_id = UserModel(self.sa)\
214 .get_by_username('default', cache=False).user_id
216 .get_by_username('default', cache=False).user_id
215
217
216 self.sa.add(repo_to_perm)
218 self.sa.add(repo_to_perm)
217 self.sa.commit()
219 self.sa.commit()
218
220
219
221
220 #now automatically start following this repository as owner
222 #now automatically start following this repository as owner
221 from rhodecode.model.scm import ScmModel
223 from rhodecode.model.scm import ScmModel
222 ScmModel(self.sa).toggle_following_repo(new_repo.repo_id,
224 ScmModel(self.sa).toggle_following_repo(new_repo.repo_id,
223 cur_user.user_id)
225 cur_user.user_id)
224
226
225 if not just_db:
227 if not just_db:
226 self.__create_repo(repo_name, form_data['repo_type'])
228 self.__create_repo(repo_name, form_data['repo_type'])
227 except:
229 except:
228 log.error(traceback.format_exc())
230 log.error(traceback.format_exc())
229 self.sa.rollback()
231 self.sa.rollback()
230 raise
232 raise
231
233
232 def create_fork(self, form_data, cur_user):
234 def create_fork(self, form_data, cur_user):
233 from rhodecode.lib.celerylib import tasks, run_task
235 from rhodecode.lib.celerylib import tasks, run_task
234 run_task(tasks.create_repo_fork, form_data, cur_user)
236 run_task(tasks.create_repo_fork, form_data, cur_user)
235
237
236 def delete(self, repo):
238 def delete(self, repo):
237 try:
239 try:
238 self.sa.delete(repo)
240 self.sa.delete(repo)
239 self.__delete_repo(repo)
241 self.__delete_repo(repo)
240 self.sa.commit()
242 self.sa.commit()
241 except:
243 except:
242 log.error(traceback.format_exc())
244 log.error(traceback.format_exc())
243 self.sa.rollback()
245 self.sa.rollback()
244 raise
246 raise
245
247
246 def delete_perm_user(self, form_data, repo_name):
248 def delete_perm_user(self, form_data, repo_name):
247 try:
249 try:
248 self.sa.query(RepoToPerm)\
250 self.sa.query(RepoToPerm)\
249 .filter(RepoToPerm.repository \
251 .filter(RepoToPerm.repository \
250 == self.get_by_repo_name(repo_name))\
252 == self.get_by_repo_name(repo_name))\
251 .filter(RepoToPerm.user_id == form_data['user_id']).delete()
253 .filter(RepoToPerm.user_id == form_data['user_id']).delete()
252 self.sa.commit()
254 self.sa.commit()
253 except:
255 except:
254 log.error(traceback.format_exc())
256 log.error(traceback.format_exc())
255 self.sa.rollback()
257 self.sa.rollback()
256 raise
258 raise
257
259
258 def delete_perm_users_group(self, form_data, repo_name):
260 def delete_perm_users_group(self, form_data, repo_name):
259 try:
261 try:
260 self.sa.query(UsersGroupToPerm)\
262 self.sa.query(UsersGroupToPerm)\
261 .filter(UsersGroupToPerm.repository \
263 .filter(UsersGroupToPerm.repository \
262 == self.get_by_repo_name(repo_name))\
264 == self.get_by_repo_name(repo_name))\
263 .filter(UsersGroupToPerm.users_group_id \
265 .filter(UsersGroupToPerm.users_group_id \
264 == form_data['users_group_id']).delete()
266 == form_data['users_group_id']).delete()
265 self.sa.commit()
267 self.sa.commit()
266 except:
268 except:
267 log.error(traceback.format_exc())
269 log.error(traceback.format_exc())
268 self.sa.rollback()
270 self.sa.rollback()
269 raise
271 raise
270
272
271 def delete_stats(self, repo_name):
273 def delete_stats(self, repo_name):
272 try:
274 try:
273 self.sa.query(Statistics)\
275 self.sa.query(Statistics)\
274 .filter(Statistics.repository == \
276 .filter(Statistics.repository == \
275 self.get_by_repo_name(repo_name)).delete()
277 self.get_by_repo_name(repo_name)).delete()
276 self.sa.commit()
278 self.sa.commit()
277 except:
279 except:
278 log.error(traceback.format_exc())
280 log.error(traceback.format_exc())
279 self.sa.rollback()
281 self.sa.rollback()
280 raise
282 raise
281
283
282
284
283 def __create_repo(self, repo_name, alias):
285 def __create_repo(self, repo_name, alias):
284 """
286 """
285 makes repository on filesystem
287 makes repository on filesystem
286 :param repo_name:
288 :param repo_name:
287 :param alias:
289 :param alias:
288 """
290 """
289 from rhodecode.lib.utils import check_repo
291 from rhodecode.lib.utils import check_repo
290 repo_path = os.path.join(self.base_path, repo_name)
292 repo_path = os.path.join(self.base_path, repo_name)
291 if check_repo(repo_name, self.base_path):
293 if check_repo(repo_name, self.base_path):
292 log.info('creating repo %s in %s', repo_name, repo_path)
294 log.info('creating repo %s in %s', repo_name, repo_path)
293 backend = get_backend(alias)
295 backend = get_backend(alias)
294 backend(repo_path, create=True)
296 backend(repo_path, create=True)
295
297
296 def __rename_repo(self, old, new):
298 def __rename_repo(self, old, new):
297 """
299 """
298 renames repository on filesystem
300 renames repository on filesystem
299 :param old: old name
301 :param old: old name
300 :param new: new name
302 :param new: new name
301 """
303 """
302 log.info('renaming repo from %s to %s', old, new)
304 log.info('renaming repo from %s to %s', old, new)
303
305
304 old_path = os.path.join(self.base_path, old)
306 old_path = os.path.join(self.base_path, old)
305 new_path = os.path.join(self.base_path, new)
307 new_path = os.path.join(self.base_path, new)
306 if os.path.isdir(new_path):
308 if os.path.isdir(new_path):
307 raise Exception('Was trying to rename to already existing dir %s',
309 raise Exception('Was trying to rename to already existing dir %s',
308 new_path)
310 new_path)
309 shutil.move(old_path, new_path)
311 shutil.move(old_path, new_path)
310
312
311 def __delete_repo(self, repo):
313 def __delete_repo(self, repo):
312 """
314 """
313 removes repo from filesystem, the removal is acctually made by
315 removes repo from filesystem, the removal is acctually made by
314 added rm__ prefix into dir, and rename internat .hg/.git dirs so this
316 added rm__ prefix into dir, and rename internat .hg/.git dirs so this
315 repository is no longer valid for rhodecode, can be undeleted later on
317 repository is no longer valid for rhodecode, can be undeleted later on
316 by reverting the renames on this repository
318 by reverting the renames on this repository
317 :param repo: repo object
319 :param repo: repo object
318 """
320 """
319 rm_path = os.path.join(self.base_path, repo.repo_name)
321 rm_path = os.path.join(self.base_path, repo.repo_name)
320 log.info("Removing %s", rm_path)
322 log.info("Removing %s", rm_path)
321 #disable hg/git
323 #disable hg/git
322 alias = repo.repo_type
324 alias = repo.repo_type
323 shutil.move(os.path.join(rm_path, '.%s' % alias),
325 shutil.move(os.path.join(rm_path, '.%s' % alias),
324 os.path.join(rm_path, 'rm__.%s' % alias))
326 os.path.join(rm_path, 'rm__.%s' % alias))
325 #disable repo
327 #disable repo
326 shutil.move(rm_path, os.path.join(self.base_path, 'rm__%s__%s' \
328 shutil.move(rm_path, os.path.join(self.base_path, 'rm__%s__%s' \
327 % (datetime.today(), repo.repo_name)))
329 % (datetime.today(), repo.repo_name)))
General Comments 0
You need to be logged in to leave comments. Login now