##// END OF EJS Templates
Moved out reposcan into hg Model....
marcink -
r665:070f3274 beta
parent child Browse files
Show More
@@ -6,7 +6,7 b' from rhodecode.config.routing import mak'
6 from rhodecode.lib.auth import set_available_permissions, set_base_path
6 from rhodecode.lib.auth import set_available_permissions, set_base_path
7 from rhodecode.lib.utils import repo2db_mapper, make_ui, set_rhodecode_config
7 from rhodecode.lib.utils import repo2db_mapper, make_ui, set_rhodecode_config
8 from rhodecode.model import init_model
8 from rhodecode.model import init_model
9 from rhodecode.model.hg import _get_repos_cached_initial
9 from rhodecode.model.hg import HgModel
10 from sqlalchemy import engine_from_config
10 from sqlalchemy import engine_from_config
11 import logging
11 import logging
12 import os
12 import os
@@ -69,7 +69,8 b' def load_environment(global_conf, app_co'
69 #init baseui
69 #init baseui
70 config['pylons.app_globals'].baseui = make_ui('db')
70 config['pylons.app_globals'].baseui = make_ui('db')
71
71
72 repo2db_mapper(_get_repos_cached_initial(config['pylons.app_globals'], initial))
72 g = config['pylons.app_globals']
73 repo2db_mapper(HgModel().repo_scan(g.paths[0][1], g.baseui, initial))
73 set_available_permissions(config)
74 set_available_permissions(config)
74 set_base_path(config)
75 set_base_path(config)
75 set_rhodecode_config(config)
76 set_rhodecode_config(config)
@@ -74,7 +74,6 b' class ReposController(BaseController):'
74 try:
74 try:
75 form_result = _form.to_python(dict(request.POST))
75 form_result = _form.to_python(dict(request.POST))
76 repo_model.create(form_result, c.rhodecode_user)
76 repo_model.create(form_result, c.rhodecode_user)
77 invalidate_cache('cached_repo_list')
78 h.flash(_('created repository %s') % form_result['repo_name'],
77 h.flash(_('created repository %s') % form_result['repo_name'],
79 category='success')
78 category='success')
80
79
@@ -133,7 +132,7 b' class ReposController(BaseController):'
133 try:
132 try:
134 form_result = _form.to_python(dict(request.POST))
133 form_result = _form.to_python(dict(request.POST))
135 repo_model.update(repo_name, form_result)
134 repo_model.update(repo_name, form_result)
136 invalidate_cache('cached_repo_list')
135 invalidate_cache('get_repo_cached_%s' % repo_name)
137 h.flash(_('Repository %s updated succesfully' % repo_name),
136 h.flash(_('Repository %s updated succesfully' % repo_name),
138 category='success')
137 category='success')
139 changed_name = form_result['repo_name']
138 changed_name = form_result['repo_name']
@@ -182,7 +181,7 b' class ReposController(BaseController):'
182 action_logger(self.rhodecode_user, 'admin_deleted_repo',
181 action_logger(self.rhodecode_user, 'admin_deleted_repo',
183 repo_name, '', self.sa)
182 repo_name, '', self.sa)
184 repo_model.delete(repo)
183 repo_model.delete(repo)
185 invalidate_cache('cached_repo_list')
184 invalidate_cache('get_repo_cached_%s' % repo_name)
186 h.flash(_('deleted repository %s') % repo_name, category='success')
185 h.flash(_('deleted repository %s') % repo_name, category='success')
187
186
188 except Exception, e:
187 except Exception, e:
@@ -33,12 +33,13 b' from rhodecode.lib.auth import LoginRequ'
33 from rhodecode.lib.base import BaseController, render
33 from rhodecode.lib.base import BaseController, render
34 from rhodecode.lib.utils import repo2db_mapper, invalidate_cache, \
34 from rhodecode.lib.utils import repo2db_mapper, invalidate_cache, \
35 set_rhodecode_config, get_hg_settings, get_hg_ui_settings
35 set_rhodecode_config, get_hg_settings, get_hg_ui_settings
36 from rhodecode.model.db import RhodeCodeSettings, RhodeCodeUi
36 from rhodecode.model.db import RhodeCodeSettings, RhodeCodeUi, Repository
37 from rhodecode.model.forms import UserForm, ApplicationSettingsForm, \
37 from rhodecode.model.forms import UserForm, ApplicationSettingsForm, \
38 ApplicationUiSettingsForm
38 ApplicationUiSettingsForm
39 from rhodecode.model.hg import HgModel
39 from rhodecode.model.hg import HgModel
40 from rhodecode.model.user import UserModel
40 from rhodecode.model.user import UserModel
41 from rhodecode.lib.celerylib import tasks, run_task
41 from rhodecode.lib.celerylib import tasks, run_task
42 from sqlalchemy import func
42 import formencode
43 import formencode
43 import logging
44 import logging
44 import traceback
45 import traceback
@@ -98,9 +99,12 b' class SettingsController(BaseController)'
98 rm_obsolete = request.POST.get('destroy', False)
99 rm_obsolete = request.POST.get('destroy', False)
99 log.debug('Rescanning directories with destroy=%s', rm_obsolete)
100 log.debug('Rescanning directories with destroy=%s', rm_obsolete)
100
101
101 initial = HgModel.repo_scan(g.paths[0][0], g.paths[0][1], g.baseui)
102 initial = HgModel().repo_scan(g.paths[0][1], g.baseui)
103 for repo_name in initial.keys():
104 invalidate_cache('get_repo_cached_%s' % repo_name)
105
102 repo2db_mapper(initial, rm_obsolete)
106 repo2db_mapper(initial, rm_obsolete)
103 invalidate_cache('cached_repo_list')
107
104 h.flash(_('Repositories successfully rescanned'), category='success')
108 h.flash(_('Repositories successfully rescanned'), category='success')
105
109
106 if setting_id == 'whoosh':
110 if setting_id == 'whoosh':
@@ -238,12 +242,14 b' class SettingsController(BaseController)'
238 """
242 """
239 GET /_admin/my_account Displays info about my account
243 GET /_admin/my_account Displays info about my account
240 """
244 """
245
241 # url('admin_settings_my_account')
246 # url('admin_settings_my_account')
242 c.user = UserModel(self.sa).get(c.rhodecode_user.user_id, cache=False)
247 c.user = UserModel(self.sa).get(c.rhodecode_user.user_id, cache=False)
243 c.user_repos = []
248 all_repos = self.sa.query(Repository)\
244 for repo in c.cached_repo_list.values():
249 .filter(Repository.user_id == c.user.user_id)\
245 if repo.dbrepo.user.username == c.user.username:
250 .order_by(func.lower(Repository.repo_name))\
246 c.user_repos.append(repo)
251 .all()
252 c.user_repos = HgModel().get_repos(all_repos)
247
253
248 if c.user.username == 'default':
254 if c.user.username == 'default':
249 h.flash(_("You can't edit this user since it's"
255 h.flash(_("You can't edit this user since it's"
@@ -78,7 +78,7 b' class SettingsController(BaseController)'
78 try:
78 try:
79 form_result = _form.to_python(dict(request.POST))
79 form_result = _form.to_python(dict(request.POST))
80 repo_model.update(repo_name, form_result)
80 repo_model.update(repo_name, form_result)
81 invalidate_cache('cached_repo_list')
81 invalidate_cache('get_repo_cached_%s' % repo_name)
82 h.flash(_('Repository %s updated successfully' % repo_name),
82 h.flash(_('Repository %s updated successfully' % repo_name),
83 category='success')
83 category='success')
84 changed_name = form_result['repo_name']
84 changed_name = form_result['repo_name']
@@ -96,7 +96,7 b' class SettingsController(BaseController)'
96 encoding="UTF-8")
96 encoding="UTF-8")
97 except Exception:
97 except Exception:
98 log.error(traceback.format_exc())
98 log.error(traceback.format_exc())
99 h.flash(_('error occured during update of repository %s') \
99 h.flash(_('error occurred during update of repository %s') \
100 % repo_name, category='error')
100 % repo_name, category='error')
101
101
102 return redirect(url('repo_settings_home', repo_name=changed_name))
102 return redirect(url('repo_settings_home', repo_name=changed_name))
@@ -126,7 +126,7 b' class SettingsController(BaseController)'
126 action_logger(self.rhodecode_user, 'user_deleted_repo',
126 action_logger(self.rhodecode_user, 'user_deleted_repo',
127 repo_name, '', self.sa)
127 repo_name, '', self.sa)
128 repo_model.delete(repo)
128 repo_model.delete(repo)
129 invalidate_cache('cached_repo_list')
129 invalidate_cache('get_repo_cached_%s' % repo_name)
130 h.flash(_('deleted repository %s') % repo_name, category='success')
130 h.flash(_('deleted repository %s') % repo_name, category='success')
131 except Exception:
131 except Exception:
132 h.flash(_('An error occurred during deletion of %s') % repo_name,
132 h.flash(_('An error occurred during deletion of %s') % repo_name,
@@ -9,20 +9,20 b' from rhodecode import __version__'
9 from rhodecode.lib import auth
9 from rhodecode.lib import auth
10 from rhodecode.lib.utils import get_repo_slug
10 from rhodecode.lib.utils import get_repo_slug
11 from rhodecode.model import meta
11 from rhodecode.model import meta
12 from rhodecode.model.hg import _get_repos_cached, \
12 from rhodecode.model.hg import HgModel
13 _get_repos_switcher_cached
14 from vcs import BACKENDS
13 from vcs import BACKENDS
14
15 class BaseController(WSGIController):
15 class BaseController(WSGIController):
16
16
17 def __before__(self):
17 def __before__(self):
18 c.rhodecode_version = __version__
18 c.rhodecode_version = __version__
19 c.rhodecode_name = config['rhodecode_title']
19 c.rhodecode_name = config['rhodecode_title']
20 c.repo_name = get_repo_slug(request)
20 c.repo_name = get_repo_slug(request)
21 c.cached_repo_list = _get_repos_cached()
21 c.cached_repo_list = HgModel().get_repos()
22 c.repo_switcher_list = _get_repos_switcher_cached(c.cached_repo_list)
23 c.backends = BACKENDS.keys()
22 c.backends = BACKENDS.keys()
23
24 if c.repo_name:
24 if c.repo_name:
25 cached_repo = c.cached_repo_list.get(c.repo_name)
25 cached_repo = HgModel().get(c.repo_name)
26
26
27 if cached_repo:
27 if cached_repo:
28 c.repository_tags = cached_repo.tags
28 c.repository_tags = cached_repo.tags
@@ -83,15 +83,15 b' class SimpleGit(object):'
83 self.repository = None
83 self.repository = None
84 self.username = None
84 self.username = None
85 self.action = None
85 self.action = None
86
86
87 def __call__(self, environ, start_response):
87 def __call__(self, environ, start_response):
88 if not is_git(environ):
88 if not is_git(environ):
89 return self.application(environ, start_response)
89 return self.application(environ, start_response)
90
90
91 proxy_key = 'HTTP_X_REAL_IP'
91 proxy_key = 'HTTP_X_REAL_IP'
92 def_key = 'REMOTE_ADDR'
92 def_key = 'REMOTE_ADDR'
93 self.ipaddr = environ.get(proxy_key, environ.get(def_key, '0.0.0.0'))
93 self.ipaddr = environ.get(proxy_key, environ.get(def_key, '0.0.0.0'))
94
94
95 #===================================================================
95 #===================================================================
96 # AUTHENTICATE THIS GIT REQUEST
96 # AUTHENTICATE THIS GIT REQUEST
97 #===================================================================
97 #===================================================================
@@ -104,7 +104,7 b' class SimpleGit(object):'
104 REMOTE_USER.update(environ, result)
104 REMOTE_USER.update(environ, result)
105 else:
105 else:
106 return result.wsgi_application(environ, start_response)
106 return result.wsgi_application(environ, start_response)
107
107
108 #=======================================================================
108 #=======================================================================
109 # GET REPOSITORY
109 # GET REPOSITORY
110 #=======================================================================
110 #=======================================================================
@@ -206,5 +206,4 b' class SimpleGit(object):'
206 """we know that some change was made to repositories and we should
206 """we know that some change was made to repositories and we should
207 invalidate the cache to see the changes right away but only for
207 invalidate the cache to see the changes right away but only for
208 push requests"""
208 push requests"""
209 invalidate_cache('cached_repo_list')
209 invalidate_cache('get_repo_cached_%s' % repo_name)
210 invalidate_cache('full_changelog', repo_name)
@@ -52,20 +52,20 b' class SimpleHg(object):'
52 self.repository = None
52 self.repository = None
53 self.username = None
53 self.username = None
54 self.action = None
54 self.action = None
55
55
56 def __call__(self, environ, start_response):
56 def __call__(self, environ, start_response):
57 if not is_mercurial(environ):
57 if not is_mercurial(environ):
58 return self.application(environ, start_response)
58 return self.application(environ, start_response)
59
59
60 proxy_key = 'HTTP_X_REAL_IP'
60 proxy_key = 'HTTP_X_REAL_IP'
61 def_key = 'REMOTE_ADDR'
61 def_key = 'REMOTE_ADDR'
62 self.ipaddr = environ.get(proxy_key, environ.get(def_key, '0.0.0.0'))
62 self.ipaddr = environ.get(proxy_key, environ.get(def_key, '0.0.0.0'))
63
63
64 #===================================================================
64 #===================================================================
65 # AUTHENTICATE THIS MERCURIAL REQUEST
65 # AUTHENTICATE THIS MERCURIAL REQUEST
66 #===================================================================
66 #===================================================================
67 username = REMOTE_USER(environ)
67 username = REMOTE_USER(environ)
68
68
69 if not username:
69 if not username:
70 self.authenticate.realm = self.config['rhodecode_realm']
70 self.authenticate.realm = self.config['rhodecode_realm']
71 result = self.authenticate(environ)
71 result = self.authenticate(environ)
@@ -74,7 +74,7 b' class SimpleHg(object):'
74 REMOTE_USER.update(environ, result)
74 REMOTE_USER.update(environ, result)
75 else:
75 else:
76 return result.wsgi_application(environ, start_response)
76 return result.wsgi_application(environ, start_response)
77
77
78 #=======================================================================
78 #=======================================================================
79 # GET REPOSITORY
79 # GET REPOSITORY
80 #=======================================================================
80 #=======================================================================
@@ -114,7 +114,7 b' class SimpleHg(object):'
114 'repository.admin')\
114 'repository.admin')\
115 (user, repo_name):
115 (user, repo_name):
116 return HTTPForbidden()(environ, start_response)
116 return HTTPForbidden()(environ, start_response)
117
117
118 self.extras = {'ip':self.ipaddr,
118 self.extras = {'ip':self.ipaddr,
119 'username':self.username,
119 'username':self.username,
120 'action':self.action,
120 'action':self.action,
@@ -200,8 +200,7 b' class SimpleHg(object):'
200 """we know that some change was made to repositories and we should
200 """we know that some change was made to repositories and we should
201 invalidate the cache to see the changes right away but only for
201 invalidate the cache to see the changes right away but only for
202 push requests"""
202 push requests"""
203 invalidate_cache('cached_repo_list')
203 invalidate_cache('get_repo_cached_%s' % repo_name)
204 invalidate_cache('full_changelog', repo_name)
205
204
206
205
207 def __load_web_settings(self, hgserve, extras={}):
206 def __load_web_settings(self, hgserve, extras={}):
@@ -209,12 +208,12 b' class SimpleHg(object):'
209 hgserve.repo.ui = self.baseui
208 hgserve.repo.ui = self.baseui
210
209
211 hgrc = os.path.join(self.repo_path, '.hg', 'hgrc')
210 hgrc = os.path.join(self.repo_path, '.hg', 'hgrc')
212
211
213 #inject some additional parameters that will be available in ui
212 #inject some additional parameters that will be available in ui
214 #for hooks
213 #for hooks
215 for k, v in extras.items():
214 for k, v in extras.items():
216 hgserve.repo.ui.setconfig('rhodecode_extras', k, v)
215 hgserve.repo.ui.setconfig('rhodecode_extras', k, v)
217
216
218 repoui = make_ui('file', hgrc, False)
217 repoui = make_ui('file', hgrc, False)
219
218
220 if repoui:
219 if repoui:
@@ -222,7 +221,7 b' class SimpleHg(object):'
222 for section in ui_sections:
221 for section in ui_sections:
223 for k, v in repoui.configitems(section):
222 for k, v in repoui.configitems(section):
224 hgserve.repo.ui.setconfig(section, k, v)
223 hgserve.repo.ui.setconfig(section, k, v)
225
224
226 return hgserve
225 return hgserve
227
226
228
227
@@ -275,25 +275,11 b' def set_rhodecode_config(config):'
275 config[k] = v
275 config[k] = v
276
276
277 def invalidate_cache(name, *args):
277 def invalidate_cache(name, *args):
278 """Invalidates given name cache"""
278 """
279
279 Puts cache invalidation task into db for
280 from beaker.cache import region_invalidate
280 further global cache invalidation
281 log.info('INVALIDATING CACHE FOR %s', name)
281 """
282
282 pass
283 """propagate our arguments to make sure invalidation works. First
284 argument has to be the name of cached func name give to cache decorator
285 without that the invalidation would not work"""
286 tmp = [name]
287 tmp.extend(args)
288 args = tuple(tmp)
289
290 if name == 'cached_repo_list':
291 from rhodecode.model.hg import _get_repos_cached
292 region_invalidate(_get_repos_cached, None, *args)
293
294 if name == 'full_changelog':
295 from rhodecode.model.hg import _full_changelog_cached
296 region_invalidate(_full_changelog_cached, None, *args)
297
283
298 class EmptyChangeset(BaseChangeset):
284 class EmptyChangeset(BaseChangeset):
299 """
285 """
@@ -352,7 +338,6 b' def repo2db_mapper(initial_repo_list, re'
352 }
338 }
353 rm.create(form_data, user, just_db=True)
339 rm.create(form_data, user, just_db=True)
354
340
355
356 if remove_obsolete:
341 if remove_obsolete:
357 #remove from database those repositories that are not in the filesystem
342 #remove from database those repositories that are not in the filesystem
358 for repo in sa.query(Repository).all():
343 for repo in sa.query(Repository).all():
@@ -360,10 +345,6 b' def repo2db_mapper(initial_repo_list, re'
360 sa.delete(repo)
345 sa.delete(repo)
361 sa.commit()
346 sa.commit()
362
347
363
364 meta.Session.remove()
365
366
367 class OrderedDict(dict, DictMixin):
348 class OrderedDict(dict, DictMixin):
368
349
369 def __init__(self, *args, **kwds):
350 def __init__(self, *args, **kwds):
@@ -22,57 +22,25 b' Created on April 9, 2010'
22 Model for RhodeCode
22 Model for RhodeCode
23 @author: marcink
23 @author: marcink
24 """
24 """
25 from beaker.cache import cache_region
25 from beaker.cache import cache_region, region_invalidate
26 from mercurial import ui
26 from mercurial import ui
27 from rhodecode.lib import helpers as h
27 from rhodecode.lib import helpers as h
28 from rhodecode.lib.utils import invalidate_cache
29 from rhodecode.lib.auth import HasRepoPermissionAny
28 from rhodecode.lib.auth import HasRepoPermissionAny
29 from rhodecode.lib.utils import get_repos
30 from rhodecode.model import meta
30 from rhodecode.model import meta
31 from rhodecode.model.db import Repository, User
31 from rhodecode.model.caching_query import FromCache
32 from rhodecode.model.db import Repository, User, RhodeCodeUi
32 from sqlalchemy.orm import joinedload
33 from sqlalchemy.orm import joinedload
34 from vcs import get_repo as vcs_get_repo, get_backend
35 from vcs.backends.hg import MercurialRepository
33 from vcs.exceptions import RepositoryError, VCSError
36 from vcs.exceptions import RepositoryError, VCSError
37 from vcs.utils.lazy import LazyProperty
34 import logging
38 import logging
35 import sys
39 import os
36 import time
40 import time
37
41
38 log = logging.getLogger(__name__)
42 log = logging.getLogger(__name__)
39
43
40 try:
41 from vcs.backends.hg import MercurialRepository
42 from vcs.backends.git import GitRepository
43 except ImportError:
44 sys.stderr.write('You have to import vcs module')
45 raise Exception('Unable to import vcs')
46
47 def _get_repos_cached_initial(app_globals, initial):
48 """return cached dict with repos
49 """
50 g = app_globals
51 return HgModel().repo_scan(g.paths[0][1], g.baseui, initial)
52
53 @cache_region('long_term', 'cached_repo_list')
54 def _get_repos_cached():
55 """return cached dict with repos
56 """
57 log.info('getting all repositories list')
58 from pylons import app_globals as g
59 return HgModel().repo_scan(g.paths[0][1], g.baseui)
60
61 @cache_region('super_short_term', 'cached_repos_switcher_list')
62 def _get_repos_switcher_cached(cached_repo_list):
63 repos_lst = []
64 for repo in [x for x in cached_repo_list.values()]:
65 if HasRepoPermissionAny('repository.write', 'repository.read',
66 'repository.admin')(repo.name, 'main page check'):
67 repos_lst.append((repo.name, repo.dbrepo.private,))
68
69 return sorted(repos_lst, key=lambda k:k[0].lower())
70
71 @cache_region('long_term', 'full_changelog')
72 def _full_changelog_cached(repo_name):
73 log.info('getting full changelog for %s', repo_name)
74 return list(reversed(list(HgModel().get_repo(repo_name))))
75
76 class HgModel(object):
44 class HgModel(object):
77 """
45 """
78 Mercurial Model
46 Mercurial Model
@@ -84,6 +52,16 b' class HgModel(object):'
84 else:
52 else:
85 self.sa = sa
53 self.sa = sa
86
54
55
56 @LazyProperty
57 def repos_path(self):
58 """
59 Get's the repositories root path from database
60 """
61 q = self.sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one()
62
63 return q.ui_value
64
87 def repo_scan(self, repos_path, baseui, initial=False):
65 def repo_scan(self, repos_path, baseui, initial=False):
88 """
66 """
89 Listing of repositories in given path. This path should not be a
67 Listing of repositories in given path. This path should not be a
@@ -91,93 +69,100 b' class HgModel(object):'
91
69
92 :param repos_path: path to directory containing repositories
70 :param repos_path: path to directory containing repositories
93 :param baseui
71 :param baseui
94 :param initial: initial scann
72 :param initial: initial scan
95 """
73 """
96 log.info('scanning for repositories in %s', repos_path)
74 log.info('scanning for repositories in %s', repos_path)
97
75
98 if not isinstance(baseui, ui.ui):
76 if not isinstance(baseui, ui.ui):
99 baseui = ui.ui()
77 baseui = ui.ui()
100
101 from rhodecode.lib.utils import get_repos
102 repos = get_repos(repos_path)
103
104
105 repos_list = {}
78 repos_list = {}
106 for name, path in repos:
79 for name, path in get_repos(repos_path):
107 try:
80 try:
108 #name = name.split('/')[-1]
109 if repos_list.has_key(name):
81 if repos_list.has_key(name):
110 raise RepositoryError('Duplicate repository name %s found in'
82 raise RepositoryError('Duplicate repository name %s '
111 ' %s' % (name, path))
83 'found in %s' % (name, path))
112 else:
84 else:
85
86 klass = get_backend(path[0])
87
113 if path[0] == 'hg':
88 if path[0] == 'hg':
114 repos_list[name] = MercurialRepository(path[1], baseui=baseui)
89 repos_list[name] = klass(path[1], baseui=baseui)
115 repos_list[name].name = name
116
90
117 if path[0] == 'git':
91 if path[0] == 'git':
118 repos_list[name] = GitRepository(path[1])
92 repos_list[name] = klass(path[1])
119 repos_list[name].name = name
120
121 dbrepo = None
122 if not initial:
123 #for initial scann on application first run we don't
124 #have db repos yet.
125 dbrepo = self.sa.query(Repository)\
126 .options(joinedload(Repository.fork))\
127 .filter(Repository.repo_name == name)\
128 .scalar()
129
130 if dbrepo:
131 log.info('Adding db instance to cached list')
132 repos_list[name].dbrepo = dbrepo
133 repos_list[name].description = dbrepo.description
134 if dbrepo.user:
135 repos_list[name].contact = dbrepo.user.full_contact
136 else:
137 repos_list[name].contact = self.sa.query(User)\
138 .filter(User.admin == True).first().full_contact
139 except OSError:
93 except OSError:
140 continue
94 continue
141
95
142 return repos_list
96 return repos_list
143
97
144 def get_repos(self):
98 def get_repos(self, all_repos=None):
145 for name, repo in _get_repos_cached().items():
99 """
100 Get all repos from db and for each such repo make backend and
101 fetch dependent data from db
102 """
103 if not all_repos:
104 all_repos = self.sa.query(Repository).all()
146
105
147 if isinstance(repo, MercurialRepository) and repo._get_hidden():
106 for r in all_repos:
148 #skip hidden web repository
107
149 continue
108 repo = self.get(r.repo_name)
150
109
151 last_change = repo.last_change
110 if repo is not None:
152 tip = h.get_changeset_safe(repo, 'tip')
111 last_change = repo.last_change
112 tip = h.get_changeset_safe(repo, 'tip')
153
113
154 tmp_d = {}
114 tmp_d = {}
155 tmp_d['name'] = repo.name
115 tmp_d['name'] = repo.name
156 tmp_d['name_sort'] = tmp_d['name'].lower()
116 tmp_d['name_sort'] = tmp_d['name'].lower()
157 tmp_d['description'] = repo.description
117 tmp_d['description'] = repo.dbrepo.description
158 tmp_d['description_sort'] = tmp_d['description']
118 tmp_d['description_sort'] = tmp_d['description']
159 tmp_d['last_change'] = last_change
119 tmp_d['last_change'] = last_change
160 tmp_d['last_change_sort'] = time.mktime(last_change.timetuple())
120 tmp_d['last_change_sort'] = time.mktime(last_change.timetuple())
161 tmp_d['tip'] = tip.raw_id
121 tmp_d['tip'] = tip.raw_id
162 tmp_d['tip_sort'] = tip.revision
122 tmp_d['tip_sort'] = tip.revision
163 tmp_d['rev'] = tip.revision
123 tmp_d['rev'] = tip.revision
164 tmp_d['contact'] = repo.contact
124 tmp_d['contact'] = repo.dbrepo.user.full_contact
165 tmp_d['contact_sort'] = tmp_d['contact']
125 tmp_d['contact_sort'] = tmp_d['contact']
166 tmp_d['repo_archives'] = list(repo._get_archives())
126 tmp_d['repo_archives'] = list(repo._get_archives())
167 tmp_d['last_msg'] = tip.message
127 tmp_d['last_msg'] = tip.message
168 tmp_d['repo'] = repo
128 tmp_d['repo'] = repo
169 yield tmp_d
129 yield tmp_d
170
130
171 def get_repo(self, repo_name):
131 def get_repo(self, repo_name):
172 try:
132 return self.get(repo_name)
173 repo = _get_repos_cached()[repo_name]
133
174 return repo
134 def get(self, repo_name):
175 except KeyError:
135 """
176 #i we're here and we got key errors let's try to invalidate the
136 Get's repository from given name, creates BackendInstance and
177 #cahce and try again
137 propagates it's data from database with all additional information
178 invalidate_cache('cached_repo_list')
138 :param repo_name:
179 repo = _get_repos_cached()[repo_name]
139 """
140 if not HasRepoPermissionAny('repository.read', 'repository.write',
141 'repository.admin')(repo_name, 'get repo check'):
142 return
143
144 @cache_region('long_term', 'get_repo_cached_%s' % repo_name)
145 def _get_repo(repo_name):
146
147 repo = vcs_get_repo(os.path.join(self.repos_path, repo_name),
148 alias=None, create=False)
149
150 #skip hidden web repository
151 if isinstance(repo, MercurialRepository) and repo._get_hidden():
152 return
153
154 dbrepo = self.sa.query(Repository)\
155 .options(joinedload(Repository.fork))\
156 .options(joinedload(Repository.user))\
157 .filter(Repository.repo_name == repo_name)\
158 .scalar()
159 repo.dbrepo = dbrepo
180 return repo
160 return repo
181
161
162 invalidate = False
163 if invalidate:
164 log.info('INVALIDATING CACHE FOR %s', repo_name)
165 region_invalidate(_get_repo, None, repo_name)
182
166
167 return _get_repo(repo_name)
183
168
@@ -100,32 +100,32 b''
100 %for repo in c.user_repos:
100 %for repo in c.user_repos:
101 <tr>
101 <tr>
102 <td>
102 <td>
103 %if repo.dbrepo.repo_type =='hg':
103 %if repo['repo'].dbrepo.repo_type =='hg':
104 <img class="icon" title="${_('Mercurial repository')}" alt="${_('Mercurial repository')}" src="/images/icons/hgicon.png"/>
104 <img class="icon" title="${_('Mercurial repository')}" alt="${_('Mercurial repository')}" src="/images/icons/hgicon.png"/>
105 %elif repo.dbrepo.repo_type =='git':
105 %elif repo['repo'].dbrepo.repo_type =='git':
106 <img class="icon" title="${_('Git repository')}" alt="${_('Git repository')}" src="/images/icons/giticon.png"/>
106 <img class="icon" title="${_('Git repository')}" alt="${_('Git repository')}" src="/images/icons/giticon.png"/>
107 %else:
107 %else:
108
108
109 %endif
109 %endif
110 %if repo.dbrepo.private:
110 %if repo['repo'].dbrepo.private:
111 <img class="icon" alt="${_('private')}" src="/images/icons/lock.png"/>
111 <img class="icon" alt="${_('private')}" src="/images/icons/lock.png"/>
112 %else:
112 %else:
113 <img class="icon" alt="${_('public')}" src="/images/icons/lock_open.png"/>
113 <img class="icon" alt="${_('public')}" src="/images/icons/lock_open.png"/>
114 %endif
114 %endif
115
115
116 ${h.link_to(repo.name, h.url('summary_home',repo_name=repo.name),class_="repo_name")}
116 ${h.link_to(repo['repo'].name, h.url('summary_home',repo_name=repo['repo'].name),class_="repo_name")}
117 %if repo.dbrepo.fork:
117 %if repo['repo'].dbrepo.fork:
118 <a href="${h.url('summary_home',repo_name=repo.dbrepo.fork.repo_name)}">
118 <a href="${h.url('summary_home',repo_name=repo['repo'].dbrepo.fork.repo_name)}">
119 <img class="icon" alt="${_('public')}"
119 <img class="icon" alt="${_('public')}"
120 title="${_('Fork of')} ${repo.dbrepo.fork.repo_name}"
120 title="${_('Fork of')} ${repo['repo'].dbrepo.fork.repo_name}"
121 src="/images/icons/arrow_divide.png"/></a>
121 src="/images/icons/arrow_divide.png"/></a>
122 %endif
122 %endif
123 </td>
123 </td>
124 <td><span class="tooltip" tooltip_title="${repo.last_change}">${("r%s:%s") % (h.get_changeset_safe(repo,'tip').revision,h.short_id(h.get_changeset_safe(repo,'tip').raw_id))}</span></td>
124 <td><span class="tooltip" tooltip_title="${repo['repo'].last_change}">${("r%s:%s") % (h.get_changeset_safe(repo['repo'],'tip').revision,h.short_id(h.get_changeset_safe(repo['repo'],'tip').raw_id))}</span></td>
125 <td><a href="${h.url('repo_settings_home',repo_name=repo.name)}" title="${_('edit')}"><img class="icon" alt="${_('private')}" src="/images/icons/application_form_edit.png"/></a></td>
125 <td><a href="${h.url('repo_settings_home',repo_name=repo['repo'].name)}" title="${_('edit')}"><img class="icon" alt="${_('private')}" src="/images/icons/application_form_edit.png"/></a></td>
126 <td>
126 <td>
127 ${h.form(url('repo_settings_delete', repo_name=repo.name),method='delete')}
127 ${h.form(url('repo_settings_delete', repo_name=repo['repo'].name),method='delete')}
128 ${h.submit('remove_%s' % repo.name,'',class_="delete_icon action_button",onclick="return confirm('Confirm to delete this repository');")}
128 ${h.submit('remove_%s' % repo['repo'].name,'',class_="delete_icon action_button",onclick="return confirm('Confirm to delete this repository');")}
129 ${h.end_form()}
129 ${h.end_form()}
130 </td>
130 </td>
131 </tr>
131 </tr>
@@ -98,11 +98,12 b''
98 <span>&darr;</span>
98 <span>&darr;</span>
99 </a>
99 </a>
100 <ul class="repo_switcher">
100 <ul class="repo_switcher">
101 %for repo,private in c.repo_switcher_list:
101 %for repo in c.cached_repo_list:
102 %if private:
102
103 <li>${h.link_to(repo,h.url('summary_home',repo_name=repo),class_="private_repo")}</li>
103 %if repo['repo'].dbrepo.private:
104 <li>${h.link_to(repo['repo'].name,h.url('summary_home',repo_name=repo['repo'].name),class_="private_repo %s" % repo['repo'].dbrepo.repo_type)}</li>
104 %else:
105 %else:
105 <li>${h.link_to(repo,h.url('summary_home',repo_name=repo),class_="public_repo")}</li>
106 <li>${h.link_to(repo['repo'].name,h.url('summary_home',repo_name=repo['repo'].name),class_="public_repo %s" % repo['repo'].dbrepo.repo_type)}</li>
106 %endif
107 %endif
107 %endfor
108 %endfor
108 </ul>
109 </ul>
General Comments 0
You need to be logged in to leave comments. Login now