# HG changeset patch # User Marcin Kuzminski # Date 1297730167 -3600 # Node ID 3fc9183e05dd27cea5916a3c6cbae943c17b28b8 # Parent f3402cb92fdf0790116e30751dad0d3be83f475d another major codes rewrite: - created BaseRepo controller for all repo specific controller, and added common data propagation - removed obosete codes, and made optimizations, removed to often calls to RepoModel - fixed found bugs in files controller that generated unhandled 500 errors - cache issues - removed repo_branches global template values - journal fixes - main repo list is fully dict now it's less resource heavy that way diff -r f3402cb92fdf -r 3fc9183e05dd rhodecode/controllers/admin/settings.py --- a/rhodecode/controllers/admin/settings.py Mon Feb 14 16:43:57 2011 +0100 +++ b/rhodecode/controllers/admin/settings.py Tue Feb 15 01:36:07 2011 +0100 @@ -257,11 +257,9 @@ # url('admin_settings_my_account') c.user = UserModel().get(c.rhodecode_user.user_id, cache=False) - all_repos = self.sa.query(Repository)\ - .filter(Repository.user_id == c.user.user_id)\ - .order_by(func.lower(Repository.repo_name))\ - .all() - + all_repos = [r.repo_name for r in self.sa.query(Repository)\ + .filter(Repository.user_id == c.user.user_id)\ + .order_by(func.lower(Repository.repo_name)).all()] c.user_repos = ScmModel().get_repos(all_repos) if c.user.username == 'default': diff -r f3402cb92fdf -r 3fc9183e05dd rhodecode/controllers/branches.py --- a/rhodecode/controllers/branches.py Mon Feb 14 16:43:57 2011 +0100 +++ b/rhodecode/controllers/branches.py Tue Feb 15 01:36:07 2011 +0100 @@ -30,13 +30,12 @@ from pylons import tmpl_context as c from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator -from rhodecode.lib.base import BaseController, render +from rhodecode.lib.base import BaseRepoController, render from rhodecode.lib.utils import OrderedDict -from rhodecode.model.scm import ScmModel log = logging.getLogger(__name__) -class BranchesController(BaseController): +class BranchesController(BaseRepoController): @LoginRequired() @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', @@ -45,9 +44,9 @@ super(BranchesController, self).__before__() def index(self): - 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_) + for name, hash_ in c.rhodecode_repo.branches.items(): + c.repo_branches[name] = c.rhodecode_repo.get_changeset(hash_) return render('branches/branches.html') diff -r f3402cb92fdf -r 3fc9183e05dd rhodecode/controllers/changelog.py --- a/rhodecode/controllers/changelog.py Mon Feb 14 16:43:57 2011 +0100 +++ b/rhodecode/controllers/changelog.py Tue Feb 15 01:36:07 2011 +0100 @@ -37,14 +37,13 @@ from pylons import request, session, tmpl_context as c from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator -from rhodecode.lib.base import BaseController, render -from rhodecode.model.scm import ScmModel +from rhodecode.lib.base import BaseRepoController, render from webhelpers.paginate import Page log = logging.getLogger(__name__) -class ChangelogController(BaseController): +class ChangelogController(BaseRepoController): @LoginRequired() @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', @@ -67,14 +66,12 @@ else: c.size = int(session.get('changelog_size', default)) - repo, dbrepo = ScmModel().get(c.repo_name, retval='repo') - p = int(request.params.get('page', 1)) - c.total_cs = len(repo) - c.pagination = Page(repo, page=p, item_count=c.total_cs, + c.total_cs = len(c.rhodecode_repo) + c.pagination = Page(c.rhodecode_repo, page=p, item_count=c.total_cs, items_per_page=c.size) - self._graph(repo, c.size, p) + self._graph(c.rhodecode_repo, c.size, p) return render('changelog/changelog.html') diff -r f3402cb92fdf -r 3fc9183e05dd rhodecode/controllers/changeset.py --- a/rhodecode/controllers/changeset.py Mon Feb 14 16:43:57 2011 +0100 +++ b/rhodecode/controllers/changeset.py Tue Feb 15 01:36:07 2011 +0100 @@ -34,9 +34,8 @@ import rhodecode.lib.helpers as h from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator -from rhodecode.lib.base import BaseController, render +from rhodecode.lib.base import BaseRepoController, render from rhodecode.lib.utils import EmptyChangeset -from rhodecode.model.scm import ScmModel from vcs.exceptions import RepositoryError, ChangesetError, \ ChangesetDoesNotExistError @@ -46,7 +45,7 @@ log = logging.getLogger(__name__) -class ChangesetController(BaseController): +class ChangesetController(BaseRepoController): @LoginRequired() @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', @@ -69,14 +68,13 @@ rev_range = revision.split('...')[:2] range_limit = 50 try: - repo, dbrepo = ScmModel().get(c.repo_name, retval='repo') if len(rev_range) == 2: rev_start = rev_range[0] rev_end = rev_range[1] - rev_ranges = repo.get_changesets_ranges(rev_start, rev_end, + rev_ranges = c.rhodecode_repo.get_changesets_ranges(rev_start, rev_end, range_limit) else: - rev_ranges = [repo.get_changeset(revision)] + rev_ranges = [c.rhodecode_repo.get_changeset(revision)] c.cs_ranges = list(rev_ranges) @@ -164,9 +162,8 @@ method = request.GET.get('diff', 'show') try: - repo, dbrepo = ScmModel().get(c.repo_name, retval='repo') - c.scm_type = repo.alias - c.changeset = repo.get_changeset(revision) + c.scm_type = c.rhodecode_repo.alias + c.changeset = c.rhodecode_repo.get_changeset(revision) except RepositoryError: log.error(traceback.format_exc()) return redirect(url('home')) @@ -182,7 +179,7 @@ if filenode_old.is_binary or node.is_binary: diff = _('binary file') + '\n' else: - f_udiff = differ.get_udiff(filenode_old, node) + f_udiff = differ.get_gitdiff(filenode_old, node) diff = differ.DiffProcessor(f_udiff).raw_diff() cs1 = None @@ -194,7 +191,7 @@ if filenode_old.is_binary or node.is_binary: diff = _('binary file') else: - f_udiff = differ.get_udiff(filenode_old, node) + f_udiff = differ.get_gitdiff(filenode_old, node) diff = differ.DiffProcessor(f_udiff).raw_diff() cs1 = filenode_old.last_changeset.raw_id diff -r f3402cb92fdf -r 3fc9183e05dd rhodecode/controllers/feed.py --- a/rhodecode/controllers/feed.py Mon Feb 14 16:43:57 2011 +0100 +++ b/rhodecode/controllers/feed.py Tue Feb 15 01:36:07 2011 +0100 @@ -27,18 +27,17 @@ import logging -from pylons import url, response +from pylons import url, response, tmpl_context as c from pylons.i18n.translation import _ from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator -from rhodecode.lib.base import BaseController -from rhodecode.model.scm import ScmModel +from rhodecode.lib.base import BaseRepoController from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed log = logging.getLogger(__name__) -class FeedController(BaseController): +class FeedController(BaseRepoController): @LoginRequired() @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', @@ -60,9 +59,7 @@ language=self.language, ttl=self.ttl) - repo, dbrepo = ScmModel().get(repo_name, retval='repo') - - for cs in repo[:self.feed_nr]: + for cs in c.rhodecode_repo[:self.feed_nr]: feed.add_item(title=cs.message, link=url('changeset_home', repo_name=repo_name, revision=cs.raw_id, qualified=True), @@ -80,8 +77,7 @@ language=self.language, ttl=self.ttl) - repo, dbrepo = ScmModel().get(repo_name, retval='repo') - for cs in repo[:self.feed_nr]: + for cs in c.rhodecode_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 -r f3402cb92fdf -r 3fc9183e05dd rhodecode/controllers/files.py --- a/rhodecode/controllers/files.py Mon Feb 14 16:43:57 2011 +0100 +++ b/rhodecode/controllers/files.py Tue Feb 15 01:36:07 2011 +0100 @@ -24,30 +24,28 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301, USA. -import tempfile import logging import rhodecode.lib.helpers as h -from mercurial import archival - from pylons import request, response, session, tmpl_context as c, url from pylons.i18n.translation import _ from pylons.controllers.util import redirect from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator -from rhodecode.lib.base import BaseController, render +from rhodecode.lib.base import BaseRepoController, render from rhodecode.lib.utils import EmptyChangeset -from rhodecode.model.scm import ScmModel +from rhodecode.model.repo import RepoModel from vcs.backends import ARCHIVE_SPECS from vcs.exceptions import RepositoryError, ChangesetError, \ - ChangesetDoesNotExistError, EmptyRepositoryError, ImproperArchiveTypeError -from vcs.nodes import FileNode + ChangesetDoesNotExistError, EmptyRepositoryError, ImproperArchiveTypeError, \ + VCSError +from vcs.nodes import FileNode, NodeKind from vcs.utils import diffs as differ log = logging.getLogger(__name__) -class FilesController(BaseController): +class FilesController(BaseRepoController): @LoginRequired() @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', @@ -56,15 +54,30 @@ super(FilesController, self).__before__() c.cut_off_limit = self.cut_off_limit + def __get_cs(self, rev, repo_name): + """ + Safe way to get changeset if error ucure it redirects to given + :param rev: revision to fetch + :param repo_name: repo name to redirect after + """ + + try: + return c.rhodecode_repo.get_changeset(rev) + except EmptyRepositoryError, e: + h.flash(_('There are no files yet'), category='warning') + redirect(h.url('summary_home', repo_name=repo_name)) + + except RepositoryError, e: + h.flash(str(e), category='warning') + redirect(h.url('files_home', repo_name=repo_name, revision='tip')) + def index(self, repo_name, revision, f_path): - c.repo, dbrepo = ScmModel().get(c.repo_name, retval='repo') - try: #reditect to given revision from form post_revision = request.POST.get('at_rev', None) if post_revision: - post_revision = c.repo.get_changeset(post_revision).raw_id + post_revision = c.rhodecode_repo.get_changeset(post_revision).raw_id redirect(url('files_home', repo_name=c.repo_name, revision=post_revision, f_path=f_path)) @@ -72,33 +85,33 @@ c.f_path = f_path - c.changeset = c.repo.get_changeset(revision) + c.changeset = c.rhodecode_repo.get_changeset(revision) cur_rev = c.changeset.revision #prev link try: - prev_rev = c.repo.get_changeset(cur_rev).prev(c.branch).raw_id + prev_rev = c.rhodecode_repo.get_changeset(cur_rev).prev(c.branch).raw_id c.url_prev = url('files_home', repo_name=c.repo_name, revision=prev_rev, f_path=f_path) if c.branch: c.url_prev += '?branch=%s' % c.branch - except ChangesetDoesNotExistError: + except (ChangesetDoesNotExistError, VCSError): c.url_prev = '#' #next link try: - next_rev = c.repo.get_changeset(cur_rev).next(c.branch).raw_id + next_rev = c.rhodecode_repo.get_changeset(cur_rev).next(c.branch).raw_id c.url_next = url('files_home', repo_name=c.repo_name, revision=next_rev, f_path=f_path) if c.branch: c.url_next += '?branch=%s' % c.branch - except ChangesetDoesNotExistError: + except (ChangesetDoesNotExistError, VCSError): c.url_next = '#' #files try: c.files_list = c.changeset.get_node(f_path) - c.file_history = self._get_history(c.repo, c.files_list, f_path) + c.file_history = self._get_history(c.rhodecode_repo, c.files_list, f_path) except RepositoryError, e: h.flash(str(e), category='warning') redirect(h.url('files_home', repo_name=repo_name, revision=revision)) @@ -116,32 +129,40 @@ return render('files/files.html') def rawfile(self, repo_name, revision, f_path): - c.repo, dbrepo = ScmModel().get(c.repo_name, retval='repo') - file_node = c.repo.get_changeset(revision).get_node(f_path) + cs = self.__get_cs(revision, repo_name) + try: + file_node = cs.get_node(f_path) + except RepositoryError, e: + h.flash(str(e), category='warning') + redirect(h.url('files_home', repo_name=repo_name, revision=cs.raw_id)) + response.content_type = file_node.mimetype response.content_disposition = 'attachment; filename=%s' \ % f_path.split('/')[-1] return file_node.content def raw(self, repo_name, revision, f_path): - c.repo, dbrepo = ScmModel().get(c.repo_name, retval='repo') - file_node = c.repo.get_changeset(revision).get_node(f_path) + cs = self.__get_cs(revision, repo_name) + try: + file_node = cs.get_node(f_path) + except RepositoryError, e: + h.flash(str(e), category='warning') + redirect(h.url('files_home', repo_name=repo_name, revision=cs.raw_id)) + response.content_type = 'text/plain' return file_node.content def annotate(self, repo_name, revision, f_path): - c.repo, dbrepo = ScmModel().get(c.repo_name, retval='repo') - + cs = self.__get_cs(revision, repo_name) try: - c.cs = c.repo.get_changeset(revision) - c.file = c.cs.get_node(f_path) + c.file = cs.get_node(f_path) except RepositoryError, e: h.flash(str(e), category='warning') - redirect(h.url('files_home', repo_name=repo_name, revision=revision)) + redirect(h.url('files_home', repo_name=repo_name, revision=cs.raw_id)) - c.file_history = self._get_history(c.repo, c.file, f_path) - + c.file_history = self._get_history(c.rhodecode_repo, c.file, f_path) + c.cs = cs c.f_path = f_path return render('files/files_annotate.html') @@ -160,12 +181,11 @@ ext = ext_data[1] try: - repo, dbrepo = ScmModel().get(repo_name) - + dbrepo = RepoModel().get_by_repo_name(repo_name) if dbrepo.enable_downloads is False: return _('downloads disabled') - cs = repo.get_changeset(revision) + cs = c.rhodecode_repo.get_changeset(revision) content_type = ARCHIVE_SPECS[fileformat][0] except ChangesetDoesNotExistError: return _('Unknown revision %s') % revision @@ -187,18 +207,17 @@ c.action = request.GET.get('diff') c.no_changes = diff1 == diff2 c.f_path = f_path - c.repo, dbrepo = ScmModel().get(c.repo_name, retval='repo') try: if diff1 not in ['', None, 'None', '0' * 12, '0' * 40]: - c.changeset_1 = c.repo.get_changeset(diff1) + c.changeset_1 = c.rhodecode_repo.get_changeset(diff1) node1 = c.changeset_1.get_node(f_path) else: c.changeset_1 = EmptyChangeset() node1 = FileNode('.', '', changeset=c.changeset_1) if diff2 not in ['', None, 'None', '0' * 12, '0' * 40]: - c.changeset_2 = c.repo.get_changeset(diff2) + c.changeset_2 = c.rhodecode_repo.get_changeset(diff2) node2 = c.changeset_2.get_node(f_path) else: c.changeset_2 = EmptyChangeset() @@ -245,7 +264,6 @@ return render('files/file_diff.html') def _get_history(self, repo, node, f_path): - from vcs.nodes import NodeKind if not node.kind is NodeKind.FILE: return [] changesets = node.history @@ -261,12 +279,12 @@ hist_l.append(changesets_group) - for name, chs in c.repository_branches.items(): + for name, chs in c.rhodecode_repo.branches.items(): #chs = chs.split(':')[-1] branches_group[0].append((chs, name),) hist_l.append(branches_group) - for name, chs in c.repository_tags.items(): + for name, chs in c.rhodecode_repo.tags.items(): #chs = chs.split(':')[-1] tags_group[0].append((chs, name),) hist_l.append(tags_group) diff -r f3402cb92fdf -r 3fc9183e05dd rhodecode/controllers/home.py --- a/rhodecode/controllers/home.py Mon Feb 14 16:43:57 2011 +0100 +++ b/rhodecode/controllers/home.py Tue Feb 15 01:36:07 2011 +0100 @@ -32,7 +32,6 @@ from rhodecode.lib.auth import LoginRequired from rhodecode.lib.base import BaseController, render -from rhodecode.model.scm import ScmModel log = logging.getLogger(__name__) @@ -53,14 +52,14 @@ else: c.sort_by = current_sort c.sort_slug = current_sort_slug - cached_repo_list = ScmModel().get_repos() sort_key = current_sort_slug + '_sort' + if c.sort_by.startswith('-'): - c.repos_list = sorted(cached_repo_list, key=itemgetter(sort_key), + c.repos_list = sorted(c.cached_repo_list, key=itemgetter(sort_key), reverse=True) else: - c.repos_list = sorted(cached_repo_list, key=itemgetter(sort_key), + c.repos_list = sorted(c.cached_repo_list, key=itemgetter(sort_key), reverse=False) return render('/index.html') diff -r f3402cb92fdf -r 3fc9183e05dd rhodecode/controllers/journal.py --- a/rhodecode/controllers/journal.py Mon Feb 14 16:43:57 2011 +0100 +++ b/rhodecode/controllers/journal.py Tue Feb 15 01:36:07 2011 +0100 @@ -29,15 +29,15 @@ from sqlalchemy import or_ from sqlalchemy.orm import joinedload, make_transient from webhelpers.paginate import Page +from itertools import groupby from paste.httpexceptions import HTTPInternalServerError -from pylons import request, response, session, tmpl_context as c, url +from pylons import request, tmpl_context as c from rhodecode.lib.auth import LoginRequired, NotAnonymous from rhodecode.lib.base import BaseController, render from rhodecode.lib.helpers import get_token from rhodecode.model.db import UserLog, UserFollowing -from rhodecode.model.scm import ScmModel log = logging.getLogger(__name__) @@ -51,6 +51,7 @@ def index(self): # Return a rendered template + c.following = self.sa.query(UserFollowing)\ .filter(UserFollowing.user_id == c.rhodecode_user.user_id)\ .options(joinedload(UserFollowing.follows_repository))\ @@ -71,7 +72,6 @@ filtering_criterion = UserLog.repository_id.in_(repo_ids) if not repo_ids and user_ids: filtering_criterion = UserLog.user_id.in_(user_ids) - if filtering_criterion is not None: journal = self.sa.query(UserLog)\ .options(joinedload(UserLog.user))\ @@ -80,19 +80,19 @@ .order_by(UserLog.action_date.desc()) else: journal = [] + p = int(request.params.get('page', 1)) - p = int(request.params.get('page', 1)) - c.journal_pager = Page(journal, page=p, items_per_page=10) + c.journal_pager = Page(journal, page=p, items_per_page=20) + c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager) + c.journal_data = render('journal/journal_data.html') if request.params.get('partial'): return c.journal_data - return render('journal/journal.html') def _get_daily_aggregate(self, journal): - from itertools import groupby groups = [] for k, g in groupby(journal, lambda x:x.action_as_day): user_group = [] @@ -109,12 +109,11 @@ cur_token = request.POST.get('auth_token') token = get_token() if cur_token == token: - scm_model = ScmModel() user_id = request.POST.get('follows_user_id') if user_id: try: - scm_model.toggle_following_user(user_id, + self.scm_model.toggle_following_user(user_id, c.rhodecode_user.user_id) return 'ok' except: @@ -123,7 +122,7 @@ repo_id = request.POST.get('follows_repo_id') if repo_id: try: - scm_model.toggle_following_repo(repo_id, + self.scm_model.toggle_following_repo(repo_id, c.rhodecode_user.user_id) return 'ok' except: diff -r f3402cb92fdf -r 3fc9183e05dd rhodecode/controllers/search.py --- a/rhodecode/controllers/search.py Mon Feb 14 16:43:57 2011 +0100 +++ b/rhodecode/controllers/search.py Tue Feb 15 01:36:07 2011 +0100 @@ -28,8 +28,7 @@ import traceback from pylons.i18n.translation import _ -from pylons import request, response, config, session, tmpl_context as c, url -from pylons.controllers.util import abort, redirect +from pylons import request, config, session, tmpl_context as c from rhodecode.lib.auth import LoginRequired from rhodecode.lib.base import BaseController, render diff -r f3402cb92fdf -r 3fc9183e05dd rhodecode/controllers/settings.py --- a/rhodecode/controllers/settings.py Mon Feb 14 16:43:57 2011 +0100 +++ b/rhodecode/controllers/settings.py Tue Feb 15 01:36:07 2011 +0100 @@ -29,7 +29,6 @@ import traceback import formencode -from formencode import htmlfill from pylons import tmpl_context as c, request, url from pylons.controllers.util import redirect @@ -37,7 +36,7 @@ import rhodecode.lib.helpers as h from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAllDecorator -from rhodecode.lib.base import BaseController, render +from rhodecode.lib.base import BaseRepoController, render from rhodecode.lib.utils import invalidate_cache, action_logger from rhodecode.model.forms import RepoSettingsForm, RepoForkForm from rhodecode.model.repo import RepoModel @@ -45,7 +44,7 @@ log = logging.getLogger(__name__) -class SettingsController(BaseController): +class SettingsController(BaseRepoController): @LoginRequired() @HasRepoPermissionAllDecorator('repository.admin') @@ -87,7 +86,7 @@ defaults.update({'g_perm_%s' % p.users_group.users_group_name: p.permission.permission_name}) - return htmlfill.render( + return formencode.htmlfill.render( render('settings/repo_settings.html'), defaults=defaults, encoding="UTF-8", @@ -111,7 +110,7 @@ c.repo_info = repo_model.get_by_repo_name(repo_name) c.users_array = repo_model.get_users_js() errors.value.update({'user':c.repo_info.user.username}) - return htmlfill.render( + return formencode.htmlfill.render( render('settings/repo_settings.html'), defaults=errors.value, errors=errors.error_dict or {}, @@ -192,7 +191,7 @@ c.new_repo = errors.value['fork_name'] r = render('settings/repo_fork.html') - return htmlfill.render( + return formencode.htmlfill.render( r, defaults=errors.value, errors=errors.error_dict or {}, diff -r f3402cb92fdf -r 3fc9183e05dd rhodecode/controllers/shortlog.py --- a/rhodecode/controllers/shortlog.py Mon Feb 14 16:43:57 2011 +0100 +++ b/rhodecode/controllers/shortlog.py Tue Feb 15 01:36:07 2011 +0100 @@ -32,12 +32,11 @@ from webhelpers.paginate import Page from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator -from rhodecode.lib.base import BaseController, render -from rhodecode.model.scm import ScmModel +from rhodecode.lib.base import BaseRepoController, render log = logging.getLogger(__name__) -class ShortlogController(BaseController): +class ShortlogController(BaseRepoController): @LoginRequired() @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', @@ -47,8 +46,7 @@ def index(self): p = int(request.params.get('page', 1)) - repo, dbrepo = ScmModel().get(c.repo_name, 'repo') - c.repo_changesets = Page(repo, page=p, items_per_page=20) + c.repo_changesets = Page(c.rhodecode_repo, page=p, items_per_page=20) c.shortlog_data = render('shortlog/shortlog_data.html') if request.params.get('partial'): return c.shortlog_data diff -r f3402cb92fdf -r 3fc9183e05dd rhodecode/controllers/summary.py --- a/rhodecode/controllers/summary.py Mon Feb 14 16:43:57 2011 +0100 +++ b/rhodecode/controllers/summary.py Tue Feb 15 01:36:07 2011 +0100 @@ -35,11 +35,10 @@ from pylons import tmpl_context as c, request, url from pylons.i18n.translation import _ -from rhodecode.model.scm import ScmModel from rhodecode.model.db import Statistics from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator -from rhodecode.lib.base import BaseController, render +from rhodecode.lib.base import BaseRepoController, render from rhodecode.lib.utils import OrderedDict, EmptyChangeset from rhodecode.lib.celerylib import run_task @@ -54,7 +53,7 @@ import simplejson as json log = logging.getLogger(__name__) -class SummaryController(BaseController): +class SummaryController(BaseRepoController): @LoginRequired() @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', @@ -63,10 +62,10 @@ super(SummaryController, self).__before__() def index(self): - scm_model = ScmModel() - c.repo, dbrepo = scm_model.get(c.repo_name) + c.repo, dbrepo = self.scm_model.get(c.repo_name) c.dbrepo = dbrepo - c.following = scm_model.is_following_repo(c.repo_name, + + c.following = self.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) @@ -158,12 +157,12 @@ branches_group = ([], _("Branches")) tags_group = ([], _("Tags")) - for name, chs in c.repository_branches.items(): + for name, chs in c.rhodecode_repo.branches.items(): #chs = chs.split(':')[-1] branches_group[0].append((chs, name),) download_l.append(branches_group) - for name, chs in c.repository_tags.items(): + for name, chs in c.rhodecode_repo.tags.items(): #chs = chs.split(':')[-1] tags_group[0].append((chs, name),) download_l.append(tags_group) diff -r f3402cb92fdf -r 3fc9183e05dd rhodecode/controllers/tags.py --- a/rhodecode/controllers/tags.py Mon Feb 14 16:43:57 2011 +0100 +++ b/rhodecode/controllers/tags.py Tue Feb 15 01:36:07 2011 +0100 @@ -29,13 +29,12 @@ from pylons import tmpl_context as c from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator -from rhodecode.lib.base import BaseController, render +from rhodecode.lib.base import BaseRepoController, render from rhodecode.lib.utils import OrderedDict -from rhodecode.model.scm import ScmModel log = logging.getLogger(__name__) -class TagsController(BaseController): +class TagsController(BaseRepoController): @LoginRequired() @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', @@ -44,9 +43,8 @@ super(TagsController, self).__before__() def index(self): - 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_) + for name, hash_ in c.rhodecode_repo.tags.items(): + c.repo_tags[name] = c.rhodecode_repo.get_changeset(hash_) return render('tags/tags.html') diff -r f3402cb92fdf -r 3fc9183e05dd rhodecode/lib/base.py --- a/rhodecode/lib/base.py Mon Feb 14 16:43:57 2011 +0100 +++ b/rhodecode/lib/base.py Tue Feb 15 01:36:07 2011 +0100 @@ -23,24 +23,10 @@ self.cut_off_limit = int(config.get('cut_off_limit')) self.sa = meta.Session() - scm_model = ScmModel(self.sa) - c.cached_repo_list = scm_model.get_repos() + self.scm_model = ScmModel(self.sa) + c.cached_repo_list = self.scm_model.get_repos() #c.unread_journal = scm_model.get_unread_journal() - if c.repo_name: - 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 = {} - c.repository_followers = 0 - c.repository_forks = 0 - - def __call__(self, environ, start_response): """Invoke the Controller""" # WSGIController.__call__ dispatches to the Controller method @@ -52,3 +38,26 @@ return WSGIController.__call__(self, environ, start_response) finally: meta.Session.remove() + + +class BaseRepoController(BaseController): + """ + Base class for controllers responsible for loading all needed data + for those controllers, loaded items are + + c.rhodecode_repo: instance of scm repository (taken from cache) + + """ + + def __before__(self): + super(BaseRepoController, self).__before__() + if c.repo_name: + + c.rhodecode_repo, dbrepo = self.scm_model.get(c.repo_name, + retval='repo') + if c.rhodecode_repo: + c.repository_followers = self.scm_model.get_followers(c.repo_name) + c.repository_forks = self.scm_model.get_forks(c.repo_name) + else: + c.repository_followers = 0 + c.repository_forks = 0 diff -r f3402cb92fdf -r 3fc9183e05dd rhodecode/lib/helpers.py --- a/rhodecode/lib/helpers.py Mon Feb 14 16:43:57 2011 +0100 +++ b/rhodecode/lib/helpers.py Tue Feb 15 01:36:07 2011 +0100 @@ -440,8 +440,11 @@ revs_top_limit = 50 #show upto this amount of changesets hidden revs = action_params.split(',') repo_name = user_log.repository.repo_name + from rhodecode.model.scm import ScmModel - repo, dbrepo = ScmModel().get(repo_name, retval='repo') + repo, dbrepo = ScmModel().get(repo_name, retval='repo', + invalidation_list=[]) + message = lambda rev: get_changeset_safe(repo, rev).message cs_links = " " + ', '.join ([link_to(rev, @@ -481,14 +484,9 @@ return cs_links def get_fork_name(): - from rhodecode.model.scm import ScmModel repo_name = action_params - 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=dbrepo.description) + return str(link_to(action_params, url('summary_home', + repo_name=repo_name,))) map = {'user_deleted_repo':(_('[deleted] repository'), None), 'user_created_repo':(_('[created] repository'), None), diff -r f3402cb92fdf -r 3fc9183e05dd rhodecode/model/repo.py --- a/rhodecode/model/repo.py Mon Feb 14 16:43:57 2011 +0100 +++ b/rhodecode/model/repo.py Tue Feb 15 01:36:07 2011 +0100 @@ -30,7 +30,7 @@ import traceback from datetime import datetime -from sqlalchemy.orm import joinedload +from sqlalchemy.orm import joinedload, make_transient from vcs.utils.lazy import LazyProperty from vcs.backends import get_backend @@ -79,9 +79,6 @@ repo = self.sa.query(Repository)\ .options(joinedload(Repository.fork))\ .options(joinedload(Repository.user))\ - .options(joinedload(Repository.followers))\ - .options(joinedload(Repository.repo_to_perm))\ - .options(joinedload(Repository.users_group_to_perm))\ .filter(Repository.repo_name == repo_name)\ if cache: @@ -91,7 +88,13 @@ repo.invalidate() ret = repo.scalar() - self.sa.expunge_all() + + #make transient for sake of errors + make_transient(ret) + for k in ['fork', 'user']: + attr = getattr(ret, k, False) + if attr: + make_transient(attr) return ret diff -r f3402cb92fdf -r 3fc9183e05dd rhodecode/model/scm.py --- a/rhodecode/model/scm.py Mon Feb 14 16:43:57 2011 +0100 +++ b/rhodecode/model/scm.py Tue Feb 15 01:36:07 2011 +0100 @@ -32,6 +32,7 @@ from mercurial import ui from sqlalchemy.exc import DatabaseError +from sqlalchemy.orm import make_transient from beaker.cache import cache_region, region_invalidate @@ -121,29 +122,27 @@ and fill that backed with information from database :param all_repos: give specific repositories list, good for filtering + this have to be a list of just the repository names """ - if all_repos is None: - all_repos = self.sa.query(Repository)\ - .order_by(Repository.repo_name).all() + all_repos = [r.repo_name for r in self.sa.query(Repository)\ + .order_by(Repository.repo_name).all()] #get the repositories that should be invalidated invalidation_list = [str(x.cache_key) for x in \ self.sa.query(CacheInvalidation.cache_key)\ .filter(CacheInvalidation.cache_active == False)\ .all()] - - for r in all_repos: - - r_dbr = self.get(r.repo_name, invalidation_list) - + for r_name in all_repos: + r_dbr = self.get(r_name, invalidation_list) if r_dbr is not None: repo, dbrepo = r_dbr + last_change = repo.last_change tip = h.get_changeset_safe(repo, 'tip') tmp_d = {} - tmp_d['name'] = r.repo_name + tmp_d['name'] = dbrepo.repo_name tmp_d['name_sort'] = tmp_d['name'].lower() tmp_d['description'] = dbrepo.description tmp_d['description_sort'] = tmp_d['description'] @@ -158,7 +157,8 @@ tmp_d['repo_archives'] = list(repo._get_archives()) tmp_d['last_msg'] = tip.message tmp_d['repo'] = repo - tmp_d['dbrepo'] = dbrepo + tmp_d['dbrepo'] = dbrepo.get_dict() + tmp_d['dbrepo_fork'] = dbrepo.fork.get_dict() if dbrepo.fork else {} yield tmp_d def get(self, repo_name, invalidation_list=None, retval='all'): @@ -226,7 +226,7 @@ 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, + dbr = RepoModel().get_full(repo_name, cache=True, invalidate=dbinvalidate) @@ -341,12 +341,22 @@ return f is not None def get_followers(self, repo_id): - return self.sa.query(UserFollowing)\ - .filter(UserFollowing.follows_repo_id == repo_id).count() + if isinstance(repo_id, int): + return self.sa.query(UserFollowing)\ + .filter(UserFollowing.follows_repo_id == repo_id).count() + else: + return self.sa.query(UserFollowing)\ + .filter(UserFollowing.follows_repository \ + == RepoModel().get_by_repo_name(repo_id)).count() def get_forks(self, repo_id): - return self.sa.query(Repository)\ + if isinstance(repo_id, int): + return self.sa.query(Repository)\ .filter(Repository.fork_id == repo_id).count() + else: + return self.sa.query(Repository)\ + .filter(Repository.fork \ + == RepoModel().get_by_repo_name(repo_id)).count() def get_unread_journal(self): diff -r f3402cb92fdf -r 3fc9183e05dd rhodecode/public/css/style.css --- a/rhodecode/public/css/style.css Mon Feb 14 16:43:57 2011 +0100 +++ b/rhodecode/public/css/style.css Tue Feb 15 01:36:07 2011 +0100 @@ -1420,11 +1420,11 @@ height: 30px; } #journal .journal_icon{ +clear: both; float: left; -padding-top: 4px; -padding-left:12px; +padding-left: 36px; padding-right: 4px; -clear: both; +padding-top: 3px; } #journal .journal_action{ padding-top:4px; @@ -1436,7 +1436,12 @@ margin-left: 6px; padding-top: 3px; } - +#journal .date{ +clear: both; +color: #777777; +font-size: 11px; +padding-left: 56px; +} #journal .journal_repo .journal_repo_name{ font-weight: bold; font-size: 1.1em; diff -r f3402cb92fdf -r 3fc9183e05dd rhodecode/templates/admin/repos/repos.html --- a/rhodecode/templates/admin/repos/repos.html Mon Feb 14 16:43:57 2011 +0100 +++ b/rhodecode/templates/admin/repos/repos.html Tue Feb 15 01:36:07 2011 +0100 @@ -38,26 +38,26 @@ ## TYPE OF REPO - %if repo['dbrepo'].repo_type =='hg': + %if repo['dbrepo']['repo_type'] =='hg': ${_('Mercurial repository')} - %elif repo['dbrepo'].repo_type =='git': + %elif repo['dbrepo']['repo_type'] =='git': ${_('Git repository')} %else: %endif ## PRIVATE/PUBLIC REPO - %if repo['dbrepo'].private: + %if repo['dbrepo']['private']: ${_('private')} %else: ${_('public')} %endif ${h.link_to(repo['name'],h.url('edit_repo',repo_name=repo['name']))} - %if repo['dbrepo'].fork: - + %if repo['dbrepo_fork']: + ${_('public')} %endif diff -r f3402cb92fdf -r 3fc9183e05dd rhodecode/templates/admin/users/user_edit_my_account.html --- a/rhodecode/templates/admin/users/user_edit_my_account.html Mon Feb 14 16:43:57 2011 +0100 +++ b/rhodecode/templates/admin/users/user_edit_my_account.html Tue Feb 15 01:36:07 2011 +0100 @@ -119,24 +119,24 @@ %for repo in c.user_repos: - %if repo['dbrepo'].repo_type =='hg': + %if repo['dbrepo']['repo_type'] =='hg': ${_('Mercurial repository')} - %elif repo['dbrepo'].repo_type =='git': + %elif repo['dbrepo']['repo_type'] =='git': ${_('Git repository')} %else: %endif - %if repo['dbrepo'].private: + %if repo['dbrepo']['private']: ${_('private')} %else: ${_('public')} %endif ${h.link_to(repo['repo'].name, h.url('summary_home',repo_name=repo['repo'].name),class_="repo_name")} - %if repo['dbrepo'].fork: - + %if repo['dbrepo_fork']: + ${_('public')} %endif diff -r f3402cb92fdf -r 3fc9183e05dd rhodecode/templates/base/base.html --- a/rhodecode/templates/base/base.html Mon Feb 14 16:43:57 2011 +0100 +++ b/rhodecode/templates/base/base.html Tue Feb 15 01:36:07 2011 +0100 @@ -142,10 +142,10 @@ @@ -185,10 +185,10 @@