diff --git a/rhodecode/controllers/admin/repos.py b/rhodecode/controllers/admin/repos.py --- a/rhodecode/controllers/admin/repos.py +++ b/rhodecode/controllers/admin/repos.py @@ -147,6 +147,7 @@ class ReposController(BaseController): except formencode.Invalid, errors: c.repo_info = repo_model.get_by_repo_name(repo_name) + if c.repo_info.stats: last_rev = c.repo_info.stats.stat_on_revision else: @@ -281,8 +282,9 @@ class ReposController(BaseController): def edit(self, repo_name, format='html'): """GET /repos/repo_name/edit: Form to edit an existing item""" # url('edit_repo', repo_name=ID) + r = ScmModel().get(repo_name)[0] + repo_model = RepoModel() - r = ScmModel().get(repo_name) c.repo_info = repo_model.get_by_repo_name(repo_name) if c.repo_info is None: diff --git a/rhodecode/controllers/branches.py b/rhodecode/controllers/branches.py --- a/rhodecode/controllers/branches.py +++ b/rhodecode/controllers/branches.py @@ -45,8 +45,7 @@ class BranchesController(BaseController) super(BranchesController, self).__before__() def index(self): - hg_model = ScmModel() - c.repo_info = hg_model.get_repo(c.repo_name) + c.repo_info, dbrepo = ScmModel().get(c.repo_name, retval='repo') c.repo_branches = OrderedDict() for name, hash_ in c.repo_info.branches.items(): c.repo_branches[name] = c.repo_info.get_changeset(hash_) diff --git a/rhodecode/controllers/changelog.py b/rhodecode/controllers/changelog.py --- a/rhodecode/controllers/changelog.py +++ b/rhodecode/controllers/changelog.py @@ -67,14 +67,14 @@ class ChangelogController(BaseController else: c.size = int(session.get('changelog_size', default)) - changesets = ScmModel().get_repo(c.repo_name) + repo, dbrepo = ScmModel().get(c.repo_name, retval='repo') p = int(request.params.get('page', 1)) - c.total_cs = len(changesets) - c.pagination = Page(changesets, page=p, item_count=c.total_cs, + c.total_cs = len(repo) + c.pagination = Page(repo, page=p, item_count=c.total_cs, items_per_page=c.size) - self._graph(changesets, c.size, p) + self._graph(repo, c.size, p) return render('changelog/changelog.html') diff --git a/rhodecode/controllers/changeset.py b/rhodecode/controllers/changeset.py --- a/rhodecode/controllers/changeset.py +++ b/rhodecode/controllers/changeset.py @@ -55,7 +55,6 @@ class ChangesetController(BaseController super(ChangesetController, self).__before__() def index(self, revision): - hg_model = ScmModel() def wrap_to_table(str): @@ -70,7 +69,7 @@ class ChangesetController(BaseController rev_range = revision.split('...')[:2] range_limit = 50 try: - repo = hg_model.get_repo(c.repo_name) + repo, dbrepo = ScmModel().get(c.repo_name, retval='repo') if len(rev_range) == 2: rev_start = rev_range[0] rev_end = rev_range[1] @@ -163,12 +162,11 @@ class ChangesetController(BaseController def raw_changeset(self, revision): - hg_model = ScmModel() method = request.GET.get('diff', 'show') try: - r = hg_model.get_repo(c.repo_name) - c.scm_type = r.alias - c.changeset = r.get_changeset(revision) + repo, dbrepo = ScmModel().get(c.repo_name, retval='repo') + c.scm_type = repo.alias + c.changeset = repo.get_changeset(revision) except RepositoryError: log.error(traceback.format_exc()) return redirect(url('home')) diff --git a/rhodecode/controllers/feed.py b/rhodecode/controllers/feed.py --- a/rhodecode/controllers/feed.py +++ b/rhodecode/controllers/feed.py @@ -28,6 +28,7 @@ import logging from pylons import url, response +from pylons.i18n.translation import _ from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator from rhodecode.lib.base import BaseController @@ -45,7 +46,7 @@ class FeedController(BaseController): def __before__(self): super(FeedController, self).__before__() #common values for feeds - self.description = 'Changes on %s repository' + self.description = _('Changes on %s repository') self.title = "%s feed" self.language = 'en-us' self.ttl = "5" @@ -59,9 +60,9 @@ class FeedController(BaseController): language=self.language, ttl=self.ttl) - changesets = ScmModel().get_repo(repo_name) + repo, dbrepo = ScmModel().get(repo_name, retval='repo') - for cs in changesets[:self.feed_nr]: + for cs in repo[:self.feed_nr]: feed.add_item(title=cs.message, link=url('changeset_home', repo_name=repo_name, revision=cs.raw_id, qualified=True), @@ -79,8 +80,8 @@ class FeedController(BaseController): language=self.language, ttl=self.ttl) - changesets = ScmModel().get_repo(repo_name) - for cs in changesets[:self.feed_nr]: + repo, dbrepo = ScmModel().get(repo_name, retval='repo') + for cs in repo[:self.feed_nr]: feed.add_item(title=cs.message, link=url('changeset_home', repo_name=repo_name, revision=cs.raw_id, qualified=True), diff --git a/rhodecode/controllers/files.py b/rhodecode/controllers/files.py --- a/rhodecode/controllers/files.py +++ b/rhodecode/controllers/files.py @@ -57,8 +57,8 @@ class FilesController(BaseController): c.cut_off_limit = self.cut_off_limit def index(self, repo_name, revision, f_path): - hg_model = ScmModel() - c.repo = hg_model.get_repo(c.repo_name) + c.repo, dbrepo = ScmModel().get(c.repo_name, retval='repo') + try: #reditect to given revision from form @@ -116,8 +116,7 @@ class FilesController(BaseController): return render('files/files.html') def rawfile(self, repo_name, revision, f_path): - hg_model = ScmModel() - c.repo = hg_model.get_repo(c.repo_name) + c.repo, dbrepo = ScmModel().get(c.repo_name, retval='repo') file_node = c.repo.get_changeset(revision).get_node(f_path) response.content_type = file_node.mimetype response.content_disposition = 'attachment; filename=%s' \ @@ -125,16 +124,14 @@ class FilesController(BaseController): return file_node.content def raw(self, repo_name, revision, f_path): - hg_model = ScmModel() - c.repo = hg_model.get_repo(c.repo_name) + c.repo, dbrepo = ScmModel().get(c.repo_name, retval='repo') file_node = c.repo.get_changeset(revision).get_node(f_path) response.content_type = 'text/plain' return file_node.content def annotate(self, repo_name, revision, f_path): - hg_model = ScmModel() - c.repo = hg_model.get_repo(c.repo_name) + c.repo, dbrepo = ScmModel().get(c.repo_name, retval='repo') try: c.cs = c.repo.get_changeset(revision) @@ -163,9 +160,9 @@ class FilesController(BaseController): ext = ext_data[1] try: - repo = ScmModel().get_repo(repo_name) + repo, dbrepo = ScmModel().get(repo_name) - if repo.dbrepo.enable_downloads is False: + if dbrepo.enable_downloads is False: return _('downloads disabled') cs = repo.get_changeset(revision) @@ -185,13 +182,12 @@ class FilesController(BaseController): def diff(self, repo_name, f_path): - hg_model = ScmModel() diff1 = request.GET.get('diff1') diff2 = request.GET.get('diff2') c.action = request.GET.get('diff') c.no_changes = diff1 == diff2 c.f_path = f_path - c.repo = hg_model.get_repo(c.repo_name) + c.repo, dbrepo = ScmModel().get(c.repo_name, retval='repo') try: if diff1 not in ['', None, 'None', '0' * 12, '0' * 40]: diff --git a/rhodecode/controllers/shortlog.py b/rhodecode/controllers/shortlog.py --- a/rhodecode/controllers/shortlog.py +++ b/rhodecode/controllers/shortlog.py @@ -47,7 +47,7 @@ class ShortlogController(BaseController) def index(self): p = int(request.params.get('page', 1)) - repo = ScmModel().get_repo(c.repo_name) + repo, dbrepo = ScmModel().get(c.repo_name, 'repo') c.repo_changesets = Page(repo, page=p, items_per_page=20) c.shortlog_data = render('shortlog/shortlog_data.html') if request.params.get('partial'): diff --git a/rhodecode/controllers/summary.py b/rhodecode/controllers/summary.py --- a/rhodecode/controllers/summary.py +++ b/rhodecode/controllers/summary.py @@ -64,13 +64,14 @@ class SummaryController(BaseController): def index(self): scm_model = ScmModel() - c.repo_info = scm_model.get_repo(c.repo_name) + c.repo, dbrepo = scm_model.get(c.repo_name) + c.dbrepo = dbrepo c.following = scm_model.is_following_repo(c.repo_name, c.rhodecode_user.user_id) def url_generator(**kw): return url('shortlog_home', repo_name=c.repo_name, **kw) - c.repo_changesets = Page(c.repo_info, page=1, items_per_page=10, + c.repo_changesets = Page(c.repo, page=1, items_per_page=10, url=url_generator) e = request.environ @@ -92,16 +93,16 @@ class SummaryController(BaseController): 'repo_name':c.repo_name, } c.clone_repo_url = uri c.repo_tags = OrderedDict() - for name, hash in c.repo_info.tags.items()[:10]: + for name, hash in c.repo.tags.items()[:10]: try: - c.repo_tags[name] = c.repo_info.get_changeset(hash) + c.repo_tags[name] = c.repo.get_changeset(hash) except ChangesetError: c.repo_tags[name] = EmptyChangeset(hash) c.repo_branches = OrderedDict() - for name, hash in c.repo_info.branches.items()[:10]: + for name, hash in c.repo.branches.items()[:10]: try: - c.repo_branches[name] = c.repo_info.get_changeset(hash) + c.repo_branches[name] = c.repo.get_changeset(hash) except ChangesetError: c.repo_branches[name] = EmptyChangeset(hash) @@ -113,21 +114,21 @@ class SummaryController(BaseController): ts_min_y = mktime(td_1y.timetuple()) ts_max_y = mktime(td.timetuple()) - if c.repo_info.dbrepo.enable_statistics: + if dbrepo.enable_statistics: c.no_data_msg = _('No data loaded yet') - run_task(get_commits_stats, c.repo_info.name, ts_min_y, ts_max_y) + run_task(get_commits_stats, c.repo.name, ts_min_y, ts_max_y) else: c.no_data_msg = _('Statistics update are disabled for this repository') c.ts_min = ts_min_m c.ts_max = ts_max_y stats = self.sa.query(Statistics)\ - .filter(Statistics.repository == c.repo_info.dbrepo)\ + .filter(Statistics.repository == dbrepo)\ .scalar() if stats and stats.languages: - c.no_data = False is c.repo_info.dbrepo.enable_statistics + c.no_data = False is dbrepo.enable_statistics lang_stats = json.loads(stats.languages) c.commit_data = stats.commit_activity c.overview_data = stats.commit_activity_combined @@ -142,9 +143,9 @@ class SummaryController(BaseController): c.trending_languages = json.dumps({}) c.no_data = True - c.enable_downloads = c.repo_info.dbrepo.enable_downloads + c.enable_downloads = dbrepo.enable_downloads if c.enable_downloads: - c.download_options = self._get_download_links(c.repo_info) + c.download_options = self._get_download_links(c.repo) return render('summary/summary.html') diff --git a/rhodecode/controllers/tags.py b/rhodecode/controllers/tags.py --- a/rhodecode/controllers/tags.py +++ b/rhodecode/controllers/tags.py @@ -44,8 +44,7 @@ class TagsController(BaseController): super(TagsController, self).__before__() def index(self): - hg_model = ScmModel() - c.repo_info = hg_model.get_repo(c.repo_name) + c.repo_info, dbrepo = ScmModel().get(c.repo_name, retval='repo') c.repo_tags = OrderedDict() for name, hash_ in c.repo_info.tags.items(): c.repo_tags[name] = c.repo_info.get_changeset(hash_) diff --git a/rhodecode/lib/base.py b/rhodecode/lib/base.py --- a/rhodecode/lib/base.py +++ b/rhodecode/lib/base.py @@ -28,12 +28,12 @@ class BaseController(WSGIController): #c.unread_journal = scm_model.get_unread_journal() if c.repo_name: - cached_repo = scm_model.get(c.repo_name) - if cached_repo: - c.repository_tags = cached_repo.tags - c.repository_branches = cached_repo.branches - c.repository_followers = scm_model.get_followers(cached_repo.dbrepo.repo_id) - c.repository_forks = scm_model.get_forks(cached_repo.dbrepo.repo_id) + repo, dbrepo = scm_model.get(c.repo_name) + if repo: + c.repository_tags = repo.tags + c.repository_branches = repo.branches + c.repository_followers = scm_model.get_followers(dbrepo.repo_id) + c.repository_forks = scm_model.get_forks(dbrepo.repo_id) else: c.repository_tags = {} c.repository_branches = {} diff --git a/rhodecode/lib/helpers.py b/rhodecode/lib/helpers.py --- a/rhodecode/lib/helpers.py +++ b/rhodecode/lib/helpers.py @@ -483,12 +483,12 @@ def action_parser(user_log): def get_fork_name(): from rhodecode.model.scm import ScmModel repo_name = action_params - repo = ScmModel().get(repo_name) + repo, dbrepo = ScmModel().get(repo_name) if repo is None: return repo_name return link_to(action_params, url('summary_home', repo_name=repo.name,), - title=repo.dbrepo.description) + title=dbrepo.description) map = {'user_deleted_repo':(_('User [deleted] repository'), None), 'user_created_repo':(_('User [created] repository'), None), diff --git a/rhodecode/model/repo.py b/rhodecode/model/repo.py --- a/rhodecode/model/repo.py +++ b/rhodecode/model/repo.py @@ -87,7 +87,7 @@ class RepoModel(BaseModel): if cache: repo = repo.options(FromCache("sql_cache_long", "get_repo_full_%s" % repo_name)) - if invalidate: + if invalidate and cache: repo.invalidate() return repo.scalar() diff --git a/rhodecode/model/scm.py b/rhodecode/model/scm.py --- a/rhodecode/model/scm.py +++ b/rhodecode/model/scm.py @@ -31,8 +31,6 @@ import logging from mercurial import ui -from sqlalchemy.orm import joinedload -from sqlalchemy.orm.session import make_transient from sqlalchemy.exc import DatabaseError from beaker.cache import cache_region, region_invalidate @@ -45,9 +43,11 @@ from vcs.utils.lazy import LazyProperty from rhodecode import BACKENDS from rhodecode.lib import helpers as h from rhodecode.lib.auth import HasRepoPermissionAny -from rhodecode.lib.utils import get_repos as get_filesystem_repos, make_ui, action_logger +from rhodecode.lib.utils import get_repos as get_filesystem_repos, make_ui, \ + action_logger from rhodecode.model import BaseModel from rhodecode.model.user import UserModel +from rhodecode.model.repo import RepoModel from rhodecode.model.db import Repository, RhodeCodeUi, CacheInvalidation, \ UserFollowing, UserLog from rhodecode.model.caching_query import FromCache @@ -82,18 +82,19 @@ class ScmModel(BaseModel): return q.ui_value - def repo_scan(self, repos_path, baseui): + def repo_scan(self, repos_path=None): """Listing of repositories in given path. This path should not be a repository itself. Return a dictionary of repository objects :param repos_path: path to directory containing repositories - :param baseui: baseui instance to instantiate MercurialRepostitory with """ log.info('scanning for repositories in %s', repos_path) - if not isinstance(baseui, ui.ui): - baseui = make_ui('db') + if repos_path is None: + repos_path = self.repos_path + + baseui = make_ui('db') repos_list = {} for name, path in get_filesystem_repos(repos_path, recursive=True): @@ -134,7 +135,7 @@ class ScmModel(BaseModel): for r in all_repos: - repo = self.get(r.repo_name, invalidation_list) + repo, dbrepo = self.get(r.repo_name, invalidation_list) if repo is not None: last_change = repo.last_change @@ -143,33 +144,34 @@ class ScmModel(BaseModel): tmp_d = {} tmp_d['name'] = r.repo_name tmp_d['name_sort'] = tmp_d['name'].lower() - tmp_d['description'] = repo.dbrepo.description + tmp_d['description'] = dbrepo.description tmp_d['description_sort'] = tmp_d['description'] tmp_d['last_change'] = last_change tmp_d['last_change_sort'] = time.mktime(last_change.timetuple()) tmp_d['tip'] = tip.raw_id tmp_d['tip_sort'] = tip.revision tmp_d['rev'] = tip.revision - tmp_d['contact'] = repo.dbrepo.user.full_contact + tmp_d['contact'] = dbrepo.user.full_contact tmp_d['contact_sort'] = tmp_d['contact'] tmp_d['owner_sort'] = tmp_d['contact'] tmp_d['repo_archives'] = list(repo._get_archives()) tmp_d['last_msg'] = tip.message tmp_d['repo'] = repo + tmp_d['dbrepo'] = dbrepo yield tmp_d - def get_repo(self, repo_name): - return self.get(repo_name) - - def get(self, repo_name, invalidation_list=None): - """Get's repository from given name, creates BackendInstance and + def get(self, repo_name, invalidation_list=None, retval='all'): + """Returns a tuple of Repository,DbRepository, + Get's repository from given name, creates BackendInstance and propagates it's data from database with all additional information :param repo_name: :param invalidation_list: if a invalidation list is given the get method should not manually check if this repository needs invalidation and just invalidate the repositories in list - + :param retval: string specifing what to return one of 'repo','dbrepo', + 'all'if repo or dbrepo is given it'll just lazy load chosen type + and return None as the second """ if not HasRepoPermissionAny('repository.read', 'repository.write', 'repository.admin')(repo_name, 'get repo check'): @@ -189,58 +191,45 @@ class ScmModel(BaseModel): backend = get_backend(alias) except VCSError: log.error(traceback.format_exc()) - log.error('Perhaps this repository is in db and not in filesystem' - 'run rescan repositories with "destroy old data "' - 'option from admin panel') + log.error('Perhaps this repository is in db and not in ' + 'filesystem run rescan repositories with ' + '"destroy old data " option from admin panel') return if alias == 'hg': - from pylons import app_globals as g - repo = backend(repo_path, create=False, baseui=g.baseui) + repo = backend(repo_path, create=False, baseui=make_ui('db')) #skip hidden web repository if repo._get_hidden(): return else: repo = backend(repo_path, create=False) - dbrepo = self.sa.query(Repository)\ - .options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ - .filter(Repository.repo_name == repo_name)\ - .scalar() - - self.sa.expunge_all() - log.debug('making transient %s', dbrepo) - make_transient(dbrepo) - - for attr in ['user', 'forks', 'followers', 'group', 'repo_to_perm', - 'users_group_to_perm', 'stats', 'logs']: - attr = getattr(dbrepo, attr, False) - if attr: - if isinstance(attr, list): - for a in attr: - log.debug('making transient %s', a) - make_transient(a) - else: - log.debug('making transient %s', attr) - make_transient(attr) - - repo.dbrepo = dbrepo return repo pre_invalidate = True + dbinvalidate = False + if invalidation_list is not None: pre_invalidate = repo_name in invalidation_list if pre_invalidate: + #this returns object to invalidate invalidate = self._should_invalidate(repo_name) - if invalidate: log.info('invalidating cache for repository %s', repo_name) - region_invalidate(_get_repo, None, repo_name) + #region_invalidate(_get_repo, None, repo_name) self._mark_invalidated(invalidate) + dbinvalidate = True - return _get_repo(repo_name) + r, dbr = None, None + if retval == 'repo' or 'all': + r = _get_repo(repo_name) + if retval == 'dbrepo' or 'all': + dbr = RepoModel(self.sa).get_full(repo_name, cache=True, + invalidate=dbinvalidate) + + + return r, dbr @@ -370,8 +359,6 @@ class ScmModel(BaseModel): """ ret = self.sa.query(CacheInvalidation)\ - .options(FromCache('sql_cache_short', - 'get_invalidation_%s' % repo_name))\ .filter(CacheInvalidation.cache_key == repo_name)\ .filter(CacheInvalidation.cache_active == False)\ .scalar() @@ -379,7 +366,8 @@ class ScmModel(BaseModel): return ret def _mark_invalidated(self, cache_key): - """ Marks all occurences of cache to invaldation as already invalidated + """ Marks all occurrences of cache to invalidation as already + invalidated :param cache_key: """ diff --git a/rhodecode/templates/admin/repos/repos.html b/rhodecode/templates/admin/repos/repos.html --- a/rhodecode/templates/admin/repos/repos.html +++ b/rhodecode/templates/admin/repos/repos.html @@ -38,26 +38,26 @@