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