comparison rhodecode/model/scm.py @ 1216:8363b0d20c41

fixes for stable
author Marcin Kuzminski <marcin@python-works.com>
date Tue, 05 Apr 2011 18:01:19 +0200
parents 93b980ebee55
children bf263968da47
comparison
equal deleted inserted replaced
1215:8a153dba7033 1216:8363b0d20c41
5 5
6 Scm model for RhodeCode 6 Scm model for RhodeCode
7 7
8 :created_on: Apr 9, 2010 8 :created_on: Apr 9, 2010
9 :author: marcink 9 :author: marcink
10 :copyright: (C) 2009-2010 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 modify
14 # modify it under the terms of the GNU General Public License 14 # it under the terms of the GNU General Public License as published by
15 # as published by the Free Software Foundation; version 2 15 # the Free Software Foundation, either version 3 of the License, or
16 # of the License or (at your opinion) any later version of the license. 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, write to the Free Software 24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 # MA 02110-1301, USA.
27 import os 25 import os
28 import time 26 import time
29 import traceback 27 import traceback
30 import logging 28 import logging
31 29
57 55
58 56
59 class UserTemp(object): 57 class UserTemp(object):
60 def __init__(self, user_id): 58 def __init__(self, user_id):
61 self.user_id = user_id 59 self.user_id = user_id
60
61 def __repr__(self):
62 return "<%s('id:%s')>" % (self.__class__.__name__, self.user_id)
63
64
62 class RepoTemp(object): 65 class RepoTemp(object):
63 def __init__(self, repo_id): 66 def __init__(self, repo_id):
64 self.repo_id = repo_id 67 self.repo_id = repo_id
65 68
69 def __repr__(self):
70 return "<%s('id:%s')>" % (self.__class__.__name__, self.repo_id)
71
72
66 class ScmModel(BaseModel): 73 class ScmModel(BaseModel):
67 """Generic Scm Model 74 """Generic Scm Model
68 """ 75 """
69 76
70 @LazyProperty 77 @LazyProperty
75 q = self.sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one() 82 q = self.sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one()
76 83
77 return q.ui_value 84 return q.ui_value
78 85
79 def repo_scan(self, repos_path, baseui): 86 def repo_scan(self, repos_path, baseui):
80 """Listing of repositories in given path. This path should not be a 87 """Listing of repositories in given path. This path should not be a
81 repository itself. Return a dictionary of repository objects 88 repository itself. Return a dictionary of repository objects
82 89
83 :param repos_path: path to directory containing repositories 90 :param repos_path: path to directory containing repositories
84 :param baseui: baseui instance to instantiate MercurialRepostitory with 91 :param baseui: baseui instance to instantiate MercurialRepostitory with
85 """ 92 """
86 93
87 log.info('scanning for repositories in %s', repos_path) 94 log.info('scanning for repositories in %s', repos_path)
90 baseui = make_ui('db') 97 baseui = make_ui('db')
91 repos_list = {} 98 repos_list = {}
92 99
93 for name, path in get_repos(repos_path): 100 for name, path in get_repos(repos_path):
94 try: 101 try:
95 if repos_list.has_key(name): 102 if name in repos_list:
96 raise RepositoryError('Duplicate repository name %s ' 103 raise RepositoryError('Duplicate repository name %s '
97 'found in %s' % (name, path)) 104 'found in %s' % (name, path))
98 else: 105 else:
99 106
100 klass = get_backend(path[0]) 107 klass = get_backend(path[0])
108 continue 115 continue
109 116
110 return repos_list 117 return repos_list
111 118
112 def get_repos(self, all_repos=None): 119 def get_repos(self, all_repos=None):
113 """Get all repos from db and for each repo create it's backend instance. 120 """Get all repos from db and for each repo create it's
114 and fill that backed with information from database 121 backend instance.and fill that backed with information from database
115 122
116 :param all_repos: give specific repositories list, good for filtering 123 :param all_repos: give specific repositories list, good for filtering
117 """ 124 """
118 125
119 if all_repos is None: 126 if all_repos is None:
120 all_repos = self.sa.query(Repository)\ 127 all_repos = self.sa.query(Repository)\
138 tmp_d['name'] = repo.name 145 tmp_d['name'] = repo.name
139 tmp_d['name_sort'] = tmp_d['name'].lower() 146 tmp_d['name_sort'] = tmp_d['name'].lower()
140 tmp_d['description'] = repo.dbrepo.description 147 tmp_d['description'] = repo.dbrepo.description
141 tmp_d['description_sort'] = tmp_d['description'] 148 tmp_d['description_sort'] = tmp_d['description']
142 tmp_d['last_change'] = last_change 149 tmp_d['last_change'] = last_change
143 tmp_d['last_change_sort'] = time.mktime(last_change.timetuple()) 150 tmp_d['last_change_sort'] = time.mktime(last_change \
151 .timetuple())
144 tmp_d['tip'] = tip.raw_id 152 tmp_d['tip'] = tip.raw_id
145 tmp_d['tip_sort'] = tip.revision 153 tmp_d['tip_sort'] = tip.revision
146 tmp_d['rev'] = tip.revision 154 tmp_d['rev'] = tip.revision
147 tmp_d['contact'] = repo.dbrepo.user.full_contact 155 tmp_d['contact'] = repo.dbrepo.user.full_contact
148 tmp_d['contact_sort'] = tmp_d['contact'] 156 tmp_d['contact_sort'] = tmp_d['contact']
156 return self.get(repo_name) 164 return self.get(repo_name)
157 165
158 def get(self, repo_name, invalidation_list=None): 166 def get(self, repo_name, invalidation_list=None):
159 """Get's repository from given name, creates BackendInstance and 167 """Get's repository from given name, creates BackendInstance and
160 propagates it's data from database with all additional information 168 propagates it's data from database with all additional information
161 169
162 :param repo_name: 170 :param repo_name:
163 :param invalidation_list: if a invalidation list is given the get 171 :param invalidation_list: if a invalidation list is given the get
164 method should not manually check if this repository needs 172 method should not manually check if this repository needs
165 invalidation and just invalidate the repositories in list 173 invalidation and just invalidate the repositories in list
166 174
167 """ 175 """
168 if not HasRepoPermissionAny('repository.read', 'repository.write', 176 if not HasRepoPermissionAny('repository.read', 'repository.write',
169 'repository.admin')(repo_name, 'get repo check'): 177 'repository.admin')(repo_name, 'get repo check'):
170 return 178 return
171 179
222 region_invalidate(_get_repo, None, repo_name) 230 region_invalidate(_get_repo, None, repo_name)
223 self._mark_invalidated(invalidate) 231 self._mark_invalidated(invalidate)
224 232
225 return _get_repo(repo_name) 233 return _get_repo(repo_name)
226 234
227
228
229 def mark_for_invalidation(self, repo_name): 235 def mark_for_invalidation(self, repo_name):
230 """Puts cache invalidation task into db for 236 """Puts cache invalidation task into db for
231 further global cache invalidation 237 further global cache invalidation
232 238
233 :param repo_name: this repo that should invalidation take place 239 :param repo_name: this repo that should invalidation take place
234 """ 240 """
235 241
236 log.debug('marking %s for invalidation', repo_name) 242 log.debug('marking %s for invalidation', repo_name)
237 cache = self.sa.query(CacheInvalidation)\ 243 cache = self.sa.query(CacheInvalidation)\
248 self.sa.add(cache) 254 self.sa.add(cache)
249 self.sa.commit() 255 self.sa.commit()
250 except (DatabaseError,): 256 except (DatabaseError,):
251 log.error(traceback.format_exc()) 257 log.error(traceback.format_exc())
252 self.sa.rollback() 258 self.sa.rollback()
253
254 259
255 def toggle_following_repo(self, follow_repo_id, user_id): 260 def toggle_following_repo(self, follow_repo_id, user_id):
256 261
257 f = self.sa.query(UserFollowing)\ 262 f = self.sa.query(UserFollowing)\
258 .filter(UserFollowing.follows_repo_id == follow_repo_id)\ 263 .filter(UserFollowing.follows_repo_id == follow_repo_id)\
269 return 274 return
270 except: 275 except:
271 log.error(traceback.format_exc()) 276 log.error(traceback.format_exc())
272 self.sa.rollback() 277 self.sa.rollback()
273 raise 278 raise
274
275 279
276 try: 280 try:
277 f = UserFollowing() 281 f = UserFollowing()
278 f.user_id = user_id 282 f.user_id = user_id
279 f.follows_repo_id = follow_repo_id 283 f.follows_repo_id = follow_repo_id
285 except: 289 except:
286 log.error(traceback.format_exc()) 290 log.error(traceback.format_exc())
287 self.sa.rollback() 291 self.sa.rollback()
288 raise 292 raise
289 293
290 def toggle_following_user(self, follow_user_id , user_id): 294 def toggle_following_user(self, follow_user_id, user_id):
291 f = self.sa.query(UserFollowing)\ 295 f = self.sa.query(UserFollowing)\
292 .filter(UserFollowing.follows_user_id == follow_user_id)\ 296 .filter(UserFollowing.follows_user_id == follow_user_id)\
293 .filter(UserFollowing.user_id == user_id).scalar() 297 .filter(UserFollowing.user_id == user_id).scalar()
294 298
295 if f is not None: 299 if f is not None:
338 342
339 def get_forks(self, repo_id): 343 def get_forks(self, repo_id):
340 return self.sa.query(Repository)\ 344 return self.sa.query(Repository)\
341 .filter(Repository.fork_id == repo_id).count() 345 .filter(Repository.fork_id == repo_id).count()
342 346
343
344 def get_unread_journal(self): 347 def get_unread_journal(self):
345 return self.sa.query(UserLog).count() 348 return self.sa.query(UserLog).count()
346 349
347
348 def _should_invalidate(self, repo_name): 350 def _should_invalidate(self, repo_name):
349 """Looks up database for invalidation signals for this repo_name 351 """Looks up database for invalidation signals for this repo_name
350 352
351 :param repo_name: 353 :param repo_name:
352 """ 354 """
353 355
354 ret = self.sa.query(CacheInvalidation)\ 356 ret = self.sa.query(CacheInvalidation)\
355 .options(FromCache('sql_cache_short', 357 .options(FromCache('sql_cache_short',
359 .scalar() 361 .scalar()
360 362
361 return ret 363 return ret
362 364
363 def _mark_invalidated(self, cache_key): 365 def _mark_invalidated(self, cache_key):
364 """ Marks all occurences of cache to invaldation as already invalidated 366 """ Marks all occurences of cache to invaldation as
365 367 already invalidated
368
366 :param cache_key: 369 :param cache_key:
367 """ 370 """
368 371
369 if cache_key: 372 if cache_key:
370 log.debug('marking %s as already invalidated', cache_key) 373 log.debug('marking %s as already invalidated', cache_key)
373 self.sa.add(cache_key) 376 self.sa.add(cache_key)
374 self.sa.commit() 377 self.sa.commit()
375 except (DatabaseError,): 378 except (DatabaseError,):
376 log.error(traceback.format_exc()) 379 log.error(traceback.format_exc())
377 self.sa.rollback() 380 self.sa.rollback()
378