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