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 |
|
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(' |
|
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(' |
|
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( |
|
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(' |
|
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(' |
|
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 |
|
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 = |
|
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 = |
|
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(' |
|
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(' |
|
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. |
|
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 |
|
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 scan |
|
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 |
|
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] = |
|
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] = |
|
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>↓</span> |
|
98 | <span>↓</span> | |
99 | </a> |
|
99 | </a> | |
100 | <ul class="repo_switcher"> |
|
100 | <ul class="repo_switcher"> | |
101 |
%for repo |
|
101 | %for repo in c.cached_repo_list: | |
102 |
|
|
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