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