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